Symbol;
    }
    return resolveName(
      reference,
      reference.escapedText,
      111551 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */,
      /*nameNotFoundMessage*/
      void 0,
      /*isUse*/
      true,
      /*excludeGlobals*/
      void 0
    );
  }
  function getReferencedValueDeclaration(referenceIn) {
    if (!isGeneratedIdentifier(referenceIn)) {
      const reference = getParseTreeNode(referenceIn, isIdentifier);
      if (reference) {
        const symbol = getReferencedValueSymbol(reference);
        if (symbol) {
          return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
        }
      }
    }
    return void 0;
  }
  function getReferencedValueDeclarations(referenceIn) {
    if (!isGeneratedIdentifier(referenceIn)) {
      const reference = getParseTreeNode(referenceIn, isIdentifier);
      if (reference) {
        const symbol = getReferencedValueSymbol(reference);
        if (symbol) {
          return filter(getExportSymbolOfValueSymbolIfExported(symbol).declarations, (declaration) => {
            switch (declaration.kind) {
              case 260 /* VariableDeclaration */:
              case 169 /* Parameter */:
              case 208 /* BindingElement */:
              case 172 /* PropertyDeclaration */:
              case 303 /* PropertyAssignment */:
              case 304 /* ShorthandPropertyAssignment */:
              case 306 /* EnumMember */:
              case 210 /* ObjectLiteralExpression */:
              case 262 /* FunctionDeclaration */:
              case 218 /* FunctionExpression */:
              case 219 /* ArrowFunction */:
              case 263 /* ClassDeclaration */:
              case 231 /* ClassExpression */:
              case 266 /* EnumDeclaration */:
              case 174 /* MethodDeclaration */:
              case 177 /* GetAccessor */:
              case 178 /* SetAccessor */:
              case 267 /* ModuleDeclaration */:
                return true;
            }
            return false;
          });
        }
      }
    }
    return void 0;
  }
  function isLiteralConstDeclaration(node) {
    if (isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConstLike2(node)) {
      return isFreshLiteralType(getTypeOfSymbol(getSymbolOfDeclaration(node)));
    }
    return false;
  }
  function literalTypeToNode(type, enclosing, tracker) {
    const enumResult = type.flags & 1056 /* EnumLike */ ? nodeBuilder.symbolToExpression(
      type.symbol,
      111551 /* Value */,
      enclosing,
      /*flags*/
      void 0,
      tracker
    ) : type === trueType ? factory.createTrue() : type === falseType && factory.createFalse();
    if (enumResult) return enumResult;
    const literalValue = type.value;
    return typeof literalValue === "object" ? factory.createBigIntLiteral(literalValue) : typeof literalValue === "string" ? factory.createStringLiteral(literalValue) : literalValue < 0 ? factory.createPrefixUnaryExpression(41 /* MinusToken */, factory.createNumericLiteral(-literalValue)) : factory.createNumericLiteral(literalValue);
  }
  function createLiteralConstValue(node, tracker) {
    const type = getTypeOfSymbol(getSymbolOfDeclaration(node));
    return literalTypeToNode(type, node, tracker);
  }
  function getJsxFactoryEntity(location) {
    return location ? (getJsxNamespace(location), getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity) : _jsxFactoryEntity;
  }
  function getJsxFragmentFactoryEntity(location) {
    if (location) {
      const file = getSourceFileOfNode(location);
      if (file) {
        if (file.localJsxFragmentFactory) {
          return file.localJsxFragmentFactory;
        }
        const jsxFragPragmas = file.pragmas.get("jsxfrag");
        const jsxFragPragma = isArray(jsxFragPragmas) ? jsxFragPragmas[0] : jsxFragPragmas;
        if (jsxFragPragma) {
          file.localJsxFragmentFactory = parseIsolatedEntityName(jsxFragPragma.arguments.factory, languageVersion);
          return file.localJsxFragmentFactory;
        }
      }
    }
    if (compilerOptions.jsxFragmentFactory) {
      return parseIsolatedEntityName(compilerOptions.jsxFragmentFactory, languageVersion);
    }
  }
  function getNonlocalEffectiveTypeAnnotationNode(node) {
    const direct = getEffectiveTypeAnnotationNode(node);
    if (direct) {
      return direct;
    }
    if (node.kind === 169 /* Parameter */ && node.parent.kind === 178 /* SetAccessor */) {
      const other = getAllAccessorDeclarationsForDeclaration(node.parent).getAccessor;
      if (other) {
        return getEffectiveReturnTypeNode(other);
      }
    }
    return void 0;
  }
  function getNonlocalEffectiveReturnTypeAnnotationNode(node) {
    const direct = getEffectiveReturnTypeNode(node);
    if (direct) {
      return direct;
    }
    if (node.kind === 177 /* GetAccessor */) {
      const other = getAllAccessorDeclarationsForDeclaration(node).setAccessor;
      if (other) {
        const param = getSetAccessorValueParameter(other);
        if (param) {
          return getEffectiveTypeAnnotationNode(param);
        }
      }
    }
    return void 0;
  }
  function createResolver() {
    return {
      getReferencedExportContainer,
      getReferencedImportDeclaration,
      getReferencedDeclarationWithCollidingName,
      isDeclarationWithCollidingName,
      isValueAliasDeclaration: (nodeIn) => {
        const node = getParseTreeNode(nodeIn);
        return node && canCollectSymbolAliasAccessabilityData ? isValueAliasDeclaration(node) : true;
      },
      hasGlobalName,
      isReferencedAliasDeclaration: (nodeIn, checkChildren) => {
        const node = getParseTreeNode(nodeIn);
        return node && canCollectSymbolAliasAccessabilityData ? isReferencedAliasDeclaration(node, checkChildren) : true;
      },
      hasNodeCheckFlag: (nodeIn, flag) => {
        const node = getParseTreeNode(nodeIn);
        if (!node) return false;
        return hasNodeCheckFlag(node, flag);
      },
      isTopLevelValueImportEqualsWithEntityName,
      isDeclarationVisible,
      isImplementationOfOverload,
      requiresAddingImplicitUndefined,
      isExpandoFunctionDeclaration,
      getPropertiesOfContainerFunction,
      createTypeOfDeclaration,
      createReturnTypeOfSignatureDeclaration,
      createTypeOfExpression,
      createLiteralConstValue,
      isSymbolAccessible,
      isEntityNameVisible,
      getConstantValue: (nodeIn) => {
        const node = getParseTreeNode(nodeIn, canHaveConstantValue);
        return node ? getConstantValue2(node) : void 0;
      },
      getEnumMemberValue: (nodeIn) => {
        const node = getParseTreeNode(nodeIn, isEnumMember);
        return node ? getEnumMemberValue(node) : void 0;
      },
      collectLinkedAliases,
      markLinkedReferences: (nodeIn) => {
        const node = getParseTreeNode(nodeIn);
        return node && markLinkedReferences(node, 0 /* Unspecified */);
      },
      getReferencedValueDeclaration,
      getReferencedValueDeclarations,
      getTypeReferenceSerializationKind,
      isOptionalParameter,
      isArgumentsLocalBinding,
      getExternalModuleFileFromDeclaration: (nodeIn) => {
        const node = getParseTreeNode(nodeIn, hasPossibleExternalModuleReference);
        return node && getExternalModuleFileFromDeclaration(node);
      },
      isLiteralConstDeclaration,
      isLateBound: (nodeIn) => {
        const node = getParseTreeNode(nodeIn, isDeclaration);
        const symbol = node && getSymbolOfDeclaration(node);
        return !!(symbol && getCheckFlags(symbol) & 4096 /* Late */);
      },
      getJsxFactoryEntity,
      getJsxFragmentFactoryEntity,
      isBindingCapturedByNode: (node, decl) => {
        const parseNode = getParseTreeNode(node);
        const parseDecl = getParseTreeNode(decl);
        return !!parseNode && !!parseDecl && (isVariableDeclaration(parseDecl) || isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl);
      },
      getDeclarationStatementsForSourceFile: (node, flags, tracker) => {
        const n = getParseTreeNode(node);
        Debug.assert(n && n.kind === 307 /* SourceFile */, "Non-sourcefile node passed into getDeclarationsForSourceFile");
        const sym = getSymbolOfDeclaration(node);
        if (!sym) {
          return !node.locals ? [] : nodeBuilder.symbolTableToDeclarationStatements(node.locals, node, flags, tracker);
        }
        resolveExternalModuleSymbol(sym);
        return !sym.exports ? [] : nodeBuilder.symbolTableToDeclarationStatements(sym.exports, node, flags, tracker);
      },
      isImportRequiredByAugmentation,
      isDefinitelyReferenceToGlobalSymbolObject
    };
    function isImportRequiredByAugmentation(node) {
      const file = getSourceFileOfNode(node);
      if (!file.symbol) return false;
      const importTarget = getExternalModuleFileFromDeclaration(node);
      if (!importTarget) return false;
      if (importTarget === file) return false;
      const exports2 = getExportsOfModule(file.symbol);
      for (const s of arrayFrom(exports2.values())) {
        if (s.mergeId) {
          const merged = getMergedSymbol(s);
          if (merged.declarations) {
            for (const d of merged.declarations) {
              const declFile = getSourceFileOfNode(d);
              if (declFile === importTarget) {
                return true;
              }
            }
          }
        }
      }
      return false;
    }
  }
  function getExternalModuleFileFromDeclaration(declaration) {
    const specifier = declaration.kind === 267 /* ModuleDeclaration */ ? tryCast(declaration.name, isStringLiteral) : getExternalModuleName(declaration);
    const moduleSymbol = resolveExternalModuleNameWorker(
      specifier,
      specifier,
      /*moduleNotFoundError*/
      void 0
    );
    if (!moduleSymbol) {
      return void 0;
    }
    return getDeclarationOfKind(moduleSymbol, 307 /* SourceFile */);
  }
  function initializeTypeChecker() {
    for (const file of host.getSourceFiles()) {
      bindSourceFile(file, compilerOptions);
    }
    amalgamatedDuplicates = /* @__PURE__ */ new Map();
    let augmentations;
    for (const file of host.getSourceFiles()) {
      if (file.redirectInfo) {
        continue;
      }
      if (!isExternalOrCommonJsModule(file)) {
        const fileGlobalThisSymbol = file.locals.get("globalThis");
        if (fileGlobalThisSymbol == null ? void 0 : fileGlobalThisSymbol.declarations) {
          for (const declaration of fileGlobalThisSymbol.declarations) {
            diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis"));
          }
        }
        mergeSymbolTable(globals, file.locals);
      }
      if (file.jsGlobalAugmentations) {
        mergeSymbolTable(globals, file.jsGlobalAugmentations);
      }
      if (file.patternAmbientModules && file.patternAmbientModules.length) {
        patternAmbientModules = concatenate(patternAmbientModules, file.patternAmbientModules);
      }
      if (file.moduleAugmentations.length) {
        (augmentations || (augmentations = [])).push(file.moduleAugmentations);
      }
      if (file.symbol && file.symbol.globalExports) {
        const source = file.symbol.globalExports;
        source.forEach((sourceSymbol, id) => {
          if (!globals.has(id)) {
            globals.set(id, sourceSymbol);
          }
        });
      }
    }
    if (augmentations) {
      for (const list of augmentations) {
        for (const augmentation of list) {
          if (!isGlobalScopeAugmentation(augmentation.parent)) continue;
          mergeModuleAugmentation(augmentation);
        }
      }
    }
    addUndefinedToGlobalsOrErrorOnRedeclaration();
    getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
    getSymbolLinks(argumentsSymbol).type = getGlobalType(
      "IArguments",
      /*arity*/
      0,
      /*reportErrors*/
      true
    );
    getSymbolLinks(unknownSymbol).type = errorType;
    getSymbolLinks(globalThisSymbol).type = createObjectType(16 /* Anonymous */, globalThisSymbol);
    globalArrayType = getGlobalType(
      "Array",
      /*arity*/
      1,
      /*reportErrors*/
      true
    );
    globalObjectType = getGlobalType(
      "Object",
      /*arity*/
      0,
      /*reportErrors*/
      true
    );
    globalFunctionType = getGlobalType(
      "Function",
      /*arity*/
      0,
      /*reportErrors*/
      true
    );
    globalCallableFunctionType = strictBindCallApply && getGlobalType(
      "CallableFunction",
      /*arity*/
      0,
      /*reportErrors*/
      true
    ) || globalFunctionType;
    globalNewableFunctionType = strictBindCallApply && getGlobalType(
      "NewableFunction",
      /*arity*/
      0,
      /*reportErrors*/
      true
    ) || globalFunctionType;
    globalStringType = getGlobalType(
      "String",
      /*arity*/
      0,
      /*reportErrors*/
      true
    );
    globalNumberType = getGlobalType(
      "Number",
      /*arity*/
      0,
      /*reportErrors*/
      true
    );
    globalBooleanType = getGlobalType(
      "Boolean",
      /*arity*/
      0,
      /*reportErrors*/
      true
    );
    globalRegExpType = getGlobalType(
      "RegExp",
      /*arity*/
      0,
      /*reportErrors*/
      true
    );
    anyArrayType = createArrayType(anyType);
    autoArrayType = createArrayType(autoType);
    if (autoArrayType === emptyObjectType) {
      autoArrayType = createAnonymousType(
        /*symbol*/
        void 0,
        emptySymbols,
        emptyArray,
        emptyArray,
        emptyArray
      );
    }
    globalReadonlyArrayType = getGlobalTypeOrUndefined(
      "ReadonlyArray",
      /*arity*/
      1
    ) || globalArrayType;
    anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
    globalThisType = getGlobalTypeOrUndefined(
      "ThisType",
      /*arity*/
      1
    );
    if (augmentations) {
      for (const list of augmentations) {
        for (const augmentation of list) {
          if (isGlobalScopeAugmentation(augmentation.parent)) continue;
          mergeModuleAugmentation(augmentation);
        }
      }
    }
    amalgamatedDuplicates.forEach(({ firstFile, secondFile, conflictingSymbols }) => {
      if (conflictingSymbols.size < 8) {
        conflictingSymbols.forEach(({ isBlockScoped, firstFileLocations, secondFileLocations }, symbolName2) => {
          const message = isBlockScoped ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0;
          for (const node of firstFileLocations) {
            addDuplicateDeclarationError(node, message, symbolName2, secondFileLocations);
          }
          for (const node of secondFileLocations) {
            addDuplicateDeclarationError(node, message, symbolName2, firstFileLocations);
          }
        });
      } else {
        const list = arrayFrom(conflictingSymbols.keys()).join(", ");
        diagnostics.add(addRelatedInfo(
          createDiagnosticForNode(firstFile, Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list),
          createDiagnosticForNode(secondFile, Diagnostics.Conflicts_are_in_this_file)
        ));
        diagnostics.add(addRelatedInfo(
          createDiagnosticForNode(secondFile, Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list),
          createDiagnosticForNode(firstFile, Diagnostics.Conflicts_are_in_this_file)
        ));
      }
    });
    amalgamatedDuplicates = void 0;
  }
  function checkExternalEmitHelpers(location, helpers) {
    if (compilerOptions.importHelpers) {
      const sourceFile = getSourceFileOfNode(location);
      if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & 33554432 /* Ambient */)) {
        const helpersModule = resolveHelpersModule(sourceFile, location);
        if (helpersModule !== unknownSymbol) {
          const links = getSymbolLinks(helpersModule);
          links.requestedExternalEmitHelpers ?? (links.requestedExternalEmitHelpers = 0);
          if ((links.requestedExternalEmitHelpers & helpers) !== helpers) {
            const uncheckedHelpers = helpers & ~links.requestedExternalEmitHelpers;
            for (let helper = 1 /* FirstEmitHelper */; helper <= 16777216 /* LastEmitHelper */; helper <<= 1) {
              if (uncheckedHelpers & helper) {
                for (const name of getHelperNames(helper)) {
                  const symbol = resolveSymbol(getSymbol(getExportsOfModule(helpersModule), escapeLeadingUnderscores(name), 111551 /* Value */));
                  if (!symbol) {
                    error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name);
                  } else if (helper & 524288 /* ClassPrivateFieldGet */) {
                    if (!some(getSignaturesOfSymbol(symbol), (signature) => getParameterCount(signature) > 3)) {
                      error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 4);
                    }
                  } else if (helper & 1048576 /* ClassPrivateFieldSet */) {
                    if (!some(getSignaturesOfSymbol(symbol), (signature) => getParameterCount(signature) > 4)) {
                      error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 5);
                    }
                  } else if (helper & 1024 /* SpreadArray */) {
                    if (!some(getSignaturesOfSymbol(symbol), (signature) => getParameterCount(signature) > 2)) {
                      error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 3);
                    }
                  }
                }
              }
            }
          }
          links.requestedExternalEmitHelpers |= helpers;
        }
      }
    }
  }
  function getHelperNames(helper) {
    switch (helper) {
      case 1 /* Extends */:
        return ["__extends"];
      case 2 /* Assign */:
        return ["__assign"];
      case 4 /* Rest */:
        return ["__rest"];
      case 8 /* Decorate */:
        return legacyDecorators ? ["__decorate"] : ["__esDecorate", "__runInitializers"];
      case 16 /* Metadata */:
        return ["__metadata"];
      case 32 /* Param */:
        return ["__param"];
      case 64 /* Awaiter */:
        return ["__awaiter"];
      case 128 /* Generator */:
        return ["__generator"];
      case 256 /* Values */:
        return ["__values"];
      case 512 /* Read */:
        return ["__read"];
      case 1024 /* SpreadArray */:
        return ["__spreadArray"];
      case 2048 /* Await */:
        return ["__await"];
      case 4096 /* AsyncGenerator */:
        return ["__asyncGenerator"];
      case 8192 /* AsyncDelegator */:
        return ["__asyncDelegator"];
      case 16384 /* AsyncValues */:
        return ["__asyncValues"];
      case 32768 /* ExportStar */:
        return ["__exportStar"];
      case 65536 /* ImportStar */:
        return ["__importStar"];
      case 131072 /* ImportDefault */:
        return ["__importDefault"];
      case 262144 /* MakeTemplateObject */:
        return ["__makeTemplateObject"];
      case 524288 /* ClassPrivateFieldGet */:
        return ["__classPrivateFieldGet"];
      case 1048576 /* ClassPrivateFieldSet */:
        return ["__classPrivateFieldSet"];
      case 2097152 /* ClassPrivateFieldIn */:
        return ["__classPrivateFieldIn"];
      case 4194304 /* SetFunctionName */:
        return ["__setFunctionName"];
      case 8388608 /* PropKey */:
        return ["__propKey"];
      case 16777216 /* AddDisposableResourceAndDisposeResources */:
        return ["__addDisposableResource", "__disposeResources"];
      default:
        return Debug.fail("Unrecognized helper");
    }
  }
  function resolveHelpersModule(file, errorNode) {
    const links = getNodeLinks(file);
    if (!links.externalHelpersModule) {
      links.externalHelpersModule = resolveExternalModule(getImportHelpersImportSpecifier(file), externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
    }
    return links.externalHelpersModule;
  }
  function checkGrammarModifiers(node) {
    var _a;
    const quickResult = reportObviousDecoratorErrors(node) || reportObviousModifierErrors(node);
    if (quickResult !== void 0) {
      return quickResult;
    }
    if (isParameter(node) && parameterIsThisKeyword(node)) {
      return grammarErrorOnFirstToken(node, Diagnostics.Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters);
    }
    const blockScopeKind = isVariableStatement(node) ? node.declarationList.flags & 7 /* BlockScoped */ : 0 /* None */;
    let lastStatic, lastDeclare, lastAsync, lastOverride, firstDecorator;
    let flags = 0 /* None */;
    let sawExportBeforeDecorators = false;
    let hasLeadingDecorators = false;
    for (const modifier of node.modifiers) {
      if (isDecorator(modifier)) {
        if (!nodeCanBeDecorated(legacyDecorators, node, node.parent, node.parent.parent)) {
          if (node.kind === 174 /* MethodDeclaration */ && !nodeIsPresent(node.body)) {
            return grammarErrorOnFirstToken(node, Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload);
          } else {
            return grammarErrorOnFirstToken(node, Diagnostics.Decorators_are_not_valid_here);
          }
        } else if (legacyDecorators && (node.kind === 177 /* GetAccessor */ || node.kind === 178 /* SetAccessor */)) {
          const accessors = getAllAccessorDeclarationsForDeclaration(node);
          if (hasDecorators(accessors.firstAccessor) && node === accessors.secondAccessor) {
            return grammarErrorOnFirstToken(node, Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name);
          }
        }
        if (flags & ~(2080 /* ExportDefault */ | 32768 /* Decorator */)) {
          return grammarErrorOnNode(modifier, Diagnostics.Decorators_are_not_valid_here);
        }
        if (hasLeadingDecorators && flags & 98303 /* Modifier */) {
          Debug.assertIsDefined(firstDecorator);
          const sourceFile = getSourceFileOfNode(modifier);
          if (!hasParseDiagnostics(sourceFile)) {
            addRelatedInfo(
              error(modifier, Diagnostics.Decorators_may_not_appear_after_export_or_export_default_if_they_also_appear_before_export),
              createDiagnosticForNode(firstDecorator, Diagnostics.Decorator_used_before_export_here)
            );
            return true;
          }
          return false;
        }
        flags |= 32768 /* Decorator */;
        if (!(flags & 98303 /* Modifier */)) {
          hasLeadingDecorators = true;
        } else if (flags & 32 /* Export */) {
          sawExportBeforeDecorators = true;
        }
        firstDecorator ?? (firstDecorator = modifier);
      } else {
        if (modifier.kind !== 148 /* ReadonlyKeyword */) {
          if (node.kind === 171 /* PropertySignature */ || node.kind === 173 /* MethodSignature */) {
            return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_type_member, tokenToString(modifier.kind));
          }
          if (node.kind === 181 /* IndexSignature */ && (modifier.kind !== 126 /* StaticKeyword */ || !isClassLike(node.parent))) {
            return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_index_signature, tokenToString(modifier.kind));
          }
        }
        if (modifier.kind !== 103 /* InKeyword */ && modifier.kind !== 147 /* OutKeyword */ && modifier.kind !== 87 /* ConstKeyword */) {
          if (node.kind === 168 /* TypeParameter */) {
            return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_type_parameter, tokenToString(modifier.kind));
          }
        }
        switch (modifier.kind) {
          case 87 /* ConstKeyword */: {
            if (node.kind !== 266 /* EnumDeclaration */ && node.kind !== 168 /* TypeParameter */) {
              return grammarErrorOnNode(node, Diagnostics.A_class_member_cannot_have_the_0_keyword, tokenToString(87 /* ConstKeyword */));
            }
            const parent = isJSDocTemplateTag(node.parent) && getEffectiveJSDocHost(node.parent) || node.parent;
            if (node.kind === 168 /* TypeParameter */ && !(isFunctionLikeDeclaration(parent) || isClassLike(parent) || isFunctionTypeNode(parent) || isConstructorTypeNode(parent) || isCallSignatureDeclaration(parent) || isConstructSignatureDeclaration(parent) || isMethodSignature(parent))) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_can_only_appear_on_a_type_parameter_of_a_function_method_or_class, tokenToString(modifier.kind));
            }
            break;
          }
          case 164 /* OverrideKeyword */:
            if (flags & 16 /* Override */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "override");
            } else if (flags & 128 /* Ambient */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "override", "declare");
            } else if (flags & 8 /* Readonly */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "override", "readonly");
            } else if (flags & 512 /* Accessor */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "override", "accessor");
            } else if (flags & 1024 /* Async */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "override", "async");
            }
            flags |= 16 /* Override */;
            lastOverride = modifier;
            break;
          case 125 /* PublicKeyword */:
          case 124 /* ProtectedKeyword */:
          case 123 /* PrivateKeyword */:
            const text = visibilityToString(modifierToFlag(modifier.kind));
            if (flags & 7 /* AccessibilityModifier */) {
              return grammarErrorOnNode(modifier, Diagnostics.Accessibility_modifier_already_seen);
            } else if (flags & 16 /* Override */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "override");
            } else if (flags & 256 /* Static */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
            } else if (flags & 512 /* Accessor */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "accessor");
            } else if (flags & 8 /* Readonly */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly");
            } else if (flags & 1024 /* Async */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
            } else if (node.parent.kind === 268 /* ModuleBlock */ || node.parent.kind === 307 /* SourceFile */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text);
            } else if (flags & 64 /* Abstract */) {
              if (modifier.kind === 123 /* PrivateKeyword */) {
                return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
              } else {
                return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract");
              }
            } else if (isPrivateIdentifierClassElementDeclaration(node)) {
              return grammarErrorOnNode(modifier, Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier);
            }
            flags |= modifierToFlag(modifier.kind);
            break;
          case 126 /* StaticKeyword */:
            if (flags & 256 /* Static */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "static");
            } else if (flags & 8 /* Readonly */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly");
            } else if (flags & 1024 /* Async */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
            } else if (flags & 512 /* Accessor */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "accessor");
            } else if (node.parent.kind === 268 /* ModuleBlock */ || node.parent.kind === 307 /* SourceFile */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static");
            } else if (node.kind === 169 /* Parameter */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
            } else if (flags & 64 /* Abstract */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
            } else if (flags & 16 /* Override */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "override");
            }
            flags |= 256 /* Static */;
            lastStatic = modifier;
            break;
          case 129 /* AccessorKeyword */:
            if (flags & 512 /* Accessor */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "accessor");
            } else if (flags & 8 /* Readonly */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "accessor", "readonly");
            } else if (flags & 128 /* Ambient */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "accessor", "declare");
            } else if (node.kind !== 172 /* PropertyDeclaration */) {
              return grammarErrorOnNode(modifier, Diagnostics.accessor_modifier_can_only_appear_on_a_property_declaration);
            }
            flags |= 512 /* Accessor */;
            break;
          case 148 /* ReadonlyKeyword */:
            if (flags & 8 /* Readonly */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "readonly");
            } else if (node.kind !== 172 /* PropertyDeclaration */ && node.kind !== 171 /* PropertySignature */ && node.kind !== 181 /* IndexSignature */ && node.kind !== 169 /* Parameter */) {
              return grammarErrorOnNode(modifier, Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
            } else if (flags & 512 /* Accessor */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "readonly", "accessor");
            }
            flags |= 8 /* Readonly */;
            break;
          case 95 /* ExportKeyword */:
            if (compilerOptions.verbatimModuleSyntax && !(node.flags & 33554432 /* Ambient */) && node.kind !== 265 /* TypeAliasDeclaration */ && node.kind !== 264 /* InterfaceDeclaration */ && // ModuleDeclaration needs to be checked that it is uninstantiated later
            node.kind !== 267 /* ModuleDeclaration */ && node.parent.kind === 307 /* SourceFile */ && (moduleKind === 1 /* CommonJS */ || getSourceFileOfNode(node).impliedNodeFormat === 1 /* CommonJS */)) {
              return grammarErrorOnNode(modifier, Diagnostics.A_top_level_export_modifier_cannot_be_used_on_value_declarations_in_a_CommonJS_module_when_verbatimModuleSyntax_is_enabled);
            }
            if (flags & 32 /* Export */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "export");
            } else if (flags & 128 /* Ambient */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
            } else if (flags & 64 /* Abstract */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
            } else if (flags & 1024 /* Async */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
            } else if (isClassLike(node.parent)) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind, "export");
            } else if (node.kind === 169 /* Parameter */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
            } else if (blockScopeKind === 4 /* Using */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_using_declaration, "export");
            } else if (blockScopeKind === 6 /* AwaitUsing */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_await_using_declaration, "export");
            }
            flags |= 32 /* Export */;
            break;
          case 90 /* DefaultKeyword */:
            const container = node.parent.kind === 307 /* SourceFile */ ? node.parent : node.parent.parent;
            if (container.kind === 267 /* ModuleDeclaration */ && !isAmbientModule(container)) {
              return grammarErrorOnNode(modifier, Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
            } else if (blockScopeKind === 4 /* Using */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_using_declaration, "default");
            } else if (blockScopeKind === 6 /* AwaitUsing */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_await_using_declaration, "default");
            } else if (!(flags & 32 /* Export */)) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "default");
            } else if (sawExportBeforeDecorators) {
              return grammarErrorOnNode(firstDecorator, Diagnostics.Decorators_are_not_valid_here);
            }
            flags |= 2048 /* Default */;
            break;
          case 138 /* DeclareKeyword */:
            if (flags & 128 /* Ambient */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "declare");
            } else if (flags & 1024 /* Async */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
            } else if (flags & 16 /* Override */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "override");
            } else if (isClassLike(node.parent) && !isPropertyDeclaration(node)) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind, "declare");
            } else if (node.kind === 169 /* Parameter */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
            } else if (blockScopeKind === 4 /* Using */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_using_declaration, "declare");
            } else if (blockScopeKind === 6 /* AwaitUsing */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_await_using_declaration, "declare");
            } else if (node.parent.flags & 33554432 /* Ambient */ && node.parent.kind === 268 /* ModuleBlock */) {
              return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
            } else if (isPrivateIdentifierClassElementDeclaration(node)) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "declare");
            } else if (flags & 512 /* Accessor */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "declare", "accessor");
            }
            flags |= 128 /* Ambient */;
            lastDeclare = modifier;
            break;
          case 128 /* AbstractKeyword */:
            if (flags & 64 /* Abstract */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract");
            }
            if (node.kind !== 263 /* ClassDeclaration */ && node.kind !== 185 /* ConstructorType */) {
              if (node.kind !== 174 /* MethodDeclaration */ && node.kind !== 172 /* PropertyDeclaration */ && node.kind !== 177 /* GetAccessor */ && node.kind !== 178 /* SetAccessor */) {
                return grammarErrorOnNode(modifier, Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration);
              }
              if (!(node.parent.kind === 263 /* ClassDeclaration */ && hasSyntacticModifier(node.parent, 64 /* Abstract */))) {
                const message = node.kind === 172 /* PropertyDeclaration */ ? Diagnostics.Abstract_properties_can_only_appear_within_an_abstract_class : Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class;
                return grammarErrorOnNode(modifier, message);
              }
              if (flags & 256 /* Static */) {
                return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
              }
              if (flags & 2 /* Private */) {
                return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
              }
              if (flags & 1024 /* Async */ && lastAsync) {
                return grammarErrorOnNode(lastAsync, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "async", "abstract");
              }
              if (flags & 16 /* Override */) {
                return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "abstract", "override");
              }
              if (flags & 512 /* Accessor */) {
                return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "abstract", "accessor");
              }
            }
            if (isNamedDeclaration(node) && node.name.kind === 81 /* PrivateIdentifier */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract");
            }
            flags |= 64 /* Abstract */;
            break;
          case 134 /* AsyncKeyword */:
            if (flags & 1024 /* Async */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async");
            } else if (flags & 128 /* Ambient */ || node.parent.flags & 33554432 /* Ambient */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
            } else if (node.kind === 169 /* Parameter */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
            }
            if (flags & 64 /* Abstract */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "async", "abstract");
            }
            flags |= 1024 /* Async */;
            lastAsync = modifier;
            break;
          case 103 /* InKeyword */:
          case 147 /* OutKeyword */: {
            const inOutFlag = modifier.kind === 103 /* InKeyword */ ? 8192 /* In */ : 16384 /* Out */;
            const inOutText = modifier.kind === 103 /* InKeyword */ ? "in" : "out";
            const parent = isJSDocTemplateTag(node.parent) && (getEffectiveJSDocHost(node.parent) || find((_a = getJSDocRoot(node.parent)) == null ? void 0 : _a.tags, isJSDocTypedefTag)) || node.parent;
            if (node.kind !== 168 /* TypeParameter */ || parent && !(isInterfaceDeclaration(parent) || isClassLike(parent) || isTypeAliasDeclaration(parent) || isJSDocTypedefTag(parent))) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_can_only_appear_on_a_type_parameter_of_a_class_interface_or_type_alias, inOutText);
            }
            if (flags & inOutFlag) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, inOutText);
            }
            if (inOutFlag & 8192 /* In */ && flags & 16384 /* Out */) {
              return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "in", "out");
            }
            flags |= inOutFlag;
            break;
          }
        }
      }
    }
    if (node.kind === 176 /* Constructor */) {
      if (flags & 256 /* Static */) {
        return grammarErrorOnNode(lastStatic, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
      }
      if (flags & 16 /* Override */) {
        return grammarErrorOnNode(lastOverride, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "override");
      }
      if (flags & 1024 /* Async */) {
        return grammarErrorOnNode(lastAsync, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
      }
      return false;
    } else if ((node.kind === 272 /* ImportDeclaration */ || node.kind === 271 /* ImportEqualsDeclaration */) && flags & 128 /* Ambient */) {
      return grammarErrorOnNode(lastDeclare, Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
    } else if (node.kind === 169 /* Parameter */ && flags & 31 /* ParameterPropertyModifier */ && isBindingPattern(node.name)) {
      return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern);
    } else if (node.kind === 169 /* Parameter */ && flags & 31 /* ParameterPropertyModifier */ && node.dotDotDotToken) {
      return grammarErrorOnNode(node, Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter);
    }
    if (flags & 1024 /* Async */) {
      return checkGrammarAsyncModifier(node, lastAsync);
    }
    return false;
  }
  function reportObviousModifierErrors(node) {
    if (!node.modifiers) return false;
    const modifier = findFirstIllegalModifier(node);
    return modifier && grammarErrorOnFirstToken(modifier, Diagnostics.Modifiers_cannot_appear_here);
  }
  function findFirstModifierExcept(node, allowedModifier) {
    const modifier = find(node.modifiers, isModifier);
    return modifier && modifier.kind !== allowedModifier ? modifier : void 0;
  }
  function findFirstIllegalModifier(node) {
    switch (node.kind) {
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 176 /* Constructor */:
      case 172 /* PropertyDeclaration */:
      case 171 /* PropertySignature */:
      case 174 /* MethodDeclaration */:
      case 173 /* MethodSignature */:
      case 181 /* IndexSignature */:
      case 267 /* ModuleDeclaration */:
      case 272 /* ImportDeclaration */:
      case 271 /* ImportEqualsDeclaration */:
      case 278 /* ExportDeclaration */:
      case 277 /* ExportAssignment */:
      case 218 /* FunctionExpression */:
      case 219 /* ArrowFunction */:
      case 169 /* Parameter */:
      case 168 /* TypeParameter */:
        return void 0;
      case 175 /* ClassStaticBlockDeclaration */:
      case 303 /* PropertyAssignment */:
      case 304 /* ShorthandPropertyAssignment */:
      case 270 /* NamespaceExportDeclaration */:
      case 282 /* MissingDeclaration */:
        return find(node.modifiers, isModifier);
      default:
        if (node.parent.kind === 268 /* ModuleBlock */ || node.parent.kind === 307 /* SourceFile */) {
          return void 0;
        }
        switch (node.kind) {
          case 262 /* FunctionDeclaration */:
            return findFirstModifierExcept(node, 134 /* AsyncKeyword */);
          case 263 /* ClassDeclaration */:
          case 185 /* ConstructorType */:
            return findFirstModifierExcept(node, 128 /* AbstractKeyword */);
          case 231 /* ClassExpression */:
          case 264 /* InterfaceDeclaration */:
          case 265 /* TypeAliasDeclaration */:
            return find(node.modifiers, isModifier);
          case 243 /* VariableStatement */:
            return node.declarationList.flags & 4 /* Using */ ? findFirstModifierExcept(node, 135 /* AwaitKeyword */) : find(node.modifiers, isModifier);
          case 266 /* EnumDeclaration */:
            return findFirstModifierExcept(node, 87 /* ConstKeyword */);
          default:
            Debug.assertNever(node);
        }
    }
  }
  function reportObviousDecoratorErrors(node) {
    const decorator = findFirstIllegalDecorator(node);
    return decorator && grammarErrorOnFirstToken(decorator, Diagnostics.Decorators_are_not_valid_here);
  }
  function findFirstIllegalDecorator(node) {
    return canHaveIllegalDecorators(node) ? find(node.modifiers, isDecorator) : void 0;
  }
  function checkGrammarAsyncModifier(node, asyncModifier) {
    switch (node.kind) {
      case 174 /* MethodDeclaration */:
      case 262 /* FunctionDeclaration */:
      case 218 /* FunctionExpression */:
      case 219 /* ArrowFunction */:
        return false;
    }
    return grammarErrorOnNode(asyncModifier, Diagnostics._0_modifier_cannot_be_used_here, "async");
  }
  function checkGrammarForDisallowedTrailingComma(list, diag2 = Diagnostics.Trailing_comma_not_allowed) {
    if (list && list.hasTrailingComma) {
      return grammarErrorAtPos(list[0], list.end - ",".length, ",".length, diag2);
    }
    return false;
  }
  function checkGrammarTypeParameterList(typeParameters, file) {
    if (typeParameters && typeParameters.length === 0) {
      const start = typeParameters.pos - "<".length;
      const end = skipTrivia(file.text, typeParameters.end) + ">".length;
      return grammarErrorAtPos(file, start, end - start, Diagnostics.Type_parameter_list_cannot_be_empty);
    }
    return false;
  }
  function checkGrammarParameterList(parameters) {
    let seenOptionalParameter = false;
    const parameterCount = parameters.length;
    for (let i = 0; i < parameterCount; i++) {
      const parameter = parameters[i];
      if (parameter.dotDotDotToken) {
        if (i !== parameterCount - 1) {
          return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
        }
        if (!(parameter.flags & 33554432 /* Ambient */)) {
          checkGrammarForDisallowedTrailingComma(parameters, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
        }
        if (parameter.questionToken) {
          return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_rest_parameter_cannot_be_optional);
        }
        if (parameter.initializer) {
          return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_cannot_have_an_initializer);
        }
      } else if (hasEffectiveQuestionToken(parameter)) {
        seenOptionalParameter = true;
        if (parameter.questionToken && parameter.initializer) {
          return grammarErrorOnNode(parameter.name, Diagnostics.Parameter_cannot_have_question_mark_and_initializer);
        }
      } else if (seenOptionalParameter && !parameter.initializer) {
        return grammarErrorOnNode(parameter.name, Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter);
      }
    }
  }
  function getNonSimpleParameters(parameters) {
    return filter(parameters, (parameter) => !!parameter.initializer || isBindingPattern(parameter.name) || isRestParameter(parameter));
  }
  function checkGrammarForUseStrictSimpleParameterList(node) {
    if (languageVersion >= 3 /* ES2016 */) {
      const useStrictDirective = node.body && isBlock(node.body) && findUseStrictPrologue(node.body.statements);
      if (useStrictDirective) {
        const nonSimpleParameters = getNonSimpleParameters(node.parameters);
        if (length(nonSimpleParameters)) {
          forEach(nonSimpleParameters, (parameter) => {
            addRelatedInfo(
              error(parameter, Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive),
              createDiagnosticForNode(useStrictDirective, Diagnostics.use_strict_directive_used_here)
            );
          });
          const diagnostics2 = nonSimpleParameters.map((parameter, index) => index === 0 ? createDiagnosticForNode(parameter, Diagnostics.Non_simple_parameter_declared_here) : createDiagnosticForNode(parameter, Diagnostics.and_here));
          addRelatedInfo(error(useStrictDirective, Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list), ...diagnostics2);
          return true;
        }
      }
    }
    return false;
  }
  function checkGrammarFunctionLikeDeclaration(node) {
    const file = getSourceFileOfNode(node);
    return checkGrammarModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) || checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file) || isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node);
  }
  function checkGrammarClassLikeDeclaration(node) {
    const file = getSourceFileOfNode(node);
    return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file);
  }
  function checkGrammarArrowFunction(node, file) {
    if (!isArrowFunction(node)) {
      return false;
    }
    if (node.typeParameters && !(length(node.typeParameters) > 1 || node.typeParameters.hasTrailingComma || node.typeParameters[0].constraint)) {
      if (file && fileExtensionIsOneOf(file.fileName, [".mts" /* Mts */, ".cts" /* Cts */])) {
        grammarErrorOnNode(node.typeParameters[0], Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Add_a_trailing_comma_or_explicit_constraint);
      }
    }
    const { equalsGreaterThanToken } = node;
    const startLine = getLineAndCharacterOfPosition(file, equalsGreaterThanToken.pos).line;
    const endLine = getLineAndCharacterOfPosition(file, equalsGreaterThanToken.end).line;
    return startLine !== endLine && grammarErrorOnNode(equalsGreaterThanToken, Diagnostics.Line_terminator_not_permitted_before_arrow);
  }
  function checkGrammarIndexSignatureParameters(node) {
    const parameter = node.parameters[0];
    if (node.parameters.length !== 1) {
      if (parameter) {
        return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_must_have_exactly_one_parameter);
      } else {
        return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_exactly_one_parameter);
      }
    }
    checkGrammarForDisallowedTrailingComma(node.parameters, Diagnostics.An_index_signature_cannot_have_a_trailing_comma);
    if (parameter.dotDotDotToken) {
      return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
    }
    if (hasEffectiveModifiers(parameter)) {
      return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
    }
    if (parameter.questionToken) {
      return grammarErrorOnNode(parameter.questionToken, Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
    }
    if (parameter.initializer) {
      return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
    }
    if (!parameter.type) {
      return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
    }
    const type = getTypeFromTypeNode(parameter.type);
    if (someType(type, (t) => !!(t.flags & 8576 /* StringOrNumberLiteralOrUnique */)) || isGenericType(type)) {
      return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead);
    }
    if (!everyType(type, isValidIndexKeyType)) {
      return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type);
    }
    if (!node.type) {
      return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_a_type_annotation);
    }
    return false;
  }
  function checkGrammarIndexSignature(node) {
    return checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node);
  }
  function checkGrammarForAtLeastOneTypeArgument(node, typeArguments) {
    if (typeArguments && typeArguments.length === 0) {
      const sourceFile = getSourceFileOfNode(node);
      const start = typeArguments.pos - "<".length;
      const end = skipTrivia(sourceFile.text, typeArguments.end) + ">".length;
      return grammarErrorAtPos(sourceFile, start, end - start, Diagnostics.Type_argument_list_cannot_be_empty);
    }
    return false;
  }
  function checkGrammarTypeArguments(node, typeArguments) {
    return checkGrammarForDisallowedTrailingComma(typeArguments) || checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
  }
  function checkGrammarTaggedTemplateChain(node) {
    if (node.questionDotToken || node.flags & 64 /* OptionalChain */) {
      return grammarErrorOnNode(node.template, Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain);
    }
    return false;
  }
  function checkGrammarHeritageClause(node) {
    const types = node.types;
    if (checkGrammarForDisallowedTrailingComma(types)) {
      return true;
    }
    if (types && types.length === 0) {
      const listType = tokenToString(node.token);
      return grammarErrorAtPos(node, types.pos, 0, Diagnostics._0_list_cannot_be_empty, listType);
    }
    return some(types, checkGrammarExpressionWithTypeArguments);
  }
  function checkGrammarExpressionWithTypeArguments(node) {
    if (isExpressionWithTypeArguments(node) && isImportKeyword(node.expression) && node.typeArguments) {
      return grammarErrorOnNode(node, Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments);
    }
    return checkGrammarTypeArguments(node, node.typeArguments);
  }
  function checkGrammarClassDeclarationHeritageClauses(node) {
    let seenExtendsClause = false;
    let seenImplementsClause = false;
    if (!checkGrammarModifiers(node) && node.heritageClauses) {
      for (const heritageClause of node.heritageClauses) {
        if (heritageClause.token === 96 /* ExtendsKeyword */) {
          if (seenExtendsClause) {
            return grammarErrorOnFirstToken(heritageClause, Diagnostics.extends_clause_already_seen);
          }
          if (seenImplementsClause) {
            return grammarErrorOnFirstToken(heritageClause, Diagnostics.extends_clause_must_precede_implements_clause);
          }
          if (heritageClause.types.length > 1) {
            return grammarErrorOnFirstToken(heritageClause.types[1], Diagnostics.Classes_can_only_extend_a_single_class);
          }
          seenExtendsClause = true;
        } else {
          Debug.assert(heritageClause.token === 119 /* ImplementsKeyword */);
          if (seenImplementsClause) {
            return grammarErrorOnFirstToken(heritageClause, Diagnostics.implements_clause_already_seen);
          }
          seenImplementsClause = true;
        }
        checkGrammarHeritageClause(heritageClause);
      }
    }
  }
  function checkGrammarInterfaceDeclaration(node) {
    let seenExtendsClause = false;
    if (node.heritageClauses) {
      for (const heritageClause of node.heritageClauses) {
        if (heritageClause.token === 96 /* ExtendsKeyword */) {
          if (seenExtendsClause) {
            return grammarErrorOnFirstToken(heritageClause, Diagnostics.extends_clause_already_seen);
          }
          seenExtendsClause = true;
        } else {
          Debug.assert(heritageClause.token === 119 /* ImplementsKeyword */);
          return grammarErrorOnFirstToken(heritageClause, Diagnostics.Interface_declaration_cannot_have_implements_clause);
        }
        checkGrammarHeritageClause(heritageClause);
      }
    }
    return false;
  }
  function checkGrammarComputedPropertyName(node) {
    if (node.kind !== 167 /* ComputedPropertyName */) {
      return false;
    }
    const computedPropertyName = node;
    if (computedPropertyName.expression.kind === 226 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 28 /* CommaToken */) {
      return grammarErrorOnNode(computedPropertyName.expression, Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
    }
    return false;
  }
  function checkGrammarForGenerator(node) {
    if (node.asteriskToken) {
      Debug.assert(
        node.kind === 262 /* FunctionDeclaration */ || node.kind === 218 /* FunctionExpression */ || node.kind === 174 /* MethodDeclaration */
      );
      if (node.flags & 33554432 /* Ambient */) {
        return grammarErrorOnNode(node.asteriskToken, Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
      }
      if (!node.body) {
        return grammarErrorOnNode(node.asteriskToken, Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator);
      }
    }
  }
  function checkGrammarForInvalidQuestionMark(questionToken, message) {
    return !!questionToken && grammarErrorOnNode(questionToken, message);
  }
  function checkGrammarForInvalidExclamationToken(exclamationToken, message) {
    return !!exclamationToken && grammarErrorOnNode(exclamationToken, message);
  }
  function checkGrammarObjectLiteralExpression(node, inDestructuring) {
    const seen = /* @__PURE__ */ new Map();
    for (const prop of node.properties) {
      if (prop.kind === 305 /* SpreadAssignment */) {
        if (inDestructuring) {
          const expression = skipParentheses(prop.expression);
          if (isArrayLiteralExpression(expression) || isObjectLiteralExpression(expression)) {
            return grammarErrorOnNode(prop.expression, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
          }
        }
        continue;
      }
      const name = prop.name;
      if (name.kind === 167 /* ComputedPropertyName */) {
        checkGrammarComputedPropertyName(name);
      }
      if (prop.kind === 304 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) {
        grammarErrorOnNode(prop.equalsToken, Diagnostics.Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern);
      }
      if (name.kind === 81 /* PrivateIdentifier */) {
        grammarErrorOnNode(name, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
      }
      if (canHaveModifiers(prop) && prop.modifiers) {
        for (const mod of prop.modifiers) {
          if (isModifier(mod) && (mod.kind !== 134 /* AsyncKeyword */ || prop.kind !== 174 /* MethodDeclaration */)) {
            grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod));
          }
        }
      } else if (canHaveIllegalModifiers(prop) && prop.modifiers) {
        for (const mod of prop.modifiers) {
          if (isModifier(mod)) {
            grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod));
          }
        }
      }
      let currentKind;
      switch (prop.kind) {
        case 304 /* ShorthandPropertyAssignment */:
        case 303 /* PropertyAssignment */:
          checkGrammarForInvalidExclamationToken(prop.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
          checkGrammarForInvalidQuestionMark(prop.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional);
          if (name.kind === 9 /* NumericLiteral */) {
            checkGrammarNumericLiteral(name);
          }
          currentKind = 4 /* PropertyAssignment */;
          break;
        case 174 /* MethodDeclaration */:
          currentKind = 8 /* Method */;
          break;
        case 177 /* GetAccessor */:
          currentKind = 1 /* GetAccessor */;
          break;
        case 178 /* SetAccessor */:
          currentKind = 2 /* SetAccessor */;
          break;
        default:
          Debug.assertNever(prop, "Unexpected syntax kind:" + prop.kind);
      }
      if (!inDestructuring) {
        const effectiveName = getEffectivePropertyNameForPropertyNameNode(name);
        if (effectiveName === void 0) {
          continue;
        }
        const existingKind = seen.get(effectiveName);
        if (!existingKind) {
          seen.set(effectiveName, currentKind);
        } else {
          if (currentKind & 8 /* Method */ && existingKind & 8 /* Method */) {
            grammarErrorOnNode(name, Diagnostics.Duplicate_identifier_0, getTextOfNode(name));
          } else if (currentKind & 4 /* PropertyAssignment */ && existingKind & 4 /* PropertyAssignment */) {
            grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name, getTextOfNode(name));
          } else if (currentKind & 3 /* GetOrSetAccessor */ && existingKind & 3 /* GetOrSetAccessor */) {
            if (existingKind !== 3 /* GetOrSetAccessor */ && currentKind !== existingKind) {
              seen.set(effectiveName, currentKind | existingKind);
            } else {
              return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
            }
          } else {
            return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
          }
        }
      }
    }
  }
  function checkGrammarJsxElement(node) {
    checkGrammarJsxName(node.tagName);
    checkGrammarTypeArguments(node, node.typeArguments);
    const seen = /* @__PURE__ */ new Map();
    for (const attr of node.attributes.properties) {
      if (attr.kind === 293 /* JsxSpreadAttribute */) {
        continue;
      }
      const { name, initializer } = attr;
      const escapedText = getEscapedTextOfJsxAttributeName(name);
      if (!seen.get(escapedText)) {
        seen.set(escapedText, true);
      } else {
        return grammarErrorOnNode(name, Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
      }
      if (initializer && initializer.kind === 294 /* JsxExpression */ && !initializer.expression) {
        return grammarErrorOnNode(initializer, Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression);
      }
    }
  }
  function checkGrammarJsxName(node) {
    if (isPropertyAccessExpression(node) && isJsxNamespacedName(node.expression)) {
      return grammarErrorOnNode(node.expression, Diagnostics.JSX_property_access_expressions_cannot_include_JSX_namespace_names);
    }
    if (isJsxNamespacedName(node) && getJSXTransformEnabled(compilerOptions) && !isIntrinsicJsxName(node.namespace.escapedText)) {
      return grammarErrorOnNode(node, Diagnostics.React_components_cannot_include_JSX_namespace_names);
    }
  }
  function checkGrammarJsxExpression(node) {
    if (node.expression && isCommaSequence(node.expression)) {
      return grammarErrorOnNode(node.expression, Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array);
    }
  }
  function checkGrammarForInOrForOfStatement(forInOrOfStatement) {
    if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
      return true;
    }
    if (forInOrOfStatement.kind === 250 /* ForOfStatement */ && forInOrOfStatement.awaitModifier) {
      if (!(forInOrOfStatement.flags & 65536 /* AwaitContext */)) {
        const sourceFile = getSourceFileOfNode(forInOrOfStatement);
        if (isInTopLevelContext(forInOrOfStatement)) {
          if (!hasParseDiagnostics(sourceFile)) {
            if (!isEffectiveExternalModule(sourceFile, compilerOptions)) {
              diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module));
            }
            switch (moduleKind) {
              case 100 /* Node16 */:
              case 199 /* NodeNext */:
                if (sourceFile.impliedNodeFormat === 1 /* CommonJS */) {
                  diagnostics.add(
                    createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level)
                  );
                  break;
                }
              case 7 /* ES2022 */:
              case 99 /* ESNext */:
              case 4 /* System */:
                if (languageVersion >= 4 /* ES2017 */) {
                  break;
                }
              default:
                diagnostics.add(
                  createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_nodenext_or_preserve_and_the_target_option_is_set_to_es2017_or_higher)
                );
                break;
            }
          }
        } else {
          if (!hasParseDiagnostics(sourceFile)) {
            const diagnostic = createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules);
            const func = getContainingFunction(forInOrOfStatement);
            if (func && func.kind !== 176 /* Constructor */) {
              Debug.assert((getFunctionFlags(func) & 2 /* Async */) === 0, "Enclosing function should never be an async function.");
              const relatedInfo = createDiagnosticForNode(func, Diagnostics.Did_you_mean_to_mark_this_function_as_async);
              addRelatedInfo(diagnostic, relatedInfo);
            }
            diagnostics.add(diagnostic);
            return true;
          }
        }
      }
    }
    if (isForOfStatement(forInOrOfStatement) && !(forInOrOfStatement.flags & 65536 /* AwaitContext */) && isIdentifier(forInOrOfStatement.initializer) && forInOrOfStatement.initializer.escapedText === "async") {
      grammarErrorOnNode(forInOrOfStatement.initializer, Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_async);
      return false;
    }
    if (forInOrOfStatement.initializer.kind === 261 /* VariableDeclarationList */) {
      const variableList = forInOrOfStatement.initializer;
      if (!checkGrammarVariableDeclarationList(variableList)) {
        const declarations = variableList.declarations;
        if (!declarations.length) {
          return false;
        }
        if (declarations.length > 1) {
          const diagnostic = forInOrOfStatement.kind === 249 /* ForInStatement */ ? Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement : Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
          return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
        }
        const firstDeclaration = declarations[0];
        if (firstDeclaration.initializer) {
          const diagnostic = forInOrOfStatement.kind === 249 /* ForInStatement */ ? Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer : Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
          return grammarErrorOnNode(firstDeclaration.name, diagnostic);
        }
        if (firstDeclaration.type) {
          const diagnostic = forInOrOfStatement.kind === 249 /* ForInStatement */ ? Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation : Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
          return grammarErrorOnNode(firstDeclaration, diagnostic);
        }
      }
    }
    return false;
  }
  function checkGrammarAccessor(accessor) {
    if (!(accessor.flags & 33554432 /* Ambient */) && accessor.parent.kind !== 187 /* TypeLiteral */ && accessor.parent.kind !== 264 /* InterfaceDeclaration */) {
      if (languageVersion < 2 /* ES2015 */ && isPrivateIdentifier(accessor.name)) {
        return grammarErrorOnNode(accessor.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher);
      }
      if (accessor.body === void 0 && !hasSyntacticModifier(accessor, 64 /* Abstract */)) {
        return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
      }
    }
    if (accessor.body) {
      if (hasSyntacticModifier(accessor, 64 /* Abstract */)) {
        return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
      }
      if (accessor.parent.kind === 187 /* TypeLiteral */ || accessor.parent.kind === 264 /* InterfaceDeclaration */) {
        return grammarErrorOnNode(accessor.body, Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
      }
    }
    if (accessor.typeParameters) {
      return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters);
    }
    if (!doesAccessorHaveCorrectParameterCount(accessor)) {
      return grammarErrorOnNode(
        accessor.name,
        accessor.kind === 177 /* GetAccessor */ ? Diagnostics.A_get_accessor_cannot_have_parameters : Diagnostics.A_set_accessor_must_have_exactly_one_parameter
      );
    }
    if (accessor.kind === 178 /* SetAccessor */) {
      if (accessor.type) {
        return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
      }
      const parameter = Debug.checkDefined(getSetAccessorValueParameter(accessor), "Return value does not match parameter count assertion.");
      if (parameter.dotDotDotToken) {
        return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter);
      }
      if (parameter.questionToken) {
        return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
      }
      if (parameter.initializer) {
        return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
      }
    }
    return false;
  }
  function doesAccessorHaveCorrectParameterCount(accessor) {
    return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === 177 /* GetAccessor */ ? 0 : 1);
  }
  function getAccessorThisParameter(accessor) {
    if (accessor.parameters.length === (accessor.kind === 177 /* GetAccessor */ ? 1 : 2)) {
      return getThisParameter(accessor);
    }
  }
  function checkGrammarTypeOperatorNode(node) {
    if (node.operator === 158 /* UniqueKeyword */) {
      if (node.type.kind !== 155 /* SymbolKeyword */) {
        return grammarErrorOnNode(node.type, Diagnostics._0_expected, tokenToString(155 /* SymbolKeyword */));
      }
      let parent = walkUpParenthesizedTypes(node.parent);
      if (isInJSFile(parent) && isJSDocTypeExpression(parent)) {
        const host2 = getJSDocHost(parent);
        if (host2) {
          parent = getSingleVariableOfVariableStatement(host2) || host2;
        }
      }
      switch (parent.kind) {
        case 260 /* VariableDeclaration */:
          const decl = parent;
          if (decl.name.kind !== 80 /* Identifier */) {
            return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name);
          }
          if (!isVariableDeclarationInVariableStatement(decl)) {
            return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement);
          }
          if (!(decl.parent.flags & 2 /* Const */)) {
            return grammarErrorOnNode(parent.name, Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const);
          }
          break;
        case 172 /* PropertyDeclaration */:
          if (!isStatic(parent) || !hasEffectiveReadonlyModifier(parent)) {
            return grammarErrorOnNode(parent.name, Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly);
          }
          break;
        case 171 /* PropertySignature */:
          if (!hasSyntacticModifier(parent, 8 /* Readonly */)) {
            return grammarErrorOnNode(parent.name, Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly);
          }
          break;
        default:
          return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_here);
      }
    } else if (node.operator === 148 /* ReadonlyKeyword */) {
      if (node.type.kind !== 188 /* ArrayType */ && node.type.kind !== 189 /* TupleType */) {
        return grammarErrorOnFirstToken(node, Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types, tokenToString(155 /* SymbolKeyword */));
      }
    }
  }
  function checkGrammarForInvalidDynamicName(node, message) {
    if (isNonBindableDynamicName(node)) {
      return grammarErrorOnNode(node, message);
    }
  }
  function checkGrammarMethod(node) {
    if (checkGrammarFunctionLikeDeclaration(node)) {
      return true;
    }
    if (node.kind === 174 /* MethodDeclaration */) {
      if (node.parent.kind === 210 /* ObjectLiteralExpression */) {
        if (node.modifiers && !(node.modifiers.length === 1 && first(node.modifiers).kind === 134 /* AsyncKeyword */)) {
          return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
        } else if (checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) {
          return true;
        } else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) {
          return true;
        } else if (node.body === void 0) {
          return grammarErrorAtPos(node, node.end - 1, ";".length, Diagnostics._0_expected, "{");
        }
      }
      if (checkGrammarForGenerator(node)) {
        return true;
      }
    }
    if (isClassLike(node.parent)) {
      if (languageVersion < 2 /* ES2015 */ && isPrivateIdentifier(node.name)) {
        return grammarErrorOnNode(node.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher);
      }
      if (node.flags & 33554432 /* Ambient */) {
        return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
      } else if (node.kind === 174 /* MethodDeclaration */ && !node.body) {
        return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
      }
    } else if (node.parent.kind === 264 /* InterfaceDeclaration */) {
      return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
    } else if (node.parent.kind === 187 /* TypeLiteral */) {
      return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
    }
  }
  function checkGrammarBreakOrContinueStatement(node) {
    let current = node;
    while (current) {
      if (isFunctionLikeOrClassStaticBlockDeclaration(current)) {
        return grammarErrorOnNode(node, Diagnostics.Jump_target_cannot_cross_function_boundary);
      }
      switch (current.kind) {
        case 256 /* LabeledStatement */:
          if (node.label && current.label.escapedText === node.label.escapedText) {
            const isMisplacedContinueLabel = node.kind === 251 /* ContinueStatement */ && !isIterationStatement(
              current.statement,
              /*lookInLabeledStatements*/
              true
            );
            if (isMisplacedContinueLabel) {
              return grammarErrorOnNode(node, Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement);
            }
            return false;
          }
          break;
        case 255 /* SwitchStatement */:
          if (node.kind === 252 /* BreakStatement */ && !node.label) {
            return false;
          }
          break;
        default:
          if (isIterationStatement(
            current,
            /*lookInLabeledStatements*/
            false
          ) && !node.label) {
            return false;
          }
          break;
      }
      current = current.parent;
    }
    if (node.label) {
      const message = node.kind === 252 /* BreakStatement */ ? Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement : Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement;
      return grammarErrorOnNode(node, message);
    } else {
      const message = node.kind === 252 /* BreakStatement */ ? Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement : Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement;
      return grammarErrorOnNode(node, message);
    }
  }
  function checkGrammarBindingElement(node) {
    if (node.dotDotDotToken) {
      const elements = node.parent.elements;
      if (node !== last(elements)) {
        return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
      }
      checkGrammarForDisallowedTrailingComma(elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
      if (node.propertyName) {
        return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_have_a_property_name);
      }
    }
    if (node.dotDotDotToken && node.initializer) {
      return grammarErrorAtPos(node, node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
    }
  }
  function isStringOrNumberLiteralExpression(expr) {
    return isStringOrNumericLiteralLike(expr) || expr.kind === 224 /* PrefixUnaryExpression */ && expr.operator === 41 /* MinusToken */ && expr.operand.kind === 9 /* NumericLiteral */;
  }
  function isBigIntLiteralExpression(expr) {
    return expr.kind === 10 /* BigIntLiteral */ || expr.kind === 224 /* PrefixUnaryExpression */ && expr.operator === 41 /* MinusToken */ && expr.operand.kind === 10 /* BigIntLiteral */;
  }
  function isSimpleLiteralEnumReference(expr) {
    if ((isPropertyAccessExpression(expr) || isElementAccessExpression(expr) && isStringOrNumberLiteralExpression(expr.argumentExpression)) && isEntityNameExpression(expr.expression)) {
      return !!(checkExpressionCached(expr).flags & 1056 /* EnumLike */);
    }
  }
  function checkAmbientInitializer(node) {
    const initializer = node.initializer;
    if (initializer) {
      const isInvalidInitializer = !(isStringOrNumberLiteralExpression(initializer) || isSimpleLiteralEnumReference(initializer) || initializer.kind === 112 /* TrueKeyword */ || initializer.kind === 97 /* FalseKeyword */ || isBigIntLiteralExpression(initializer));
      const isConstOrReadonly = isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConstLike2(node);
      if (isConstOrReadonly && !node.type) {
        if (isInvalidInitializer) {
          return grammarErrorOnNode(initializer, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference);
        }
      } else {
        return grammarErrorOnNode(initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
      }
    }
  }
  function checkGrammarVariableDeclaration(node) {
    const nodeFlags = getCombinedNodeFlagsCached(node);
    const blockScopeKind = nodeFlags & 7 /* BlockScoped */;
    if (isBindingPattern(node.name)) {
      switch (blockScopeKind) {
        case 6 /* AwaitUsing */:
          return grammarErrorOnNode(node, Diagnostics._0_declarations_may_not_have_binding_patterns, "await using");
        case 4 /* Using */:
          return grammarErrorOnNode(node, Diagnostics._0_declarations_may_not_have_binding_patterns, "using");
      }
    }
    if (node.parent.parent.kind !== 249 /* ForInStatement */ && node.parent.parent.kind !== 250 /* ForOfStatement */) {
      if (nodeFlags & 33554432 /* Ambient */) {
        checkAmbientInitializer(node);
      } else if (!node.initializer) {
        if (isBindingPattern(node.name) && !isBindingPattern(node.parent)) {
          return grammarErrorOnNode(node, Diagnostics.A_destructuring_declaration_must_have_an_initializer);
        }
        switch (blockScopeKind) {
          case 6 /* AwaitUsing */:
            return grammarErrorOnNode(node, Diagnostics._0_declarations_must_be_initialized, "await using");
          case 4 /* Using */:
            return grammarErrorOnNode(node, Diagnostics._0_declarations_must_be_initialized, "using");
          case 2 /* Const */:
            return grammarErrorOnNode(node, Diagnostics._0_declarations_must_be_initialized, "const");
        }
      }
    }
    if (node.exclamationToken && (node.parent.parent.kind !== 243 /* VariableStatement */ || !node.type || node.initializer || nodeFlags & 33554432 /* Ambient */)) {
      const message = node.initializer ? Diagnostics.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions : !node.type ? Diagnostics.Declarations_with_definite_assignment_assertions_must_also_have_type_annotations : Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context;
      return grammarErrorOnNode(node.exclamationToken, message);
    }
    if ((moduleKind < 5 /* ES2015 */ || getSourceFileOfNode(node).impliedNodeFormat === 1 /* CommonJS */) && moduleKind !== 4 /* System */ && !(node.parent.parent.flags & 33554432 /* Ambient */) && hasSyntacticModifier(node.parent.parent, 32 /* Export */)) {
      checkESModuleMarker(node.name);
    }
    return !!blockScopeKind && checkGrammarNameInLetOrConstDeclarations(node.name);
  }
  function checkESModuleMarker(name) {
    if (name.kind === 80 /* Identifier */) {
      if (idText(name) === "__esModule") {
        return grammarErrorOnNodeSkippedOn("noEmit", name, Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules);
      }
    } else {
      const elements = name.elements;
      for (const element of elements) {
        if (!isOmittedExpression(element)) {
          return checkESModuleMarker(element.name);
        }
      }
    }
    return false;
  }
  function checkGrammarNameInLetOrConstDeclarations(name) {
    if (name.kind === 80 /* Identifier */) {
      if (name.escapedText === "let") {
        return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
      }
    } else {
      const elements = name.elements;
      for (const element of elements) {
        if (!isOmittedExpression(element)) {
          checkGrammarNameInLetOrConstDeclarations(element.name);
        }
      }
    }
    return false;
  }
  function checkGrammarVariableDeclarationList(declarationList) {
    const declarations = declarationList.declarations;
    if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) {
      return true;
    }
    if (!declarationList.declarations.length) {
      return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, Diagnostics.Variable_declaration_list_cannot_be_empty);
    }
    const blockScopeFlags = declarationList.flags & 7 /* BlockScoped */;
    if ((blockScopeFlags === 4 /* Using */ || blockScopeFlags === 6 /* AwaitUsing */) && isForInStatement(declarationList.parent)) {
      return grammarErrorOnNode(
        declarationList,
        blockScopeFlags === 4 /* Using */ ? Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_using_declaration : Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_an_await_using_declaration
      );
    }
    if (blockScopeFlags === 6 /* AwaitUsing */) {
      return checkAwaitGrammar(declarationList);
    }
    return false;
  }
  function allowLetAndConstDeclarations(parent) {
    switch (parent.kind) {
      case 245 /* IfStatement */:
      case 246 /* DoStatement */:
      case 247 /* WhileStatement */:
      case 254 /* WithStatement */:
      case 248 /* ForStatement */:
      case 249 /* ForInStatement */:
      case 250 /* ForOfStatement */:
        return false;
      case 256 /* LabeledStatement */:
        return allowLetAndConstDeclarations(parent.parent);
    }
    return true;
  }
  function checkGrammarForDisallowedBlockScopedVariableStatement(node) {
    if (!allowLetAndConstDeclarations(node.parent)) {
      const blockScopeKind = getCombinedNodeFlagsCached(node.declarationList) & 7 /* BlockScoped */;
      if (blockScopeKind) {
        const keyword = blockScopeKind === 1 /* Let */ ? "let" : blockScopeKind === 2 /* Const */ ? "const" : blockScopeKind === 4 /* Using */ ? "using" : blockScopeKind === 6 /* AwaitUsing */ ? "await using" : Debug.fail("Unknown BlockScope flag");
        return grammarErrorOnNode(node, Diagnostics._0_declarations_can_only_be_declared_inside_a_block, keyword);
      }
    }
  }
  function checkGrammarMetaProperty(node) {
    const escapedText = node.name.escapedText;
    switch (node.keywordToken) {
      case 105 /* NewKeyword */:
        if (escapedText !== "target") {
          return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "target");
        }
        break;
      case 102 /* ImportKeyword */:
        if (escapedText !== "meta") {
          return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta");
        }
        break;
    }
  }
  function hasParseDiagnostics(sourceFile) {
    return sourceFile.parseDiagnostics.length > 0;
  }
  function grammarErrorOnFirstToken(node, message, ...args) {
    const sourceFile = getSourceFileOfNode(node);
    if (!hasParseDiagnostics(sourceFile)) {
      const span = getSpanOfTokenAtPosition(sourceFile, node.pos);
      diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, message, ...args));
      return true;
    }
    return false;
  }
  function grammarErrorAtPos(nodeForSourceFile, start, length2, message, ...args) {
    const sourceFile = getSourceFileOfNode(nodeForSourceFile);
    if (!hasParseDiagnostics(sourceFile)) {
      diagnostics.add(createFileDiagnostic(sourceFile, start, length2, message, ...args));
      return true;
    }
    return false;
  }
  function grammarErrorOnNodeSkippedOn(key, node, message, ...args) {
    const sourceFile = getSourceFileOfNode(node);
    if (!hasParseDiagnostics(sourceFile)) {
      errorSkippedOn(key, node, message, ...args);
      return true;
    }
    return false;
  }
  function grammarErrorOnNode(node, message, ...args) {
    const sourceFile = getSourceFileOfNode(node);
    if (!hasParseDiagnostics(sourceFile)) {
      diagnostics.add(createDiagnosticForNode(node, message, ...args));
      return true;
    }
    return false;
  }
  function checkGrammarConstructorTypeParameters(node) {
    const jsdocTypeParameters = isInJSFile(node) ? getJSDocTypeParameterDeclarations(node) : void 0;
    const range = node.typeParameters || jsdocTypeParameters && firstOrUndefined(jsdocTypeParameters);
    if (range) {
      const pos = range.pos === range.end ? range.pos : skipTrivia(getSourceFileOfNode(node).text, range.pos);
      return grammarErrorAtPos(node, pos, range.end - pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
    }
  }
  function checkGrammarConstructorTypeAnnotation(node) {
    const type = node.type || getEffectiveReturnTypeNode(node);
    if (type) {
      return grammarErrorOnNode(type, Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
    }
  }
  function checkGrammarProperty(node) {
    if (isComputedPropertyName(node.name) && isBinaryExpression(node.name.expression) && node.name.expression.operatorToken.kind === 103 /* InKeyword */) {
      return grammarErrorOnNode(node.parent.members[0], Diagnostics.A_mapped_type_may_not_declare_properties_or_methods);
    }
    if (isClassLike(node.parent)) {
      if (isStringLiteral(node.name) && node.name.text === "constructor") {
        return grammarErrorOnNode(node.name, Diagnostics.Classes_may_not_have_a_field_named_constructor);
      }
      if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_have_a_simple_literal_type_or_a_unique_symbol_type)) {
        return true;
      }
      if (languageVersion < 2 /* ES2015 */ && isPrivateIdentifier(node.name)) {
        return grammarErrorOnNode(node.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher);
      }
      if (languageVersion < 2 /* ES2015 */ && isAutoAccessorPropertyDeclaration(node)) {
        return grammarErrorOnNode(node.name, Diagnostics.Properties_with_the_accessor_modifier_are_only_available_when_targeting_ECMAScript_2015_and_higher);
      }
      if (isAutoAccessorPropertyDeclaration(node) && checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_accessor_property_cannot_be_declared_optional)) {
        return true;
      }
    } else if (node.parent.kind === 264 /* InterfaceDeclaration */) {
      if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
        return true;
      }
      Debug.assertNode(node, isPropertySignature);
      if (node.initializer) {
        return grammarErrorOnNode(node.initializer, Diagnostics.An_interface_property_cannot_have_an_initializer);
      }
    } else if (isTypeLiteralNode(node.parent)) {
      if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
        return true;
      }
      Debug.assertNode(node, isPropertySignature);
      if (node.initializer) {
        return grammarErrorOnNode(node.initializer, Diagnostics.A_type_literal_property_cannot_have_an_initializer);
      }
    }
    if (node.flags & 33554432 /* Ambient */) {
      checkAmbientInitializer(node);
    }
    if (isPropertyDeclaration(node) && node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer || node.flags & 33554432 /* Ambient */ || isStatic(node) || hasAbstractModifier(node))) {
      const message = node.initializer ? Diagnostics.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions : !node.type ? Diagnostics.Declarations_with_definite_assignment_assertions_must_also_have_type_annotations : Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context;
      return grammarErrorOnNode(node.exclamationToken, message);
    }
  }
  function checkGrammarTopLevelElementForRequiredDeclareModifier(node) {
    if (node.kind === 264 /* InterfaceDeclaration */ || node.kind === 265 /* TypeAliasDeclaration */ || node.kind === 272 /* ImportDeclaration */ || node.kind === 271 /* ImportEqualsDeclaration */ || node.kind === 278 /* ExportDeclaration */ || node.kind === 277 /* ExportAssignment */ || node.kind === 270 /* NamespaceExportDeclaration */ || hasSyntacticModifier(node, 128 /* Ambient */ | 32 /* Export */ | 2048 /* Default */)) {
      return false;
    }
    return grammarErrorOnFirstToken(node, Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier);
  }
  function checkGrammarTopLevelElementsForRequiredDeclareModifier(file) {
    for (const decl of file.statements) {
      if (isDeclaration(decl) || decl.kind === 243 /* VariableStatement */) {
        if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) {
          return true;
        }
      }
    }
    return false;
  }
  function checkGrammarSourceFile(node) {
    return !!(node.flags & 33554432 /* Ambient */) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
  }
  function checkGrammarStatementInAmbientContext(node) {
    if (node.flags & 33554432 /* Ambient */) {
      const links = getNodeLinks(node);
      if (!links.hasReportedStatementInAmbientContext && (isFunctionLike(node.parent) || isAccessor(node.parent))) {
        return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
      }
      if (node.parent.kind === 241 /* Block */ || node.parent.kind === 268 /* ModuleBlock */ || node.parent.kind === 307 /* SourceFile */) {
        const links2 = getNodeLinks(node.parent);
        if (!links2.hasReportedStatementInAmbientContext) {
          return links2.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
        }
      } else {
      }
    }
    return false;
  }
  function checkGrammarNumericLiteral(node) {
    const isFractional = getTextOfNode(node).includes(".");
    const isScientific = node.numericLiteralFlags & 16 /* Scientific */;
    if (isFractional || isScientific) {
      return;
    }
    const value = +node.text;
    if (value <= 2 ** 53 - 1) {
      return;
    }
    addErrorOrSuggestion(
      /*isError*/
      false,
      createDiagnosticForNode(node, Diagnostics.Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers)
    );
  }
  function checkGrammarBigIntLiteral(node) {
    const literalType = isLiteralTypeNode(node.parent) || isPrefixUnaryExpression(node.parent) && isLiteralTypeNode(node.parent.parent);
    if (!literalType) {
      if (languageVersion < 7 /* ES2020 */) {
        if (grammarErrorOnNode(node, Diagnostics.BigInt_literals_are_not_available_when_targeting_lower_than_ES2020)) {
          return true;
        }
      }
    }
    return false;
  }
  function grammarErrorAfterFirstToken(node, message, ...args) {
    const sourceFile = getSourceFileOfNode(node);
    if (!hasParseDiagnostics(sourceFile)) {
      const span = getSpanOfTokenAtPosition(sourceFile, node.pos);
      diagnostics.add(createFileDiagnostic(
        sourceFile,
        textSpanEnd(span),
        /*length*/
        0,
        message,
        ...args
      ));
      return true;
    }
    return false;
  }
  function getAmbientModules() {
    if (!ambientModulesCache) {
      ambientModulesCache = [];
      globals.forEach((global2, sym) => {
        if (ambientModuleSymbolRegex.test(sym)) {
          ambientModulesCache.push(global2);
        }
      });
    }
    return ambientModulesCache;
  }
  function checkGrammarImportClause(node) {
    var _a;
    if (node.isTypeOnly && node.name && node.namedBindings) {
      return grammarErrorOnNode(node, Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both);
    }
    if (node.isTypeOnly && ((_a = node.namedBindings) == null ? void 0 : _a.kind) === 275 /* NamedImports */) {
      return checkGrammarNamedImportsOrExports(node.namedBindings);
    }
    return false;
  }
  function checkGrammarNamedImportsOrExports(namedBindings) {
    return !!forEach(namedBindings.elements, (specifier) => {
      if (specifier.isTypeOnly) {
        return grammarErrorOnFirstToken(
          specifier,
          specifier.kind === 276 /* ImportSpecifier */ ? Diagnostics.The_type_modifier_cannot_be_used_on_a_named_import_when_import_type_is_used_on_its_import_statement : Diagnostics.The_type_modifier_cannot_be_used_on_a_named_export_when_export_type_is_used_on_its_export_statement
        );
      }
    });
  }
  function checkGrammarImportCallExpression(node) {
    if (compilerOptions.verbatimModuleSyntax && moduleKind === 1 /* CommonJS */) {
      return grammarErrorOnNode(node, Diagnostics.ESM_syntax_is_not_allowed_in_a_CommonJS_module_when_verbatimModuleSyntax_is_enabled);
    }
    if (moduleKind === 5 /* ES2015 */) {
      return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_or_nodenext);
    }
    if (node.typeArguments) {
      return grammarErrorOnNode(node, Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments);
    }
    const nodeArguments = node.arguments;
    if (moduleKind !== 99 /* ESNext */ && moduleKind !== 199 /* NodeNext */ && moduleKind !== 100 /* Node16 */) {
      checkGrammarForDisallowedTrailingComma(nodeArguments);
      if (nodeArguments.length > 1) {
        const importAttributesArgument = nodeArguments[1];
        return grammarErrorOnNode(importAttributesArgument, Diagnostics.Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext_node16_or_nodenext);
      }
    }
    if (nodeArguments.length === 0 || nodeArguments.length > 2) {
      return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_set_of_attributes_as_arguments);
    }
    const spreadElement = find(nodeArguments, isSpreadElement);
    if (spreadElement) {
      return grammarErrorOnNode(spreadElement, Diagnostics.Argument_of_dynamic_import_cannot_be_spread_element);
    }
    return false;
  }
  function findMatchingTypeReferenceOrTypeAliasReference(source, unionTarget) {
    const sourceObjectFlags = getObjectFlags(source);
    if (sourceObjectFlags & (4 /* Reference */ | 16 /* Anonymous */) && unionTarget.flags & 1048576 /* Union */) {
      return find(unionTarget.types, (target) => {
        if (target.flags & 524288 /* Object */) {
          const overlapObjFlags = sourceObjectFlags & getObjectFlags(target);
          if (overlapObjFlags & 4 /* Reference */) {
            return source.target === target.target;
          }
          if (overlapObjFlags & 16 /* Anonymous */) {
            return !!source.aliasSymbol && source.aliasSymbol === target.aliasSymbol;
          }
        }
        return false;
      });
    }
  }
  function findBestTypeForObjectLiteral(source, unionTarget) {
    if (getObjectFlags(source) & 128 /* ObjectLiteral */ && someType(unionTarget, isArrayLikeType)) {
      return find(unionTarget.types, (t) => !isArrayLikeType(t));
    }
  }
  function findBestTypeForInvokable(source, unionTarget) {
    let signatureKind = 0 /* Call */;
    const hasSignatures = getSignaturesOfType(source, signatureKind).length > 0 || (signatureKind = 1 /* Construct */, getSignaturesOfType(source, signatureKind).length > 0);
    if (hasSignatures) {
      return find(unionTarget.types, (t) => getSignaturesOfType(t, signatureKind).length > 0);
    }
  }
  function findMostOverlappyType(source, unionTarget) {
    let bestMatch;
    if (!(source.flags & (402784252 /* Primitive */ | 406847488 /* InstantiablePrimitive */))) {
      let matchingCount = 0;
      for (const target of unionTarget.types) {
        if (!(target.flags & (402784252 /* Primitive */ | 406847488 /* InstantiablePrimitive */))) {
          const overlap = getIntersectionType([getIndexType(source), getIndexType(target)]);
          if (overlap.flags & 4194304 /* Index */) {
            return target;
          } else if (isUnitType(overlap) || overlap.flags & 1048576 /* Union */) {
            const len = overlap.flags & 1048576 /* Union */ ? countWhere(overlap.types, isUnitType) : 1;
            if (len >= matchingCount) {
              bestMatch = target;
              matchingCount = len;
            }
          }
        }
      }
    }
    return bestMatch;
  }
  function filterPrimitivesIfContainsNonPrimitive(type) {
    if (maybeTypeOfKind(type, 67108864 /* NonPrimitive */)) {
      const result = filterType(type, (t) => !(t.flags & 402784252 /* Primitive */));
      if (!(result.flags & 131072 /* Never */)) {
        return result;
      }
    }
    return type;
  }
  function findMatchingDiscriminantType(source, target, isRelatedTo) {
    if (target.flags & 1048576 /* Union */ && source.flags & (2097152 /* Intersection */ | 524288 /* Object */)) {
      const match = getMatchingUnionConstituentForType(target, source);
      if (match) {
        return match;
      }
      const sourceProperties = getPropertiesOfType(source);
      if (sourceProperties) {
        const sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
        if (sourcePropertiesFiltered) {
          const discriminated = discriminateTypeByDiscriminableItems(target, map(sourcePropertiesFiltered, (p) => [() => getTypeOfSymbol(p), p.escapedName]), isRelatedTo);
          if (discriminated !== target) {
            return discriminated;
          }
        }
      }
    }
    return void 0;
  }
  function getEffectivePropertyNameForPropertyNameNode(node) {
    const name = getPropertyNameForPropertyNameNode(node);
    return name ? name : isComputedPropertyName(node) ? tryGetNameFromType(getTypeOfExpression(node.expression)) : void 0;
  }
  function getCombinedModifierFlagsCached(node) {
    if (lastGetCombinedModifierFlagsNode === node) {
      return lastGetCombinedModifierFlagsResult;
    }
    lastGetCombinedModifierFlagsNode = node;
    lastGetCombinedModifierFlagsResult = getCombinedModifierFlags(node);
    return lastGetCombinedModifierFlagsResult;
  }
  function getCombinedNodeFlagsCached(node) {
    if (lastGetCombinedNodeFlagsNode === node) {
      return lastGetCombinedNodeFlagsResult;
    }
    lastGetCombinedNodeFlagsNode = node;
    lastGetCombinedNodeFlagsResult = getCombinedNodeFlags(node);
    return lastGetCombinedNodeFlagsResult;
  }
  function isVarConstLike2(node) {
    const blockScopeKind = getCombinedNodeFlagsCached(node) & 7 /* BlockScoped */;
    return blockScopeKind === 2 /* Const */ || blockScopeKind === 4 /* Using */ || blockScopeKind === 6 /* AwaitUsing */;
  }
  function getJSXRuntimeImportSpecifier(file, specifierText) {
    const jsxImportIndex = compilerOptions.importHelpers ? 1 : 0;
    const specifier = file == null ? void 0 : file.imports[jsxImportIndex];
    if (specifier) {
      Debug.assert(nodeIsSynthesized(specifier) && specifier.text === specifierText, `Expected sourceFile.imports[${jsxImportIndex}] to be the synthesized JSX runtime import`);
    }
    return specifier;
  }
  function getImportHelpersImportSpecifier(file) {
    Debug.assert(compilerOptions.importHelpers, "Expected importHelpers to be enabled");
    const specifier = file.imports[0];
    Debug.assert(specifier && nodeIsSynthesized(specifier) && specifier.text === "tslib", `Expected sourceFile.imports[0] to be the synthesized tslib import`);
    return specifier;
  }
}
function isNotAccessor(declaration) {
  return !isAccessor(declaration);
}
function isNotOverload(declaration) {
  return declaration.kind !== 262 /* FunctionDeclaration */ && declaration.kind !== 174 /* MethodDeclaration */ || !!declaration.body;
}
function isDeclarationNameOrImportPropertyName(name) {
  switch (name.parent.kind) {
    case 276 /* ImportSpecifier */:
    case 281 /* ExportSpecifier */:
      return isIdentifier(name);
    default:
      return isDeclarationName(name);
  }
}
var JsxNames;
((JsxNames2) => {
  JsxNames2.JSX = "JSX";
  JsxNames2.IntrinsicElements = "IntrinsicElements";
  JsxNames2.ElementClass = "ElementClass";
  JsxNames2.ElementAttributesPropertyNameContainer = "ElementAttributesProperty";
  JsxNames2.ElementChildrenAttributeNameContainer = "ElementChildrenAttribute";
  JsxNames2.Element = "Element";
  JsxNames2.ElementType = "ElementType";
  JsxNames2.IntrinsicAttributes = "IntrinsicAttributes";
  JsxNames2.IntrinsicClassAttributes = "IntrinsicClassAttributes";
  JsxNames2.LibraryManagedAttributes = "LibraryManagedAttributes";
})(JsxNames || (JsxNames = {}));
function getIterationTypesKeyFromIterationTypeKind(typeKind) {
  switch (typeKind) {
    case 0 /* Yield */:
      return "yieldType";
    case 1 /* Return */:
      return "returnType";
    case 2 /* Next */:
      return "nextType";
  }
}
function signatureHasRestParameter(s) {
  return !!(s.flags & 1 /* HasRestParameter */);
}
function signatureHasLiteralTypes(s) {
  return !!(s.flags & 2 /* HasLiteralTypes */);
}
function createBasicNodeBuilderModuleSpecifierResolutionHost(host) {
  return {
    getCommonSourceDirectory: !!host.getCommonSourceDirectory ? () => host.getCommonSourceDirectory() : () => "",
    getCurrentDirectory: () => host.getCurrentDirectory(),
    getSymlinkCache: maybeBind(host, host.getSymlinkCache),
    getPackageJsonInfoCache: () => {
      var _a;
      return (_a = host.getPackageJsonInfoCache) == null ? void 0 : _a.call(host);
    },
    useCaseSensitiveFileNames: maybeBind(host, host.useCaseSensitiveFileNames),
    redirectTargetsMap: host.redirectTargetsMap,
    getProjectReferenceRedirect: (fileName) => host.getProjectReferenceRedirect(fileName),
    isSourceOfProjectReferenceRedirect: (fileName) => host.isSourceOfProjectReferenceRedirect(fileName),
    fileExists: (fileName) => host.fileExists(fileName),
    getFileIncludeReasons: () => host.getFileIncludeReasons(),
    readFile: host.readFile ? (fileName) => host.readFile(fileName) : void 0
  };
}
var SymbolTrackerImpl = class _SymbolTrackerImpl {
  constructor(context, tracker, moduleResolverHost) {
    this.moduleResolverHost = void 0;
    this.inner = void 0;
    this.disableTrackSymbol = false;
    var _a;
    while (tracker instanceof _SymbolTrackerImpl) {
      tracker = tracker.inner;
    }
    this.inner = tracker;
    this.moduleResolverHost = moduleResolverHost;
    this.context = context;
    this.canTrackSymbol = !!((_a = this.inner) == null ? void 0 : _a.trackSymbol);
  }
  trackSymbol(symbol, enclosingDeclaration, meaning) {
    var _a, _b;
    if (((_a = this.inner) == null ? void 0 : _a.trackSymbol) && !this.disableTrackSymbol) {
      if (this.inner.trackSymbol(symbol, enclosingDeclaration, meaning)) {
        this.onDiagnosticReported();
        return true;
      }
      if (!(symbol.flags & 262144 /* TypeParameter */)) ((_b = this.context).trackedSymbols ?? (_b.trackedSymbols = [])).push([symbol, enclosingDeclaration, meaning]);
    }
    return false;
  }
  reportInaccessibleThisError() {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportInaccessibleThisError) {
      this.onDiagnosticReported();
      this.inner.reportInaccessibleThisError();
    }
  }
  reportPrivateInBaseOfClassExpression(propertyName) {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportPrivateInBaseOfClassExpression) {
      this.onDiagnosticReported();
      this.inner.reportPrivateInBaseOfClassExpression(propertyName);
    }
  }
  reportInaccessibleUniqueSymbolError() {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportInaccessibleUniqueSymbolError) {
      this.onDiagnosticReported();
      this.inner.reportInaccessibleUniqueSymbolError();
    }
  }
  reportCyclicStructureError() {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportCyclicStructureError) {
      this.onDiagnosticReported();
      this.inner.reportCyclicStructureError();
    }
  }
  reportLikelyUnsafeImportRequiredError(specifier) {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportLikelyUnsafeImportRequiredError) {
      this.onDiagnosticReported();
      this.inner.reportLikelyUnsafeImportRequiredError(specifier);
    }
  }
  reportTruncationError() {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportTruncationError) {
      this.onDiagnosticReported();
      this.inner.reportTruncationError();
    }
  }
  reportNonlocalAugmentation(containingFile, parentSymbol, augmentingSymbol) {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportNonlocalAugmentation) {
      this.onDiagnosticReported();
      this.inner.reportNonlocalAugmentation(containingFile, parentSymbol, augmentingSymbol);
    }
  }
  reportNonSerializableProperty(propertyName) {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportNonSerializableProperty) {
      this.onDiagnosticReported();
      this.inner.reportNonSerializableProperty(propertyName);
    }
  }
  onDiagnosticReported() {
    this.context.reportedDiagnostic = true;
  }
  reportInferenceFallback(node) {
    var _a;
    if ((_a = this.inner) == null ? void 0 : _a.reportInferenceFallback) {
      this.inner.reportInferenceFallback(node);
    }
  }
};

// src/compiler/visitorPublic.ts
function visitNode(node, visitor, test, lift) {
  if (node === void 0) {
    return node;
  }
  const visited = visitor(node);
  let visitedNode;
  if (visited === void 0) {
    return void 0;
  } else if (isArray(visited)) {
    visitedNode = (lift || extractSingleNode)(visited);
  } else {
    visitedNode = visited;
  }
  Debug.assertNode(visitedNode, test);
  return visitedNode;
}
function visitNodes2(nodes, visitor, test, start, count) {
  if (nodes === void 0) {
    return nodes;
  }
  const length2 = nodes.length;
  if (start === void 0 || start < 0) {
    start = 0;
  }
  if (count === void 0 || count > length2 - start) {
    count = length2 - start;
  }
  let hasTrailingComma;
  let pos = -1;
  let end = -1;
  if (start > 0 || count < length2) {
    hasTrailingComma = nodes.hasTrailingComma && start + count === length2;
  } else {
    pos = nodes.pos;
    end = nodes.end;
    hasTrailingComma = nodes.hasTrailingComma;
  }
  const updated = visitArrayWorker(nodes, visitor, test, start, count);
  if (updated !== nodes) {
    const updatedArray = factory.createNodeArray(updated, hasTrailingComma);
    setTextRangePosEnd(updatedArray, pos, end);
    return updatedArray;
  }
  return nodes;
}
function visitArray(nodes, visitor, test, start, count) {
  if (nodes === void 0) {
    return nodes;
  }
  const length2 = nodes.length;
  if (start === void 0 || start < 0) {
    start = 0;
  }
  if (count === void 0 || count > length2 - start) {
    count = length2 - start;
  }
  return visitArrayWorker(nodes, visitor, test, start, count);
}
function visitArrayWorker(nodes, visitor, test, start, count) {
  let updated;
  const length2 = nodes.length;
  if (start > 0 || count < length2) {
    updated = [];
  }
  for (let i = 0; i < count; i++) {
    const node = nodes[i + start];
    const visited = node !== void 0 ? visitor ? visitor(node) : node : void 0;
    if (updated !== void 0 || visited === void 0 || visited !== node) {
      if (updated === void 0) {
        updated = nodes.slice(0, i);
        Debug.assertEachNode(updated, test);
      }
      if (visited) {
        if (isArray(visited)) {
          for (const visitedNode of visited) {
            Debug.assertNode(visitedNode, test);
            updated.push(visitedNode);
          }
        } else {
          Debug.assertNode(visited, test);
          updated.push(visited);
        }
      }
    }
  }
  if (updated) {
    return updated;
  }
  Debug.assertEachNode(nodes, test);
  return nodes;
}
function visitLexicalEnvironment(statements, visitor, context, start, ensureUseStrict, nodesVisitor = visitNodes2) {
  context.startLexicalEnvironment();
  statements = nodesVisitor(statements, visitor, isStatement, start);
  if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements);
  return factory.mergeLexicalEnvironment(statements, context.endLexicalEnvironment());
}
function visitParameterList(nodes, visitor, context, nodesVisitor = visitNodes2) {
  let updated;
  context.startLexicalEnvironment();
  if (nodes) {
    context.setLexicalEnvironmentFlags(1 /* InParameters */, true);
    updated = nodesVisitor(nodes, visitor, isParameter);
    if (context.getLexicalEnvironmentFlags() & 2 /* VariablesHoistedInParameters */ && getEmitScriptTarget(context.getCompilerOptions()) >= 2 /* ES2015 */) {
      updated = addDefaultValueAssignmentsIfNeeded(updated, context);
    }
    context.setLexicalEnvironmentFlags(1 /* InParameters */, false);
  }
  context.suspendLexicalEnvironment();
  return updated;
}
function addDefaultValueAssignmentsIfNeeded(parameters, context) {
  let result;
  for (let i = 0; i < parameters.length; i++) {
    const parameter = parameters[i];
    const updated = addDefaultValueAssignmentIfNeeded(parameter, context);
    if (result || updated !== parameter) {
      if (!result) result = parameters.slice(0, i);
      result[i] = updated;
    }
  }
  if (result) {
    return setTextRange(context.factory.createNodeArray(result, parameters.hasTrailingComma), parameters);
  }
  return parameters;
}
function addDefaultValueAssignmentIfNeeded(parameter, context) {
  return parameter.dotDotDotToken ? parameter : isBindingPattern(parameter.name) ? addDefaultValueAssignmentForBindingPattern(parameter, context) : parameter.initializer ? addDefaultValueAssignmentForInitializer(parameter, parameter.name, parameter.initializer, context) : parameter;
}
function addDefaultValueAssignmentForBindingPattern(parameter, context) {
  const { factory: factory2 } = context;
  context.addInitializationStatement(
    factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      factory2.createVariableDeclarationList([
        factory2.createVariableDeclaration(
          parameter.name,
          /*exclamationToken*/
          void 0,
          parameter.type,
          parameter.initializer ? factory2.createConditionalExpression(
            factory2.createStrictEquality(
              factory2.getGeneratedNameForNode(parameter),
              factory2.createVoidZero()
            ),
            /*questionToken*/
            void 0,
            parameter.initializer,
            /*colonToken*/
            void 0,
            factory2.getGeneratedNameForNode(parameter)
          ) : factory2.getGeneratedNameForNode(parameter)
        )
      ])
    )
  );
  return factory2.updateParameterDeclaration(
    parameter,
    parameter.modifiers,
    parameter.dotDotDotToken,
    factory2.getGeneratedNameForNode(parameter),
    parameter.questionToken,
    parameter.type,
    /*initializer*/
    void 0
  );
}
function addDefaultValueAssignmentForInitializer(parameter, name, initializer, context) {
  const factory2 = context.factory;
  context.addInitializationStatement(
    factory2.createIfStatement(
      factory2.createTypeCheck(factory2.cloneNode(name), "undefined"),
      setEmitFlags(
        setTextRange(
          factory2.createBlock([
            factory2.createExpressionStatement(
              setEmitFlags(
                setTextRange(
                  factory2.createAssignment(
                    setEmitFlags(factory2.cloneNode(name), 96 /* NoSourceMap */),
                    setEmitFlags(initializer, 96 /* NoSourceMap */ | getEmitFlags(initializer) | 3072 /* NoComments */)
                  ),
                  parameter
                ),
                3072 /* NoComments */
              )
            )
          ]),
          parameter
        ),
        1 /* SingleLine */ | 64 /* NoTrailingSourceMap */ | 768 /* NoTokenSourceMaps */ | 3072 /* NoComments */
      )
    )
  );
  return factory2.updateParameterDeclaration(
    parameter,
    parameter.modifiers,
    parameter.dotDotDotToken,
    parameter.name,
    parameter.questionToken,
    parameter.type,
    /*initializer*/
    void 0
  );
}
function visitFunctionBody(node, visitor, context, nodeVisitor = visitNode) {
  context.resumeLexicalEnvironment();
  const updated = nodeVisitor(node, visitor, isConciseBody);
  const declarations = context.endLexicalEnvironment();
  if (some(declarations)) {
    if (!updated) {
      return context.factory.createBlock(declarations);
    }
    const block = context.factory.converters.convertToFunctionBlock(updated);
    const statements = factory.mergeLexicalEnvironment(block.statements, declarations);
    return context.factory.updateBlock(block, statements);
  }
  return updated;
}
function visitIterationBody(body, visitor, context, nodeVisitor = visitNode) {
  context.startBlockScope();
  const updated = nodeVisitor(body, visitor, isStatement, context.factory.liftToBlock);
  Debug.assert(updated);
  const declarations = context.endBlockScope();
  if (some(declarations)) {
    if (isBlock(updated)) {
      declarations.push(...updated.statements);
      return context.factory.updateBlock(updated, declarations);
    }
    declarations.push(updated);
    return context.factory.createBlock(declarations);
  }
  return updated;
}
function visitCommaListElements(elements, visitor, discardVisitor = visitor) {
  if (discardVisitor === visitor || elements.length <= 1) {
    return visitNodes2(elements, visitor, isExpression);
  }
  let i = 0;
  const length2 = elements.length;
  return visitNodes2(elements, (node) => {
    const discarded = i < length2 - 1;
    i++;
    return discarded ? discardVisitor(node) : visitor(node);
  }, isExpression);
}
function visitEachChild(node, visitor, context = nullTransformationContext, nodesVisitor = visitNodes2, tokenVisitor, nodeVisitor = visitNode) {
  if (node === void 0) {
    return void 0;
  }
  const fn = visitEachChildTable[node.kind];
  return fn === void 0 ? node : fn(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor);
}
var visitEachChildTable = {
  [166 /* QualifiedName */]: function visitEachChildOfQualifiedName(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateQualifiedName(
      node,
      Debug.checkDefined(nodeVisitor(node.left, visitor, isEntityName)),
      Debug.checkDefined(nodeVisitor(node.right, visitor, isIdentifier))
    );
  },
  [167 /* ComputedPropertyName */]: function visitEachChildOfComputedPropertyName(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateComputedPropertyName(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  // Signature elements
  [168 /* TypeParameter */]: function visitEachChildOfTypeParameterDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeParameterDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifier),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)),
      nodeVisitor(node.constraint, visitor, isTypeNode),
      nodeVisitor(node.default, visitor, isTypeNode)
    );
  },
  [169 /* Parameter */]: function visitEachChildOfParameterDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateParameterDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      tokenVisitor ? nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken) : node.dotDotDotToken,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)),
      tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken,
      nodeVisitor(node.type, visitor, isTypeNode),
      nodeVisitor(node.initializer, visitor, isExpression)
    );
  },
  [170 /* Decorator */]: function visitEachChildOfDecorator(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateDecorator(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  // Type elements
  [171 /* PropertySignature */]: function visitEachChildOfPropertySignature(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updatePropertySignature(
      node,
      nodesVisitor(node.modifiers, visitor, isModifier),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken,
      nodeVisitor(node.type, visitor, isTypeNode)
    );
  },
  [172 /* PropertyDeclaration */]: function visitEachChildOfPropertyDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updatePropertyDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      // QuestionToken and ExclamationToken are mutually exclusive in PropertyDeclaration
      tokenVisitor ? nodeVisitor(node.questionToken ?? node.exclamationToken, tokenVisitor, isQuestionOrExclamationToken) : node.questionToken ?? node.exclamationToken,
      nodeVisitor(node.type, visitor, isTypeNode),
      nodeVisitor(node.initializer, visitor, isExpression)
    );
  },
  [173 /* MethodSignature */]: function visitEachChildOfMethodSignature(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateMethodSignature(
      node,
      nodesVisitor(node.modifiers, visitor, isModifier),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken,
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.parameters, visitor, isParameter),
      nodeVisitor(node.type, visitor, isTypeNode)
    );
  },
  [174 /* MethodDeclaration */]: function visitEachChildOfMethodDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateMethodDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken,
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      visitParameterList(node.parameters, visitor, context, nodesVisitor),
      nodeVisitor(node.type, visitor, isTypeNode),
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [176 /* Constructor */]: function visitEachChildOfConstructorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateConstructorDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      visitParameterList(node.parameters, visitor, context, nodesVisitor),
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [177 /* GetAccessor */]: function visitEachChildOfGetAccessorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateGetAccessorDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      visitParameterList(node.parameters, visitor, context, nodesVisitor),
      nodeVisitor(node.type, visitor, isTypeNode),
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [178 /* SetAccessor */]: function visitEachChildOfSetAccessorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateSetAccessorDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      visitParameterList(node.parameters, visitor, context, nodesVisitor),
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [175 /* ClassStaticBlockDeclaration */]: function visitEachChildOfClassStaticBlockDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    context.startLexicalEnvironment();
    context.suspendLexicalEnvironment();
    return context.factory.updateClassStaticBlockDeclaration(
      node,
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [179 /* CallSignature */]: function visitEachChildOfCallSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateCallSignature(
      node,
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.parameters, visitor, isParameter),
      nodeVisitor(node.type, visitor, isTypeNode)
    );
  },
  [180 /* ConstructSignature */]: function visitEachChildOfConstructSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateConstructSignature(
      node,
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.parameters, visitor, isParameter),
      nodeVisitor(node.type, visitor, isTypeNode)
    );
  },
  [181 /* IndexSignature */]: function visitEachChildOfIndexSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateIndexSignature(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      nodesVisitor(node.parameters, visitor, isParameter),
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  // Types
  [182 /* TypePredicate */]: function visitEachChildOfTypePredicateNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypePredicateNode(
      node,
      nodeVisitor(node.assertsModifier, visitor, isAssertsKeyword),
      Debug.checkDefined(nodeVisitor(node.parameterName, visitor, isIdentifierOrThisTypeNode)),
      nodeVisitor(node.type, visitor, isTypeNode)
    );
  },
  [183 /* TypeReference */]: function visitEachChildOfTypeReferenceNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeReferenceNode(
      node,
      Debug.checkDefined(nodeVisitor(node.typeName, visitor, isEntityName)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode)
    );
  },
  [184 /* FunctionType */]: function visitEachChildOfFunctionTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateFunctionTypeNode(
      node,
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.parameters, visitor, isParameter),
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [185 /* ConstructorType */]: function visitEachChildOfConstructorTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateConstructorTypeNode(
      node,
      nodesVisitor(node.modifiers, visitor, isModifier),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.parameters, visitor, isParameter),
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [186 /* TypeQuery */]: function visitEachChildOfTypeQueryNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeQueryNode(
      node,
      Debug.checkDefined(nodeVisitor(node.exprName, visitor, isEntityName)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode)
    );
  },
  [187 /* TypeLiteral */]: function visitEachChildOfTypeLiteralNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeLiteralNode(
      node,
      nodesVisitor(node.members, visitor, isTypeElement)
    );
  },
  [188 /* ArrayType */]: function visitEachChildOfArrayTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateArrayTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.elementType, visitor, isTypeNode))
    );
  },
  [189 /* TupleType */]: function visitEachChildOfTupleTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateTupleTypeNode(
      node,
      nodesVisitor(node.elements, visitor, isTypeNode)
    );
  },
  [190 /* OptionalType */]: function visitEachChildOfOptionalTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateOptionalTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [191 /* RestType */]: function visitEachChildOfRestTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateRestTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [192 /* UnionType */]: function visitEachChildOfUnionTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateUnionTypeNode(
      node,
      nodesVisitor(node.types, visitor, isTypeNode)
    );
  },
  [193 /* IntersectionType */]: function visitEachChildOfIntersectionTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateIntersectionTypeNode(
      node,
      nodesVisitor(node.types, visitor, isTypeNode)
    );
  },
  [194 /* ConditionalType */]: function visitEachChildOfConditionalTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateConditionalTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.checkType, visitor, isTypeNode)),
      Debug.checkDefined(nodeVisitor(node.extendsType, visitor, isTypeNode)),
      Debug.checkDefined(nodeVisitor(node.trueType, visitor, isTypeNode)),
      Debug.checkDefined(nodeVisitor(node.falseType, visitor, isTypeNode))
    );
  },
  [195 /* InferType */]: function visitEachChildOfInferTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateInferTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration))
    );
  },
  [205 /* ImportType */]: function visitEachChildOfImportTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.argument, visitor, isTypeNode)),
      nodeVisitor(node.attributes, visitor, isImportAttributes),
      nodeVisitor(node.qualifier, visitor, isEntityName),
      nodesVisitor(node.typeArguments, visitor, isTypeNode),
      node.isTypeOf
    );
  },
  [302 /* ImportTypeAssertionContainer */]: function visitEachChildOfImportTypeAssertionContainer(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportTypeAssertionContainer(
      node,
      Debug.checkDefined(nodeVisitor(node.assertClause, visitor, isAssertClause)),
      node.multiLine
    );
  },
  [202 /* NamedTupleMember */]: function visitEachChildOfNamedTupleMember(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateNamedTupleMember(
      node,
      tokenVisitor ? nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken) : node.dotDotDotToken,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)),
      tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken,
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [196 /* ParenthesizedType */]: function visitEachChildOfParenthesizedType(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateParenthesizedType(
      node,
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [198 /* TypeOperator */]: function visitEachChildOfTypeOperatorNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeOperatorNode(
      node,
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [199 /* IndexedAccessType */]: function visitEachChildOfIndexedAccessType(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateIndexedAccessTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.objectType, visitor, isTypeNode)),
      Debug.checkDefined(nodeVisitor(node.indexType, visitor, isTypeNode))
    );
  },
  [200 /* MappedType */]: function visitEachChildOfMappedType(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateMappedTypeNode(
      node,
      tokenVisitor ? nodeVisitor(node.readonlyToken, tokenVisitor, isReadonlyKeywordOrPlusOrMinusToken) : node.readonlyToken,
      Debug.checkDefined(nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration)),
      nodeVisitor(node.nameType, visitor, isTypeNode),
      tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionOrPlusOrMinusToken) : node.questionToken,
      nodeVisitor(node.type, visitor, isTypeNode),
      nodesVisitor(node.members, visitor, isTypeElement)
    );
  },
  [201 /* LiteralType */]: function visitEachChildOfLiteralTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateLiteralTypeNode(
      node,
      Debug.checkDefined(nodeVisitor(node.literal, visitor, isLiteralTypeLiteral))
    );
  },
  [203 /* TemplateLiteralType */]: function visitEachChildOfTemplateLiteralType(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTemplateLiteralType(
      node,
      Debug.checkDefined(nodeVisitor(node.head, visitor, isTemplateHead)),
      nodesVisitor(node.templateSpans, visitor, isTemplateLiteralTypeSpan)
    );
  },
  [204 /* TemplateLiteralTypeSpan */]: function visitEachChildOfTemplateLiteralTypeSpan(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTemplateLiteralTypeSpan(
      node,
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode)),
      Debug.checkDefined(nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail))
    );
  },
  // Binding patterns
  [206 /* ObjectBindingPattern */]: function visitEachChildOfObjectBindingPattern(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateObjectBindingPattern(
      node,
      nodesVisitor(node.elements, visitor, isBindingElement)
    );
  },
  [207 /* ArrayBindingPattern */]: function visitEachChildOfArrayBindingPattern(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateArrayBindingPattern(
      node,
      nodesVisitor(node.elements, visitor, isArrayBindingElement)
    );
  },
  [208 /* BindingElement */]: function visitEachChildOfBindingElement(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateBindingElement(
      node,
      tokenVisitor ? nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken) : node.dotDotDotToken,
      nodeVisitor(node.propertyName, visitor, isPropertyName),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)),
      nodeVisitor(node.initializer, visitor, isExpression)
    );
  },
  // Expression
  [209 /* ArrayLiteralExpression */]: function visitEachChildOfArrayLiteralExpression(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateArrayLiteralExpression(
      node,
      nodesVisitor(node.elements, visitor, isExpression)
    );
  },
  [210 /* ObjectLiteralExpression */]: function visitEachChildOfObjectLiteralExpression(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateObjectLiteralExpression(
      node,
      nodesVisitor(node.properties, visitor, isObjectLiteralElementLike)
    );
  },
  [211 /* PropertyAccessExpression */]: function visitEachChildOfPropertyAccessExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return isPropertyAccessChain(node) ? context.factory.updatePropertyAccessChain(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      tokenVisitor ? nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken) : node.questionDotToken,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isMemberName))
    ) : context.factory.updatePropertyAccessExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isMemberName))
    );
  },
  [212 /* ElementAccessExpression */]: function visitEachChildOfElementAccessExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return isElementAccessChain(node) ? context.factory.updateElementAccessChain(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      tokenVisitor ? nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken) : node.questionDotToken,
      Debug.checkDefined(nodeVisitor(node.argumentExpression, visitor, isExpression))
    ) : context.factory.updateElementAccessExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.argumentExpression, visitor, isExpression))
    );
  },
  [213 /* CallExpression */]: function visitEachChildOfCallExpression(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return isCallChain(node) ? context.factory.updateCallChain(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      tokenVisitor ? nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken) : node.questionDotToken,
      nodesVisitor(node.typeArguments, visitor, isTypeNode),
      nodesVisitor(node.arguments, visitor, isExpression)
    ) : context.factory.updateCallExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode),
      nodesVisitor(node.arguments, visitor, isExpression)
    );
  },
  [214 /* NewExpression */]: function visitEachChildOfNewExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateNewExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode),
      nodesVisitor(node.arguments, visitor, isExpression)
    );
  },
  [215 /* TaggedTemplateExpression */]: function visitEachChildOfTaggedTemplateExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTaggedTemplateExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.tag, visitor, isExpression)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode),
      Debug.checkDefined(nodeVisitor(node.template, visitor, isTemplateLiteral))
    );
  },
  [216 /* TypeAssertionExpression */]: function visitEachChildOfTypeAssertionExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeAssertion(
      node,
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode)),
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [217 /* ParenthesizedExpression */]: function visitEachChildOfParenthesizedExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateParenthesizedExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [218 /* FunctionExpression */]: function visitEachChildOfFunctionExpression(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateFunctionExpression(
      node,
      nodesVisitor(node.modifiers, visitor, isModifier),
      tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken,
      nodeVisitor(node.name, visitor, isIdentifier),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      visitParameterList(node.parameters, visitor, context, nodesVisitor),
      nodeVisitor(node.type, visitor, isTypeNode),
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [219 /* ArrowFunction */]: function visitEachChildOfArrowFunction(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateArrowFunction(
      node,
      nodesVisitor(node.modifiers, visitor, isModifier),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      visitParameterList(node.parameters, visitor, context, nodesVisitor),
      nodeVisitor(node.type, visitor, isTypeNode),
      tokenVisitor ? Debug.checkDefined(nodeVisitor(node.equalsGreaterThanToken, tokenVisitor, isEqualsGreaterThanToken)) : node.equalsGreaterThanToken,
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [220 /* DeleteExpression */]: function visitEachChildOfDeleteExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateDeleteExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [221 /* TypeOfExpression */]: function visitEachChildOfTypeOfExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeOfExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [222 /* VoidExpression */]: function visitEachChildOfVoidExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateVoidExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [223 /* AwaitExpression */]: function visitEachChildOfAwaitExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateAwaitExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [224 /* PrefixUnaryExpression */]: function visitEachChildOfPrefixUnaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updatePrefixUnaryExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.operand, visitor, isExpression))
    );
  },
  [225 /* PostfixUnaryExpression */]: function visitEachChildOfPostfixUnaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updatePostfixUnaryExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.operand, visitor, isExpression))
    );
  },
  [226 /* BinaryExpression */]: function visitEachChildOfBinaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateBinaryExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.left, visitor, isExpression)),
      tokenVisitor ? Debug.checkDefined(nodeVisitor(node.operatorToken, tokenVisitor, isBinaryOperatorToken)) : node.operatorToken,
      Debug.checkDefined(nodeVisitor(node.right, visitor, isExpression))
    );
  },
  [227 /* ConditionalExpression */]: function visitEachChildOfConditionalExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateConditionalExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.condition, visitor, isExpression)),
      tokenVisitor ? Debug.checkDefined(nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken)) : node.questionToken,
      Debug.checkDefined(nodeVisitor(node.whenTrue, visitor, isExpression)),
      tokenVisitor ? Debug.checkDefined(nodeVisitor(node.colonToken, tokenVisitor, isColonToken)) : node.colonToken,
      Debug.checkDefined(nodeVisitor(node.whenFalse, visitor, isExpression))
    );
  },
  [228 /* TemplateExpression */]: function visitEachChildOfTemplateExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTemplateExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.head, visitor, isTemplateHead)),
      nodesVisitor(node.templateSpans, visitor, isTemplateSpan)
    );
  },
  [229 /* YieldExpression */]: function visitEachChildOfYieldExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateYieldExpression(
      node,
      tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken,
      nodeVisitor(node.expression, visitor, isExpression)
    );
  },
  [230 /* SpreadElement */]: function visitEachChildOfSpreadElement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateSpreadElement(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [231 /* ClassExpression */]: function visitEachChildOfClassExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateClassExpression(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      nodeVisitor(node.name, visitor, isIdentifier),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.heritageClauses, visitor, isHeritageClause),
      nodesVisitor(node.members, visitor, isClassElement)
    );
  },
  [233 /* ExpressionWithTypeArguments */]: function visitEachChildOfExpressionWithTypeArguments(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateExpressionWithTypeArguments(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode)
    );
  },
  [234 /* AsExpression */]: function visitEachChildOfAsExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateAsExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [238 /* SatisfiesExpression */]: function visitEachChildOfSatisfiesExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateSatisfiesExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [235 /* NonNullExpression */]: function visitEachChildOfNonNullExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return isOptionalChain(node) ? context.factory.updateNonNullChain(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    ) : context.factory.updateNonNullExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [236 /* MetaProperty */]: function visitEachChildOfMetaProperty(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateMetaProperty(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))
    );
  },
  // Misc
  [239 /* TemplateSpan */]: function visitEachChildOfTemplateSpan(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTemplateSpan(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail))
    );
  },
  // Element
  [241 /* Block */]: function visitEachChildOfBlock(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateBlock(
      node,
      nodesVisitor(node.statements, visitor, isStatement)
    );
  },
  [243 /* VariableStatement */]: function visitEachChildOfVariableStatement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateVariableStatement(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.declarationList, visitor, isVariableDeclarationList))
    );
  },
  [244 /* ExpressionStatement */]: function visitEachChildOfExpressionStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateExpressionStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [245 /* IfStatement */]: function visitEachChildOfIfStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateIfStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.thenStatement, visitor, isStatement, context.factory.liftToBlock)),
      nodeVisitor(node.elseStatement, visitor, isStatement, context.factory.liftToBlock)
    );
  },
  [246 /* DoStatement */]: function visitEachChildOfDoStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateDoStatement(
      node,
      visitIterationBody(node.statement, visitor, context, nodeVisitor),
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [247 /* WhileStatement */]: function visitEachChildOfWhileStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateWhileStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      visitIterationBody(node.statement, visitor, context, nodeVisitor)
    );
  },
  [248 /* ForStatement */]: function visitEachChildOfForStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateForStatement(
      node,
      nodeVisitor(node.initializer, visitor, isForInitializer),
      nodeVisitor(node.condition, visitor, isExpression),
      nodeVisitor(node.incrementor, visitor, isExpression),
      visitIterationBody(node.statement, visitor, context, nodeVisitor)
    );
  },
  [249 /* ForInStatement */]: function visitEachChildOfForInStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateForInStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.initializer, visitor, isForInitializer)),
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      visitIterationBody(node.statement, visitor, context, nodeVisitor)
    );
  },
  [250 /* ForOfStatement */]: function visitEachChildOfForOfStatement(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateForOfStatement(
      node,
      tokenVisitor ? nodeVisitor(node.awaitModifier, tokenVisitor, isAwaitKeyword) : node.awaitModifier,
      Debug.checkDefined(nodeVisitor(node.initializer, visitor, isForInitializer)),
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      visitIterationBody(node.statement, visitor, context, nodeVisitor)
    );
  },
  [251 /* ContinueStatement */]: function visitEachChildOfContinueStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateContinueStatement(
      node,
      nodeVisitor(node.label, visitor, isIdentifier)
    );
  },
  [252 /* BreakStatement */]: function visitEachChildOfBreakStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateBreakStatement(
      node,
      nodeVisitor(node.label, visitor, isIdentifier)
    );
  },
  [253 /* ReturnStatement */]: function visitEachChildOfReturnStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateReturnStatement(
      node,
      nodeVisitor(node.expression, visitor, isExpression)
    );
  },
  [254 /* WithStatement */]: function visitEachChildOfWithStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateWithStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock))
    );
  },
  [255 /* SwitchStatement */]: function visitEachChildOfSwitchStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateSwitchStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      Debug.checkDefined(nodeVisitor(node.caseBlock, visitor, isCaseBlock))
    );
  },
  [256 /* LabeledStatement */]: function visitEachChildOfLabeledStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateLabeledStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.label, visitor, isIdentifier)),
      Debug.checkDefined(nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock))
    );
  },
  [257 /* ThrowStatement */]: function visitEachChildOfThrowStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateThrowStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [258 /* TryStatement */]: function visitEachChildOfTryStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTryStatement(
      node,
      Debug.checkDefined(nodeVisitor(node.tryBlock, visitor, isBlock)),
      nodeVisitor(node.catchClause, visitor, isCatchClause),
      nodeVisitor(node.finallyBlock, visitor, isBlock)
    );
  },
  [260 /* VariableDeclaration */]: function visitEachChildOfVariableDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateVariableDeclaration(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)),
      tokenVisitor ? nodeVisitor(node.exclamationToken, tokenVisitor, isExclamationToken) : node.exclamationToken,
      nodeVisitor(node.type, visitor, isTypeNode),
      nodeVisitor(node.initializer, visitor, isExpression)
    );
  },
  [261 /* VariableDeclarationList */]: function visitEachChildOfVariableDeclarationList(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateVariableDeclarationList(
      node,
      nodesVisitor(node.declarations, visitor, isVariableDeclaration)
    );
  },
  [262 /* FunctionDeclaration */]: function visitEachChildOfFunctionDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
    return context.factory.updateFunctionDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifier),
      tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken,
      nodeVisitor(node.name, visitor, isIdentifier),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      visitParameterList(node.parameters, visitor, context, nodesVisitor),
      nodeVisitor(node.type, visitor, isTypeNode),
      visitFunctionBody(node.body, visitor, context, nodeVisitor)
    );
  },
  [263 /* ClassDeclaration */]: function visitEachChildOfClassDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateClassDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      nodeVisitor(node.name, visitor, isIdentifier),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.heritageClauses, visitor, isHeritageClause),
      nodesVisitor(node.members, visitor, isClassElement)
    );
  },
  [264 /* InterfaceDeclaration */]: function visitEachChildOfInterfaceDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateInterfaceDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      nodesVisitor(node.heritageClauses, visitor, isHeritageClause),
      nodesVisitor(node.members, visitor, isTypeElement)
    );
  },
  [265 /* TypeAliasDeclaration */]: function visitEachChildOfTypeAliasDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateTypeAliasDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)),
      nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
      Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))
    );
  },
  [266 /* EnumDeclaration */]: function visitEachChildOfEnumDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateEnumDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)),
      nodesVisitor(node.members, visitor, isEnumMember)
    );
  },
  [267 /* ModuleDeclaration */]: function visitEachChildOfModuleDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateModuleDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isModuleName)),
      nodeVisitor(node.body, visitor, isModuleBody)
    );
  },
  [268 /* ModuleBlock */]: function visitEachChildOfModuleBlock(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateModuleBlock(
      node,
      nodesVisitor(node.statements, visitor, isStatement)
    );
  },
  [269 /* CaseBlock */]: function visitEachChildOfCaseBlock(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateCaseBlock(
      node,
      nodesVisitor(node.clauses, visitor, isCaseOrDefaultClause)
    );
  },
  [270 /* NamespaceExportDeclaration */]: function visitEachChildOfNamespaceExportDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateNamespaceExportDeclaration(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))
    );
  },
  [271 /* ImportEqualsDeclaration */]: function visitEachChildOfImportEqualsDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportEqualsDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      node.isTypeOnly,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)),
      Debug.checkDefined(nodeVisitor(node.moduleReference, visitor, isModuleReference))
    );
  },
  [272 /* ImportDeclaration */]: function visitEachChildOfImportDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      nodeVisitor(node.importClause, visitor, isImportClause),
      Debug.checkDefined(nodeVisitor(node.moduleSpecifier, visitor, isExpression)),
      nodeVisitor(node.attributes, visitor, isImportAttributes)
    );
  },
  [300 /* ImportAttributes */]: function visitEachChildOfImportAttributes(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportAttributes(
      node,
      nodesVisitor(node.elements, visitor, isImportAttribute),
      node.multiLine
    );
  },
  [301 /* ImportAttribute */]: function visitEachChildOfImportAttribute(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportAttribute(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isImportAttributeName)),
      Debug.checkDefined(nodeVisitor(node.value, visitor, isExpression))
    );
  },
  [273 /* ImportClause */]: function visitEachChildOfImportClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportClause(
      node,
      node.isTypeOnly,
      nodeVisitor(node.name, visitor, isIdentifier),
      nodeVisitor(node.namedBindings, visitor, isNamedImportBindings)
    );
  },
  [274 /* NamespaceImport */]: function visitEachChildOfNamespaceImport(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateNamespaceImport(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))
    );
  },
  [280 /* NamespaceExport */]: function visitEachChildOfNamespaceExport(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateNamespaceExport(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))
    );
  },
  [275 /* NamedImports */]: function visitEachChildOfNamedImports(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateNamedImports(
      node,
      nodesVisitor(node.elements, visitor, isImportSpecifier)
    );
  },
  [276 /* ImportSpecifier */]: function visitEachChildOfImportSpecifier(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateImportSpecifier(
      node,
      node.isTypeOnly,
      nodeVisitor(node.propertyName, visitor, isIdentifier),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))
    );
  },
  [277 /* ExportAssignment */]: function visitEachChildOfExportAssignment(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateExportAssignment(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [278 /* ExportDeclaration */]: function visitEachChildOfExportDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateExportDeclaration(
      node,
      nodesVisitor(node.modifiers, visitor, isModifierLike),
      node.isTypeOnly,
      nodeVisitor(node.exportClause, visitor, isNamedExportBindings),
      nodeVisitor(node.moduleSpecifier, visitor, isExpression),
      nodeVisitor(node.attributes, visitor, isImportAttributes)
    );
  },
  [279 /* NamedExports */]: function visitEachChildOfNamedExports(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateNamedExports(
      node,
      nodesVisitor(node.elements, visitor, isExportSpecifier)
    );
  },
  [281 /* ExportSpecifier */]: function visitEachChildOfExportSpecifier(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateExportSpecifier(
      node,
      node.isTypeOnly,
      nodeVisitor(node.propertyName, visitor, isIdentifier),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))
    );
  },
  // Module references
  [283 /* ExternalModuleReference */]: function visitEachChildOfExternalModuleReference(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateExternalModuleReference(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  // JSX
  [284 /* JsxElement */]: function visitEachChildOfJsxElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxElement(
      node,
      Debug.checkDefined(nodeVisitor(node.openingElement, visitor, isJsxOpeningElement)),
      nodesVisitor(node.children, visitor, isJsxChild),
      Debug.checkDefined(nodeVisitor(node.closingElement, visitor, isJsxClosingElement))
    );
  },
  [285 /* JsxSelfClosingElement */]: function visitEachChildOfJsxSelfClosingElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxSelfClosingElement(
      node,
      Debug.checkDefined(nodeVisitor(node.tagName, visitor, isJsxTagNameExpression)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode),
      Debug.checkDefined(nodeVisitor(node.attributes, visitor, isJsxAttributes))
    );
  },
  [286 /* JsxOpeningElement */]: function visitEachChildOfJsxOpeningElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxOpeningElement(
      node,
      Debug.checkDefined(nodeVisitor(node.tagName, visitor, isJsxTagNameExpression)),
      nodesVisitor(node.typeArguments, visitor, isTypeNode),
      Debug.checkDefined(nodeVisitor(node.attributes, visitor, isJsxAttributes))
    );
  },
  [287 /* JsxClosingElement */]: function visitEachChildOfJsxClosingElement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxClosingElement(
      node,
      Debug.checkDefined(nodeVisitor(node.tagName, visitor, isJsxTagNameExpression))
    );
  },
  [295 /* JsxNamespacedName */]: function forEachChildInJsxNamespacedName2(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxNamespacedName(
      node,
      Debug.checkDefined(nodeVisitor(node.namespace, visitor, isIdentifier)),
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))
    );
  },
  [288 /* JsxFragment */]: function visitEachChildOfJsxFragment(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxFragment(
      node,
      Debug.checkDefined(nodeVisitor(node.openingFragment, visitor, isJsxOpeningFragment)),
      nodesVisitor(node.children, visitor, isJsxChild),
      Debug.checkDefined(nodeVisitor(node.closingFragment, visitor, isJsxClosingFragment))
    );
  },
  [291 /* JsxAttribute */]: function visitEachChildOfJsxAttribute(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxAttribute(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isJsxAttributeName)),
      nodeVisitor(node.initializer, visitor, isStringLiteralOrJsxExpression)
    );
  },
  [292 /* JsxAttributes */]: function visitEachChildOfJsxAttributes(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxAttributes(
      node,
      nodesVisitor(node.properties, visitor, isJsxAttributeLike)
    );
  },
  [293 /* JsxSpreadAttribute */]: function visitEachChildOfJsxSpreadAttribute(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxSpreadAttribute(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [294 /* JsxExpression */]: function visitEachChildOfJsxExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateJsxExpression(
      node,
      nodeVisitor(node.expression, visitor, isExpression)
    );
  },
  // Clauses
  [296 /* CaseClause */]: function visitEachChildOfCaseClause(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateCaseClause(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)),
      nodesVisitor(node.statements, visitor, isStatement)
    );
  },
  [297 /* DefaultClause */]: function visitEachChildOfDefaultClause(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateDefaultClause(
      node,
      nodesVisitor(node.statements, visitor, isStatement)
    );
  },
  [298 /* HeritageClause */]: function visitEachChildOfHeritageClause(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateHeritageClause(
      node,
      nodesVisitor(node.types, visitor, isExpressionWithTypeArguments)
    );
  },
  [299 /* CatchClause */]: function visitEachChildOfCatchClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateCatchClause(
      node,
      nodeVisitor(node.variableDeclaration, visitor, isVariableDeclaration),
      Debug.checkDefined(nodeVisitor(node.block, visitor, isBlock))
    );
  },
  // Property assignments
  [303 /* PropertyAssignment */]: function visitEachChildOfPropertyAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updatePropertyAssignment(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      Debug.checkDefined(nodeVisitor(node.initializer, visitor, isExpression))
    );
  },
  [304 /* ShorthandPropertyAssignment */]: function visitEachChildOfShorthandPropertyAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateShorthandPropertyAssignment(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)),
      nodeVisitor(node.objectAssignmentInitializer, visitor, isExpression)
    );
  },
  [305 /* SpreadAssignment */]: function visitEachChildOfSpreadAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateSpreadAssignment(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  // Enum
  [306 /* EnumMember */]: function visitEachChildOfEnumMember(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updateEnumMember(
      node,
      Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)),
      nodeVisitor(node.initializer, visitor, isExpression)
    );
  },
  // Top-level nodes
  [307 /* SourceFile */]: function visitEachChildOfSourceFile(node, visitor, context, _nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateSourceFile(
      node,
      visitLexicalEnvironment(node.statements, visitor, context)
    );
  },
  // Transformation nodes
  [354 /* PartiallyEmittedExpression */]: function visitEachChildOfPartiallyEmittedExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
    return context.factory.updatePartiallyEmittedExpression(
      node,
      Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))
    );
  },
  [355 /* CommaListExpression */]: function visitEachChildOfCommaListExpression(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
    return context.factory.updateCommaListExpression(
      node,
      nodesVisitor(node.elements, visitor, isExpression)
    );
  }
};
function extractSingleNode(nodes) {
  Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
  return singleOrUndefined(nodes);
}

// src/compiler/sourcemap.ts
function createSourceMapGenerator(host, file, sourceRoot, sourcesDirectoryPath, generatorOptions) {
  var { enter, exit } = generatorOptions.extendedDiagnostics ? createTimer("Source Map", "beforeSourcemap", "afterSourcemap") : nullTimer;
  var rawSources = [];
  var sources = [];
  var sourceToSourceIndexMap = /* @__PURE__ */ new Map();
  var sourcesContent;
  var names = [];
  var nameToNameIndexMap;
  var mappingCharCodes = [];
  var mappings = "";
  var lastGeneratedLine = 0;
  var lastGeneratedCharacter = 0;
  var lastSourceIndex = 0;
  var lastSourceLine = 0;
  var lastSourceCharacter = 0;
  var lastNameIndex = 0;
  var hasLast = false;
  var pendingGeneratedLine = 0;
  var pendingGeneratedCharacter = 0;
  var pendingSourceIndex = 0;
  var pendingSourceLine = 0;
  var pendingSourceCharacter = 0;
  var pendingNameIndex = 0;
  var hasPending = false;
  var hasPendingSource = false;
  var hasPendingName = false;
  return {
    getSources: () => rawSources,
    addSource,
    setSourceContent,
    addName,
    addMapping,
    appendSourceMap,
    toJSON,
    toString: () => JSON.stringify(toJSON())
  };
  function addSource(fileName) {
    enter();
    const source = getRelativePathToDirectoryOrUrl(
      sourcesDirectoryPath,
      fileName,
      host.getCurrentDirectory(),
      host.getCanonicalFileName,
      /*isAbsolutePathAnUrl*/
      true
    );
    let sourceIndex = sourceToSourceIndexMap.get(source);
    if (sourceIndex === void 0) {
      sourceIndex = sources.length;
      sources.push(source);
      rawSources.push(fileName);
      sourceToSourceIndexMap.set(source, sourceIndex);
    }
    exit();
    return sourceIndex;
  }
  function setSourceContent(sourceIndex, content) {
    enter();
    if (content !== null) {
      if (!sourcesContent) sourcesContent = [];
      while (sourcesContent.length < sourceIndex) {
        sourcesContent.push(null);
      }
      sourcesContent[sourceIndex] = content;
    }
    exit();
  }
  function addName(name) {
    enter();
    if (!nameToNameIndexMap) nameToNameIndexMap = /* @__PURE__ */ new Map();
    let nameIndex = nameToNameIndexMap.get(name);
    if (nameIndex === void 0) {
      nameIndex = names.length;
      names.push(name);
      nameToNameIndexMap.set(name, nameIndex);
    }
    exit();
    return nameIndex;
  }
  function isNewGeneratedPosition(generatedLine, generatedCharacter) {
    return !hasPending || pendingGeneratedLine !== generatedLine || pendingGeneratedCharacter !== generatedCharacter;
  }
  function isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter) {
    return sourceIndex !== void 0 && sourceLine !== void 0 && sourceCharacter !== void 0 && pendingSourceIndex === sourceIndex && (pendingSourceLine > sourceLine || pendingSourceLine === sourceLine && pendingSourceCharacter > sourceCharacter);
  }
  function addMapping(generatedLine, generatedCharacter, sourceIndex, sourceLine, sourceCharacter, nameIndex) {
    Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
    Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
    Debug.assert(sourceIndex === void 0 || sourceIndex >= 0, "sourceIndex cannot be negative");
    Debug.assert(sourceLine === void 0 || sourceLine >= 0, "sourceLine cannot be negative");
    Debug.assert(sourceCharacter === void 0 || sourceCharacter >= 0, "sourceCharacter cannot be negative");
    enter();
    if (isNewGeneratedPosition(generatedLine, generatedCharacter) || isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter)) {
      commitPendingMapping();
      pendingGeneratedLine = generatedLine;
      pendingGeneratedCharacter = generatedCharacter;
      hasPendingSource = false;
      hasPendingName = false;
      hasPending = true;
    }
    if (sourceIndex !== void 0 && sourceLine !== void 0 && sourceCharacter !== void 0) {
      pendingSourceIndex = sourceIndex;
      pendingSourceLine = sourceLine;
      pendingSourceCharacter = sourceCharacter;
      hasPendingSource = true;
      if (nameIndex !== void 0) {
        pendingNameIndex = nameIndex;
        hasPendingName = true;
      }
    }
    exit();
  }
  function appendSourceMap(generatedLine, generatedCharacter, map2, sourceMapPath, start, end) {
    Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
    Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
    enter();
    const sourceIndexToNewSourceIndexMap = [];
    let nameIndexToNewNameIndexMap;
    const mappingIterator = decodeMappings(map2.mappings);
    for (const raw of mappingIterator) {
      if (end && (raw.generatedLine > end.line || raw.generatedLine === end.line && raw.generatedCharacter > end.character)) {
        break;
      }
      if (start && (raw.generatedLine < start.line || start.line === raw.generatedLine && raw.generatedCharacter < start.character)) {
        continue;
      }
      let newSourceIndex;
      let newSourceLine;
      let newSourceCharacter;
      let newNameIndex;
      if (raw.sourceIndex !== void 0) {
        newSourceIndex = sourceIndexToNewSourceIndexMap[raw.sourceIndex];
        if (newSourceIndex === void 0) {
          const rawPath = map2.sources[raw.sourceIndex];
          const relativePath = map2.sourceRoot ? combinePaths(map2.sourceRoot, rawPath) : rawPath;
          const combinedPath = combinePaths(getDirectoryPath(sourceMapPath), relativePath);
          sourceIndexToNewSourceIndexMap[raw.sourceIndex] = newSourceIndex = addSource(combinedPath);
          if (map2.sourcesContent && typeof map2.sourcesContent[raw.sourceIndex] === "string") {
            setSourceContent(newSourceIndex, map2.sourcesContent[raw.sourceIndex]);
          }
        }
        newSourceLine = raw.sourceLine;
        newSourceCharacter = raw.sourceCharacter;
        if (map2.names && raw.nameIndex !== void 0) {
          if (!nameIndexToNewNameIndexMap) nameIndexToNewNameIndexMap = [];
          newNameIndex = nameIndexToNewNameIndexMap[raw.nameIndex];
          if (newNameIndex === void 0) {
            nameIndexToNewNameIndexMap[raw.nameIndex] = newNameIndex = addName(map2.names[raw.nameIndex]);
          }
        }
      }
      const rawGeneratedLine = raw.generatedLine - (start ? start.line : 0);
      const newGeneratedLine = rawGeneratedLine + generatedLine;
      const rawGeneratedCharacter = start && start.line === raw.generatedLine ? raw.generatedCharacter - start.character : raw.generatedCharacter;
      const newGeneratedCharacter = rawGeneratedLine === 0 ? rawGeneratedCharacter + generatedCharacter : rawGeneratedCharacter;
      addMapping(newGeneratedLine, newGeneratedCharacter, newSourceIndex, newSourceLine, newSourceCharacter, newNameIndex);
    }
    exit();
  }
  function shouldCommitMapping() {
    return !hasLast || lastGeneratedLine !== pendingGeneratedLine || lastGeneratedCharacter !== pendingGeneratedCharacter || lastSourceIndex !== pendingSourceIndex || lastSourceLine !== pendingSourceLine || lastSourceCharacter !== pendingSourceCharacter || lastNameIndex !== pendingNameIndex;
  }
  function appendMappingCharCode(charCode) {
    mappingCharCodes.push(charCode);
    if (mappingCharCodes.length >= 1024) {
      flushMappingBuffer();
    }
  }
  function commitPendingMapping() {
    if (!hasPending || !shouldCommitMapping()) {
      return;
    }
    enter();
    if (lastGeneratedLine < pendingGeneratedLine) {
      do {
        appendMappingCharCode(59 /* semicolon */);
        lastGeneratedLine++;
      } while (lastGeneratedLine < pendingGeneratedLine);
      lastGeneratedCharacter = 0;
    } else {
      Debug.assertEqual(lastGeneratedLine, pendingGeneratedLine, "generatedLine cannot backtrack");
      if (hasLast) {
        appendMappingCharCode(44 /* comma */);
      }
    }
    appendBase64VLQ(pendingGeneratedCharacter - lastGeneratedCharacter);
    lastGeneratedCharacter = pendingGeneratedCharacter;
    if (hasPendingSource) {
      appendBase64VLQ(pendingSourceIndex - lastSourceIndex);
      lastSourceIndex = pendingSourceIndex;
      appendBase64VLQ(pendingSourceLine - lastSourceLine);
      lastSourceLine = pendingSourceLine;
      appendBase64VLQ(pendingSourceCharacter - lastSourceCharacter);
      lastSourceCharacter = pendingSourceCharacter;
      if (hasPendingName) {
        appendBase64VLQ(pendingNameIndex - lastNameIndex);
        lastNameIndex = pendingNameIndex;
      }
    }
    hasLast = true;
    exit();
  }
  function flushMappingBuffer() {
    if (mappingCharCodes.length > 0) {
      mappings += String.fromCharCode.apply(void 0, mappingCharCodes);
      mappingCharCodes.length = 0;
    }
  }
  function toJSON() {
    commitPendingMapping();
    flushMappingBuffer();
    return {
      version: 3,
      file,
      sourceRoot,
      sources,
      names,
      mappings,
      sourcesContent
    };
  }
  function appendBase64VLQ(inValue) {
    if (inValue < 0) {
      inValue = (-inValue << 1) + 1;
    } else {
      inValue = inValue << 1;
    }
    do {
      let currentDigit = inValue & 31;
      inValue = inValue >> 5;
      if (inValue > 0) {
        currentDigit = currentDigit | 32;
      }
      appendMappingCharCode(base64FormatEncode(currentDigit));
    } while (inValue > 0);
  }
}
var sourceMapCommentRegExpDontCareLineStart = /\/\/[@#] source[M]appingURL=(.+)\r?\n?$/;
var sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/;
var whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
function decodeMappings(mappings) {
  let done = false;
  let pos = 0;
  let generatedLine = 0;
  let generatedCharacter = 0;
  let sourceIndex = 0;
  let sourceLine = 0;
  let sourceCharacter = 0;
  let nameIndex = 0;
  let error;
  return {
    get pos() {
      return pos;
    },
    get error() {
      return error;
    },
    get state() {
      return captureMapping(
        /*hasSource*/
        true,
        /*hasName*/
        true
      );
    },
    next() {
      while (!done && pos < mappings.length) {
        const ch = mappings.charCodeAt(pos);
        if (ch === 59 /* semicolon */) {
          generatedLine++;
          generatedCharacter = 0;
          pos++;
          continue;
        }
        if (ch === 44 /* comma */) {
          pos++;
          continue;
        }
        let hasSource = false;
        let hasName = false;
        generatedCharacter += base64VLQFormatDecode();
        if (hasReportedError()) return stopIterating();
        if (generatedCharacter < 0) return setErrorAndStopIterating("Invalid generatedCharacter found");
        if (!isSourceMappingSegmentEnd()) {
          hasSource = true;
          sourceIndex += base64VLQFormatDecode();
          if (hasReportedError()) return stopIterating();
          if (sourceIndex < 0) return setErrorAndStopIterating("Invalid sourceIndex found");
          if (isSourceMappingSegmentEnd()) return setErrorAndStopIterating("Unsupported Format: No entries after sourceIndex");
          sourceLine += base64VLQFormatDecode();
          if (hasReportedError()) return stopIterating();
          if (sourceLine < 0) return setErrorAndStopIterating("Invalid sourceLine found");
          if (isSourceMappingSegmentEnd()) return setErrorAndStopIterating("Unsupported Format: No entries after sourceLine");
          sourceCharacter += base64VLQFormatDecode();
          if (hasReportedError()) return stopIterating();
          if (sourceCharacter < 0) return setErrorAndStopIterating("Invalid sourceCharacter found");
          if (!isSourceMappingSegmentEnd()) {
            hasName = true;
            nameIndex += base64VLQFormatDecode();
            if (hasReportedError()) return stopIterating();
            if (nameIndex < 0) return setErrorAndStopIterating("Invalid nameIndex found");
            if (!isSourceMappingSegmentEnd()) return setErrorAndStopIterating("Unsupported Error Format: Entries after nameIndex");
          }
        }
        return { value: captureMapping(hasSource, hasName), done };
      }
      return stopIterating();
    },
    [Symbol.iterator]() {
      return this;
    }
  };
  function captureMapping(hasSource, hasName) {
    return {
      generatedLine,
      generatedCharacter,
      sourceIndex: hasSource ? sourceIndex : void 0,
      sourceLine: hasSource ? sourceLine : void 0,
      sourceCharacter: hasSource ? sourceCharacter : void 0,
      nameIndex: hasName ? nameIndex : void 0
    };
  }
  function stopIterating() {
    done = true;
    return { value: void 0, done: true };
  }
  function setError(message) {
    if (error === void 0) {
      error = message;
    }
  }
  function setErrorAndStopIterating(message) {
    setError(message);
    return stopIterating();
  }
  function hasReportedError() {
    return error !== void 0;
  }
  function isSourceMappingSegmentEnd() {
    return pos === mappings.length || mappings.charCodeAt(pos) === 44 /* comma */ || mappings.charCodeAt(pos) === 59 /* semicolon */;
  }
  function base64VLQFormatDecode() {
    let moreDigits = true;
    let shiftCount = 0;
    let value = 0;
    for (; moreDigits; pos++) {
      if (pos >= mappings.length) return setError("Error in decoding base64VLQFormatDecode, past the mapping string"), -1;
      const currentByte = base64FormatDecode(mappings.charCodeAt(pos));
      if (currentByte === -1) return setError("Invalid character in VLQ"), -1;
      moreDigits = (currentByte & 32) !== 0;
      value = value | (currentByte & 31) << shiftCount;
      shiftCount += 5;
    }
    if ((value & 1) === 0) {
      value = value >> 1;
    } else {
      value = value >> 1;
      value = -value;
    }
    return value;
  }
}
function base64FormatEncode(value) {
  return value >= 0 && value < 26 ? 65 /* A */ + value : value >= 26 && value < 52 ? 97 /* a */ + value - 26 : value >= 52 && value < 62 ? 48 /* _0 */ + value - 52 : value === 62 ? 43 /* plus */ : value === 63 ? 47 /* slash */ : Debug.fail(`${value}: not a base64 value`);
}
function base64FormatDecode(ch) {
  return ch >= 65 /* A */ && ch <= 90 /* Z */ ? ch - 65 /* A */ : ch >= 97 /* a */ && ch <= 122 /* z */ ? ch - 97 /* a */ + 26 : ch >= 48 /* _0 */ && ch <= 57 /* _9 */ ? ch - 48 /* _0 */ + 52 : ch === 43 /* plus */ ? 62 : ch === 47 /* slash */ ? 63 : -1;
}

// src/compiler/transformers/utilities.ts
function getOriginalNodeId(node) {
  node = getOriginalNode(node);
  return node ? getNodeId(node) : 0;
}
function containsDefaultReference(node) {
  if (!node) return false;
  if (!isNamedImports(node) && !isNamedExports(node)) return false;
  return some(node.elements, isNamedDefaultReference);
}
function isNamedDefaultReference(e) {
  return e.propertyName !== void 0 ? e.propertyName.escapedText === "default" /* Default */ : e.name.escapedText === "default" /* Default */;
}
function chainBundle(context, transformSourceFile) {
  return transformSourceFileOrBundle;
  function transformSourceFileOrBundle(node) {
    return node.kind === 307 /* SourceFile */ ? transformSourceFile(node) : transformBundle(node);
  }
  function transformBundle(node) {
    return context.factory.createBundle(map(node.sourceFiles, transformSourceFile));
  }
}
function getExportNeedsImportStarHelper(node) {
  return !!getNamespaceDeclarationNode(node);
}
function getImportNeedsImportStarHelper(node) {
  if (!!getNamespaceDeclarationNode(node)) {
    return true;
  }
  const bindings = node.importClause && node.importClause.namedBindings;
  if (!bindings) {
    return false;
  }
  if (!isNamedImports(bindings)) return false;
  let defaultRefCount = 0;
  for (const binding of bindings.elements) {
    if (isNamedDefaultReference(binding)) {
      defaultRefCount++;
    }
  }
  return defaultRefCount > 0 && defaultRefCount !== bindings.elements.length || !!(bindings.elements.length - defaultRefCount) && isDefaultImport(node);
}
function getImportNeedsImportDefaultHelper(node) {
  return !getImportNeedsImportStarHelper(node) && (isDefaultImport(node) || !!node.importClause && isNamedImports(node.importClause.namedBindings) && containsDefaultReference(node.importClause.namedBindings));
}
function collectExternalModuleInfo(context, sourceFile) {
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const externalImports = [];
  const exportSpecifiers = new IdentifierNameMultiMap();
  const exportedBindings = [];
  const uniqueExports = /* @__PURE__ */ new Map();
  const exportedFunctions = /* @__PURE__ */ new Set();
  let exportedNames;
  let hasExportDefault = false;
  let exportEquals;
  let hasExportStarsToExportValues = false;
  let hasImportStar = false;
  let hasImportDefault = false;
  for (const node of sourceFile.statements) {
    switch (node.kind) {
      case 272 /* ImportDeclaration */:
        externalImports.push(node);
        if (!hasImportStar && getImportNeedsImportStarHelper(node)) {
          hasImportStar = true;
        }
        if (!hasImportDefault && getImportNeedsImportDefaultHelper(node)) {
          hasImportDefault = true;
        }
        break;
      case 271 /* ImportEqualsDeclaration */:
        if (node.moduleReference.kind === 283 /* ExternalModuleReference */) {
          externalImports.push(node);
        }
        break;
      case 278 /* ExportDeclaration */:
        if (node.moduleSpecifier) {
          if (!node.exportClause) {
            externalImports.push(node);
            hasExportStarsToExportValues = true;
          } else {
            externalImports.push(node);
            if (isNamedExports(node.exportClause)) {
              addExportedNamesForExportDeclaration(node);
              hasImportDefault || (hasImportDefault = containsDefaultReference(node.exportClause));
            } else {
              const name = node.exportClause.name;
              if (!uniqueExports.get(idText(name))) {
                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                uniqueExports.set(idText(name), true);
                exportedNames = append(exportedNames, name);
              }
              hasImportStar = true;
            }
          }
        } else {
          addExportedNamesForExportDeclaration(node);
        }
        break;
      case 277 /* ExportAssignment */:
        if (node.isExportEquals && !exportEquals) {
          exportEquals = node;
        }
        break;
      case 243 /* VariableStatement */:
        if (hasSyntacticModifier(node, 32 /* Export */)) {
          for (const decl of node.declarationList.declarations) {
            exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames, exportedBindings);
          }
        }
        break;
      case 262 /* FunctionDeclaration */:
        if (hasSyntacticModifier(node, 32 /* Export */)) {
          addExportedFunctionDeclaration(
            node,
            /*name*/
            void 0,
            hasSyntacticModifier(node, 2048 /* Default */)
          );
        }
        break;
      case 263 /* ClassDeclaration */:
        if (hasSyntacticModifier(node, 32 /* Export */)) {
          if (hasSyntacticModifier(node, 2048 /* Default */)) {
            if (!hasExportDefault) {
              multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), context.factory.getDeclarationName(node));
              hasExportDefault = true;
            }
          } else {
            const name = node.name;
            if (name && !uniqueExports.get(idText(name))) {
              multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
              uniqueExports.set(idText(name), true);
              exportedNames = append(exportedNames, name);
            }
          }
        }
        break;
    }
  }
  const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(context.factory, context.getEmitHelperFactory(), sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault);
  if (externalHelpersImportDeclaration) {
    externalImports.unshift(externalHelpersImportDeclaration);
  }
  return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, exportedFunctions, externalHelpersImportDeclaration };
  function addExportedNamesForExportDeclaration(node) {
    for (const specifier of cast(node.exportClause, isNamedExports).elements) {
      if (!uniqueExports.get(idText(specifier.name))) {
        const name = specifier.propertyName || specifier.name;
        if (!node.moduleSpecifier) {
          exportSpecifiers.add(name, specifier);
        }
        const decl = resolver.getReferencedImportDeclaration(name) || resolver.getReferencedValueDeclaration(name);
        if (decl) {
          if (decl.kind === 262 /* FunctionDeclaration */) {
            addExportedFunctionDeclaration(decl, specifier.name, specifier.name.escapedText === "default" /* Default */);
            continue;
          }
          multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
        }
        uniqueExports.set(idText(specifier.name), true);
        exportedNames = append(exportedNames, specifier.name);
      }
    }
  }
  function addExportedFunctionDeclaration(node, name, isDefault) {
    exportedFunctions.add(node);
    if (isDefault) {
      if (!hasExportDefault) {
        multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name ?? context.factory.getDeclarationName(node));
        hasExportDefault = true;
      }
    } else {
      name ?? (name = node.name);
      if (!uniqueExports.get(idText(name))) {
        multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
        uniqueExports.set(idText(name), true);
      }
    }
  }
}
function collectExportedVariableInfo(decl, uniqueExports, exportedNames, exportedBindings) {
  if (isBindingPattern(decl.name)) {
    for (const element of decl.name.elements) {
      if (!isOmittedExpression(element)) {
        exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames, exportedBindings);
      }
    }
  } else if (!isGeneratedIdentifier(decl.name)) {
    const text = idText(decl.name);
    if (!uniqueExports.get(text)) {
      uniqueExports.set(text, true);
      exportedNames = append(exportedNames, decl.name);
      if (isLocalName(decl.name)) {
        multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), decl.name);
      }
    }
  }
  return exportedNames;
}
function multiMapSparseArrayAdd(map2, key, value) {
  let values = map2[key];
  if (values) {
    values.push(value);
  } else {
    map2[key] = values = [value];
  }
  return values;
}
var IdentifierNameMap = class _IdentifierNameMap {
  constructor() {
    this._map = /* @__PURE__ */ new Map();
  }
  get size() {
    return this._map.size;
  }
  has(key) {
    return this._map.has(_IdentifierNameMap.toKey(key));
  }
  get(key) {
    return this._map.get(_IdentifierNameMap.toKey(key));
  }
  set(key, value) {
    this._map.set(_IdentifierNameMap.toKey(key), value);
    return this;
  }
  delete(key) {
    var _a;
    return ((_a = this._map) == null ? void 0 : _a.delete(_IdentifierNameMap.toKey(key))) ?? false;
  }
  clear() {
    this._map.clear();
  }
  values() {
    return this._map.values();
  }
  static toKey(name) {
    if (isGeneratedPrivateIdentifier(name) || isGeneratedIdentifier(name)) {
      const autoGenerate = name.emitNode.autoGenerate;
      if ((autoGenerate.flags & 7 /* KindMask */) === 4 /* Node */) {
        const node = getNodeForGeneratedName(name);
        const baseName = isMemberName(node) && node !== name ? _IdentifierNameMap.toKey(node) : `(generated@${getNodeId(node)})`;
        return formatGeneratedName(
          /*privateName*/
          false,
          autoGenerate.prefix,
          baseName,
          autoGenerate.suffix,
          _IdentifierNameMap.toKey
        );
      } else {
        const baseName = `(auto@${autoGenerate.id})`;
        return formatGeneratedName(
          /*privateName*/
          false,
          autoGenerate.prefix,
          baseName,
          autoGenerate.suffix,
          _IdentifierNameMap.toKey
        );
      }
    }
    if (isPrivateIdentifier(name)) {
      return idText(name).slice(1);
    }
    return idText(name);
  }
};
var IdentifierNameMultiMap = class extends IdentifierNameMap {
  add(key, value) {
    let values = this.get(key);
    if (values) {
      values.push(value);
    } else {
      this.set(key, values = [value]);
    }
    return values;
  }
  remove(key, value) {
    const values = this.get(key);
    if (values) {
      unorderedRemoveItem(values, value);
      if (!values.length) {
        this.delete(key);
      }
    }
  }
};
function isSimpleCopiableExpression(expression) {
  return isStringLiteralLike(expression) || expression.kind === 9 /* NumericLiteral */ || isKeyword(expression.kind) || isIdentifier(expression);
}
function isSimpleInlineableExpression(expression) {
  return !isIdentifier(expression) && isSimpleCopiableExpression(expression);
}
function isCompoundAssignment(kind) {
  return kind >= 65 /* FirstCompoundAssignment */ && kind <= 79 /* LastCompoundAssignment */;
}
function getNonAssignmentOperatorForCompoundAssignment(kind) {
  switch (kind) {
    case 65 /* PlusEqualsToken */:
      return 40 /* PlusToken */;
    case 66 /* MinusEqualsToken */:
      return 41 /* MinusToken */;
    case 67 /* AsteriskEqualsToken */:
      return 42 /* AsteriskToken */;
    case 68 /* AsteriskAsteriskEqualsToken */:
      return 43 /* AsteriskAsteriskToken */;
    case 69 /* SlashEqualsToken */:
      return 44 /* SlashToken */;
    case 70 /* PercentEqualsToken */:
      return 45 /* PercentToken */;
    case 71 /* LessThanLessThanEqualsToken */:
      return 48 /* LessThanLessThanToken */;
    case 72 /* GreaterThanGreaterThanEqualsToken */:
      return 49 /* GreaterThanGreaterThanToken */;
    case 73 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
      return 50 /* GreaterThanGreaterThanGreaterThanToken */;
    case 74 /* AmpersandEqualsToken */:
      return 51 /* AmpersandToken */;
    case 75 /* BarEqualsToken */:
      return 52 /* BarToken */;
    case 79 /* CaretEqualsToken */:
      return 53 /* CaretToken */;
    case 76 /* BarBarEqualsToken */:
      return 57 /* BarBarToken */;
    case 77 /* AmpersandAmpersandEqualsToken */:
      return 56 /* AmpersandAmpersandToken */;
    case 78 /* QuestionQuestionEqualsToken */:
      return 61 /* QuestionQuestionToken */;
  }
}
function getSuperCallFromStatement(statement) {
  if (!isExpressionStatement(statement)) {
    return void 0;
  }
  const expression = skipParentheses(statement.expression);
  return isSuperCall(expression) ? expression : void 0;
}
function findSuperStatementIndexPathWorker(statements, start, indices) {
  for (let i = start; i < statements.length; i += 1) {
    const statement = statements[i];
    if (getSuperCallFromStatement(statement)) {
      indices.unshift(i);
      return true;
    } else if (isTryStatement(statement) && findSuperStatementIndexPathWorker(statement.tryBlock.statements, 0, indices)) {
      indices.unshift(i);
      return true;
    }
  }
  return false;
}
function findSuperStatementIndexPath(statements, start) {
  const indices = [];
  findSuperStatementIndexPathWorker(statements, start, indices);
  return indices;
}
function getProperties(node, requireInitializer, isStatic2) {
  return filter(node.members, (m) => isInitializedOrStaticProperty(m, requireInitializer, isStatic2));
}
function isStaticPropertyDeclarationOrClassStaticBlockDeclaration(element) {
  return isStaticPropertyDeclaration(element) || isClassStaticBlockDeclaration(element);
}
function getStaticPropertiesAndClassStaticBlock(node) {
  return filter(node.members, isStaticPropertyDeclarationOrClassStaticBlockDeclaration);
}
function isInitializedOrStaticProperty(member, requireInitializer, isStatic2) {
  return isPropertyDeclaration(member) && (!!member.initializer || !requireInitializer) && hasStaticModifier(member) === isStatic2;
}
function isStaticPropertyDeclaration(member) {
  return isPropertyDeclaration(member) && hasStaticModifier(member);
}
function isInitializedProperty(member) {
  return member.kind === 172 /* PropertyDeclaration */ && member.initializer !== void 0;
}
function isNonStaticMethodOrAccessorWithPrivateName(member) {
  return !isStatic(member) && (isMethodOrAccessor(member) || isAutoAccessorPropertyDeclaration(member)) && isPrivateIdentifier(member.name);
}
function getDecoratorsOfParameters(node) {
  let decorators;
  if (node) {
    const parameters = node.parameters;
    const firstParameterIsThis = parameters.length > 0 && parameterIsThisKeyword(parameters[0]);
    const firstParameterOffset = firstParameterIsThis ? 1 : 0;
    const numParameters = firstParameterIsThis ? parameters.length - 1 : parameters.length;
    for (let i = 0; i < numParameters; i++) {
      const parameter = parameters[i + firstParameterOffset];
      if (decorators || hasDecorators(parameter)) {
        if (!decorators) {
          decorators = new Array(numParameters);
        }
        decorators[i] = getDecorators(parameter);
      }
    }
  }
  return decorators;
}
function getAllDecoratorsOfClass(node) {
  const decorators = getDecorators(node);
  const parameters = getDecoratorsOfParameters(getFirstConstructorWithBody(node));
  if (!some(decorators) && !some(parameters)) {
    return void 0;
  }
  return {
    decorators,
    parameters
  };
}
function getAllDecoratorsOfClassElement(member, parent, useLegacyDecorators) {
  switch (member.kind) {
    case 177 /* GetAccessor */:
    case 178 /* SetAccessor */:
      if (!useLegacyDecorators) {
        return getAllDecoratorsOfMethod(member);
      }
      return getAllDecoratorsOfAccessors(member, parent);
    case 174 /* MethodDeclaration */:
      return getAllDecoratorsOfMethod(member);
    case 172 /* PropertyDeclaration */:
      return getAllDecoratorsOfProperty(member);
    default:
      return void 0;
  }
}
function getAllDecoratorsOfAccessors(accessor, parent) {
  if (!accessor.body) {
    return void 0;
  }
  const { firstAccessor, secondAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(parent.members, accessor);
  const firstAccessorWithDecorators = hasDecorators(firstAccessor) ? firstAccessor : secondAccessor && hasDecorators(secondAccessor) ? secondAccessor : void 0;
  if (!firstAccessorWithDecorators || accessor !== firstAccessorWithDecorators) {
    return void 0;
  }
  const decorators = getDecorators(firstAccessorWithDecorators);
  const parameters = getDecoratorsOfParameters(setAccessor);
  if (!some(decorators) && !some(parameters)) {
    return void 0;
  }
  return {
    decorators,
    parameters,
    getDecorators: getAccessor && getDecorators(getAccessor),
    setDecorators: setAccessor && getDecorators(setAccessor)
  };
}
function getAllDecoratorsOfMethod(method) {
  if (!method.body) {
    return void 0;
  }
  const decorators = getDecorators(method);
  const parameters = getDecoratorsOfParameters(method);
  if (!some(decorators) && !some(parameters)) {
    return void 0;
  }
  return { decorators, parameters };
}
function getAllDecoratorsOfProperty(property) {
  const decorators = getDecorators(property);
  if (!some(decorators)) {
    return void 0;
  }
  return { decorators };
}
function walkUpLexicalEnvironments(env, cb) {
  while (env) {
    const result = cb(env);
    if (result !== void 0) return result;
    env = env.previous;
  }
}
function newPrivateEnvironment(data) {
  return { data };
}
function getPrivateIdentifier(privateEnv, name) {
  var _a, _b;
  return isGeneratedPrivateIdentifier(name) ? (_a = privateEnv == null ? void 0 : privateEnv.generatedIdentifiers) == null ? void 0 : _a.get(getNodeForGeneratedName(name)) : (_b = privateEnv == null ? void 0 : privateEnv.identifiers) == null ? void 0 : _b.get(name.escapedText);
}
function setPrivateIdentifier(privateEnv, name, entry) {
  if (isGeneratedPrivateIdentifier(name)) {
    privateEnv.generatedIdentifiers ?? (privateEnv.generatedIdentifiers = /* @__PURE__ */ new Map());
    privateEnv.generatedIdentifiers.set(getNodeForGeneratedName(name), entry);
  } else {
    privateEnv.identifiers ?? (privateEnv.identifiers = /* @__PURE__ */ new Map());
    privateEnv.identifiers.set(name.escapedText, entry);
  }
}
function accessPrivateIdentifier(env, name) {
  return walkUpLexicalEnvironments(env, (env2) => getPrivateIdentifier(env2.privateEnv, name));
}
function isSimpleParameter(node) {
  return !node.initializer && isIdentifier(node.name);
}
function isSimpleParameterList(nodes) {
  return every(nodes, isSimpleParameter);
}

// src/compiler/transformers/destructuring.ts
function flattenDestructuringAssignment(node, visitor, context, level, needsValue, createAssignmentCallback) {
  let location = node;
  let value;
  if (isDestructuringAssignment(node)) {
    value = node.right;
    while (isEmptyArrayLiteral(node.left) || isEmptyObjectLiteral(node.left)) {
      if (isDestructuringAssignment(value)) {
        location = node = value;
        value = node.right;
      } else {
        return Debug.checkDefined(visitNode(value, visitor, isExpression));
      }
    }
  }
  let expressions;
  const flattenContext = {
    context,
    level,
    downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
    hoistTempVariables: true,
    emitExpression,
    emitBindingOrAssignment,
    createArrayBindingOrAssignmentPattern: (elements) => makeArrayAssignmentPattern(context.factory, elements),
    createObjectBindingOrAssignmentPattern: (elements) => makeObjectAssignmentPattern(context.factory, elements),
    createArrayBindingOrAssignmentElement: makeAssignmentElement,
    visitor
  };
  if (value) {
    value = visitNode(value, visitor, isExpression);
    Debug.assert(value);
    if (isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText) || bindingOrAssignmentElementContainsNonLiteralComputedName(node)) {
      value = ensureIdentifier(
        flattenContext,
        value,
        /*reuseIdentifierExpressions*/
        false,
        location
      );
    } else if (needsValue) {
      value = ensureIdentifier(
        flattenContext,
        value,
        /*reuseIdentifierExpressions*/
        true,
        location
      );
    } else if (nodeIsSynthesized(node)) {
      location = value;
    }
  }
  flattenBindingOrAssignmentElement(
    flattenContext,
    node,
    value,
    location,
    /*skipInitializer*/
    isDestructuringAssignment(node)
  );
  if (value && needsValue) {
    if (!some(expressions)) {
      return value;
    }
    expressions.push(value);
  }
  return context.factory.inlineExpressions(expressions) || context.factory.createOmittedExpression();
  function emitExpression(expression) {
    expressions = append(expressions, expression);
  }
  function emitBindingOrAssignment(target, value2, location2, original) {
    Debug.assertNode(target, createAssignmentCallback ? isIdentifier : isExpression);
    const expression = createAssignmentCallback ? createAssignmentCallback(target, value2, location2) : setTextRange(
      context.factory.createAssignment(Debug.checkDefined(visitNode(target, visitor, isExpression)), value2),
      location2
    );
    expression.original = original;
    emitExpression(expression);
  }
}
function bindingOrAssignmentElementAssignsToName(element, escapedName) {
  const target = getTargetOfBindingOrAssignmentElement(element);
  if (isBindingOrAssignmentPattern(target)) {
    return bindingOrAssignmentPatternAssignsToName(target, escapedName);
  } else if (isIdentifier(target)) {
    return target.escapedText === escapedName;
  }
  return false;
}
function bindingOrAssignmentPatternAssignsToName(pattern, escapedName) {
  const elements = getElementsOfBindingOrAssignmentPattern(pattern);
  for (const element of elements) {
    if (bindingOrAssignmentElementAssignsToName(element, escapedName)) {
      return true;
    }
  }
  return false;
}
function bindingOrAssignmentElementContainsNonLiteralComputedName(element) {
  const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(element);
  if (propertyName && isComputedPropertyName(propertyName) && !isLiteralExpression(propertyName.expression)) {
    return true;
  }
  const target = getTargetOfBindingOrAssignmentElement(element);
  return !!target && isBindingOrAssignmentPattern(target) && bindingOrAssignmentPatternContainsNonLiteralComputedName(target);
}
function bindingOrAssignmentPatternContainsNonLiteralComputedName(pattern) {
  return !!forEach(getElementsOfBindingOrAssignmentPattern(pattern), bindingOrAssignmentElementContainsNonLiteralComputedName);
}
function flattenDestructuringBinding(node, visitor, context, level, rval, hoistTempVariables = false, skipInitializer) {
  let pendingExpressions;
  const pendingDeclarations = [];
  const declarations = [];
  const flattenContext = {
    context,
    level,
    downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
    hoistTempVariables,
    emitExpression,
    emitBindingOrAssignment,
    createArrayBindingOrAssignmentPattern: (elements) => makeArrayBindingPattern(context.factory, elements),
    createObjectBindingOrAssignmentPattern: (elements) => makeObjectBindingPattern(context.factory, elements),
    createArrayBindingOrAssignmentElement: (name) => makeBindingElement(context.factory, name),
    visitor
  };
  if (isVariableDeclaration(node)) {
    let initializer = getInitializerOfBindingOrAssignmentElement(node);
    if (initializer && (isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText) || bindingOrAssignmentElementContainsNonLiteralComputedName(node))) {
      initializer = ensureIdentifier(
        flattenContext,
        Debug.checkDefined(visitNode(initializer, flattenContext.visitor, isExpression)),
        /*reuseIdentifierExpressions*/
        false,
        initializer
      );
      node = context.factory.updateVariableDeclaration(
        node,
        node.name,
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        initializer
      );
    }
  }
  flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer);
  if (pendingExpressions) {
    const temp = context.factory.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    if (hoistTempVariables) {
      const value = context.factory.inlineExpressions(pendingExpressions);
      pendingExpressions = void 0;
      emitBindingOrAssignment(
        temp,
        value,
        /*location*/
        void 0,
        /*original*/
        void 0
      );
    } else {
      context.hoistVariableDeclaration(temp);
      const pendingDeclaration = last(pendingDeclarations);
      pendingDeclaration.pendingExpressions = append(
        pendingDeclaration.pendingExpressions,
        context.factory.createAssignment(temp, pendingDeclaration.value)
      );
      addRange(pendingDeclaration.pendingExpressions, pendingExpressions);
      pendingDeclaration.value = temp;
    }
  }
  for (const { pendingExpressions: pendingExpressions2, name, value, location, original } of pendingDeclarations) {
    const variable = context.factory.createVariableDeclaration(
      name,
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      pendingExpressions2 ? context.factory.inlineExpressions(append(pendingExpressions2, value)) : value
    );
    variable.original = original;
    setTextRange(variable, location);
    declarations.push(variable);
  }
  return declarations;
  function emitExpression(value) {
    pendingExpressions = append(pendingExpressions, value);
  }
  function emitBindingOrAssignment(target, value, location, original) {
    Debug.assertNode(target, isBindingName);
    if (pendingExpressions) {
      value = context.factory.inlineExpressions(append(pendingExpressions, value));
      pendingExpressions = void 0;
    }
    pendingDeclarations.push({ pendingExpressions, name: target, value, location, original });
  }
}
function flattenBindingOrAssignmentElement(flattenContext, element, value, location, skipInitializer) {
  const bindingTarget = getTargetOfBindingOrAssignmentElement(element);
  if (!skipInitializer) {
    const initializer = visitNode(getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, isExpression);
    if (initializer) {
      if (value) {
        value = createDefaultValueCheck(flattenContext, value, initializer, location);
        if (!isSimpleInlineableExpression(initializer) && isBindingOrAssignmentPattern(bindingTarget)) {
          value = ensureIdentifier(
            flattenContext,
            value,
            /*reuseIdentifierExpressions*/
            true,
            location
          );
        }
      } else {
        value = initializer;
      }
    } else if (!value) {
      value = flattenContext.context.factory.createVoidZero();
    }
  }
  if (isObjectBindingOrAssignmentPattern(bindingTarget)) {
    flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
  } else if (isArrayBindingOrAssignmentPattern(bindingTarget)) {
    flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
  } else {
    flattenContext.emitBindingOrAssignment(
      bindingTarget,
      value,
      location,
      /*original*/
      element
    );
  }
}
function flattenObjectBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
  const elements = getElementsOfBindingOrAssignmentPattern(pattern);
  const numElements = elements.length;
  if (numElements !== 1) {
    const reuseIdentifierExpressions = !isDeclarationBindingElement(parent) || numElements !== 0;
    value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
  }
  let bindingElements;
  let computedTempVariables;
  for (let i = 0; i < numElements; i++) {
    const element = elements[i];
    if (!getRestIndicatorOfBindingOrAssignmentElement(element)) {
      const propertyName = getPropertyNameOfBindingOrAssignmentElement(element);
      if (flattenContext.level >= 1 /* ObjectRest */ && !(element.transformFlags & (32768 /* ContainsRestOrSpread */ | 65536 /* ContainsObjectRestOrSpread */)) && !(getTargetOfBindingOrAssignmentElement(element).transformFlags & (32768 /* ContainsRestOrSpread */ | 65536 /* ContainsObjectRestOrSpread */)) && !isComputedPropertyName(propertyName)) {
        bindingElements = append(bindingElements, visitNode(element, flattenContext.visitor, isBindingOrAssignmentElement));
      } else {
        if (bindingElements) {
          flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
          bindingElements = void 0;
        }
        const rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName);
        if (isComputedPropertyName(propertyName)) {
          computedTempVariables = append(computedTempVariables, rhsValue.argumentExpression);
        }
        flattenBindingOrAssignmentElement(
          flattenContext,
          element,
          rhsValue,
          /*location*/
          element
        );
      }
    } else if (i === numElements - 1) {
      if (bindingElements) {
        flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        bindingElements = void 0;
      }
      const rhsValue = flattenContext.context.getEmitHelperFactory().createRestHelper(value, elements, computedTempVariables, pattern);
      flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element);
    }
  }
  if (bindingElements) {
    flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
  }
}
function flattenArrayBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
  const elements = getElementsOfBindingOrAssignmentPattern(pattern);
  const numElements = elements.length;
  if (flattenContext.level < 1 /* ObjectRest */ && flattenContext.downlevelIteration) {
    value = ensureIdentifier(
      flattenContext,
      setTextRange(
        flattenContext.context.getEmitHelperFactory().createReadHelper(
          value,
          numElements > 0 && getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1]) ? void 0 : numElements
        ),
        location
      ),
      /*reuseIdentifierExpressions*/
      false,
      location
    );
  } else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0) || every(elements, isOmittedExpression)) {
    const reuseIdentifierExpressions = !isDeclarationBindingElement(parent) || numElements !== 0;
    value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
  }
  let bindingElements;
  let restContainingElements;
  for (let i = 0; i < numElements; i++) {
    const element = elements[i];
    if (flattenContext.level >= 1 /* ObjectRest */) {
      if (element.transformFlags & 65536 /* ContainsObjectRestOrSpread */ || flattenContext.hasTransformedPriorElement && !isSimpleBindingOrAssignmentElement(element)) {
        flattenContext.hasTransformedPriorElement = true;
        const temp = flattenContext.context.factory.createTempVariable(
          /*recordTempVariable*/
          void 0
        );
        if (flattenContext.hoistTempVariables) {
          flattenContext.context.hoistVariableDeclaration(temp);
        }
        restContainingElements = append(restContainingElements, [temp, element]);
        bindingElements = append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp));
      } else {
        bindingElements = append(bindingElements, element);
      }
    } else if (isOmittedExpression(element)) {
      continue;
    } else if (!getRestIndicatorOfBindingOrAssignmentElement(element)) {
      const rhsValue = flattenContext.context.factory.createElementAccessExpression(value, i);
      flattenBindingOrAssignmentElement(
        flattenContext,
        element,
        rhsValue,
        /*location*/
        element
      );
    } else if (i === numElements - 1) {
      const rhsValue = flattenContext.context.factory.createArraySliceCall(value, i);
      flattenBindingOrAssignmentElement(
        flattenContext,
        element,
        rhsValue,
        /*location*/
        element
      );
    }
  }
  if (bindingElements) {
    flattenContext.emitBindingOrAssignment(flattenContext.createArrayBindingOrAssignmentPattern(bindingElements), value, location, pattern);
  }
  if (restContainingElements) {
    for (const [id, element] of restContainingElements) {
      flattenBindingOrAssignmentElement(flattenContext, element, id, element);
    }
  }
}
function isSimpleBindingOrAssignmentElement(element) {
  const target = getTargetOfBindingOrAssignmentElement(element);
  if (!target || isOmittedExpression(target)) return true;
  const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(element);
  if (propertyName && !isPropertyNameLiteral(propertyName)) return false;
  const initializer = getInitializerOfBindingOrAssignmentElement(element);
  if (initializer && !isSimpleInlineableExpression(initializer)) return false;
  if (isBindingOrAssignmentPattern(target)) return every(getElementsOfBindingOrAssignmentPattern(target), isSimpleBindingOrAssignmentElement);
  return isIdentifier(target);
}
function createDefaultValueCheck(flattenContext, value, defaultValue, location) {
  value = ensureIdentifier(
    flattenContext,
    value,
    /*reuseIdentifierExpressions*/
    true,
    location
  );
  return flattenContext.context.factory.createConditionalExpression(
    flattenContext.context.factory.createTypeCheck(value, "undefined"),
    /*questionToken*/
    void 0,
    defaultValue,
    /*colonToken*/
    void 0,
    value
  );
}
function createDestructuringPropertyAccess(flattenContext, value, propertyName) {
  const { factory: factory2 } = flattenContext.context;
  if (isComputedPropertyName(propertyName)) {
    const argumentExpression = ensureIdentifier(
      flattenContext,
      Debug.checkDefined(visitNode(propertyName.expression, flattenContext.visitor, isExpression)),
      /*reuseIdentifierExpressions*/
      false,
      /*location*/
      propertyName
    );
    return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression);
  } else if (isStringOrNumericLiteralLike(propertyName)) {
    const argumentExpression = factory2.cloneNode(propertyName);
    return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression);
  } else {
    const name = flattenContext.context.factory.createIdentifier(idText(propertyName));
    return flattenContext.context.factory.createPropertyAccessExpression(value, name);
  }
}
function ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location) {
  if (isIdentifier(value) && reuseIdentifierExpressions) {
    return value;
  } else {
    const temp = flattenContext.context.factory.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    if (flattenContext.hoistTempVariables) {
      flattenContext.context.hoistVariableDeclaration(temp);
      flattenContext.emitExpression(setTextRange(flattenContext.context.factory.createAssignment(temp, value), location));
    } else {
      flattenContext.emitBindingOrAssignment(
        temp,
        value,
        location,
        /*original*/
        void 0
      );
    }
    return temp;
  }
}
function makeArrayBindingPattern(factory2, elements) {
  Debug.assertEachNode(elements, isArrayBindingElement);
  return factory2.createArrayBindingPattern(elements);
}
function makeArrayAssignmentPattern(factory2, elements) {
  Debug.assertEachNode(elements, isArrayBindingOrAssignmentElement);
  return factory2.createArrayLiteralExpression(map(elements, factory2.converters.convertToArrayAssignmentElement));
}
function makeObjectBindingPattern(factory2, elements) {
  Debug.assertEachNode(elements, isBindingElement);
  return factory2.createObjectBindingPattern(elements);
}
function makeObjectAssignmentPattern(factory2, elements) {
  Debug.assertEachNode(elements, isObjectBindingOrAssignmentElement);
  return factory2.createObjectLiteralExpression(map(elements, factory2.converters.convertToObjectAssignmentElement));
}
function makeBindingElement(factory2, name) {
  return factory2.createBindingElement(
    /*dotDotDotToken*/
    void 0,
    /*propertyName*/
    void 0,
    name
  );
}
function makeAssignmentElement(name) {
  return name;
}

// src/compiler/transformers/classThis.ts
function createClassThisAssignmentBlock(factory2, classThis, thisExpression = factory2.createThis()) {
  const expression = factory2.createAssignment(classThis, thisExpression);
  const statement = factory2.createExpressionStatement(expression);
  const body = factory2.createBlock(
    [statement],
    /*multiLine*/
    false
  );
  const block = factory2.createClassStaticBlockDeclaration(body);
  getOrCreateEmitNode(block).classThis = classThis;
  return block;
}
function isClassThisAssignmentBlock(node) {
  var _a;
  if (!isClassStaticBlockDeclaration(node) || node.body.statements.length !== 1) {
    return false;
  }
  const statement = node.body.statements[0];
  return isExpressionStatement(statement) && isAssignmentExpression(
    statement.expression,
    /*excludeCompoundAssignment*/
    true
  ) && isIdentifier(statement.expression.left) && ((_a = node.emitNode) == null ? void 0 : _a.classThis) === statement.expression.left && statement.expression.right.kind === 110 /* ThisKeyword */;
}
function classHasClassThisAssignment(node) {
  var _a;
  return !!((_a = node.emitNode) == null ? void 0 : _a.classThis) && some(node.members, isClassThisAssignmentBlock);
}
function injectClassThisAssignmentIfMissing(factory2, node, classThis, thisExpression) {
  if (classHasClassThisAssignment(node)) {
    return node;
  }
  const staticBlock = createClassThisAssignmentBlock(factory2, classThis, thisExpression);
  if (node.name) {
    setSourceMapRange(staticBlock.body.statements[0], node.name);
  }
  const members = factory2.createNodeArray([staticBlock, ...node.members]);
  setTextRange(members, node.members);
  const updatedNode = isClassDeclaration(node) ? factory2.updateClassDeclaration(
    node,
    node.modifiers,
    node.name,
    node.typeParameters,
    node.heritageClauses,
    members
  ) : factory2.updateClassExpression(
    node,
    node.modifiers,
    node.name,
    node.typeParameters,
    node.heritageClauses,
    members
  );
  getOrCreateEmitNode(updatedNode).classThis = classThis;
  return updatedNode;
}

// src/compiler/transformers/namedEvaluation.ts
function getAssignedNameOfIdentifier(factory2, name, expression) {
  const original = getOriginalNode(skipOuterExpressions(expression));
  if ((isClassDeclaration(original) || isFunctionDeclaration(original)) && !original.name && hasSyntacticModifier(original, 2048 /* Default */)) {
    return factory2.createStringLiteral("default");
  }
  return factory2.createStringLiteralFromNode(name);
}
function getAssignedNameOfPropertyName(context, name, assignedNameText) {
  const { factory: factory2 } = context;
  if (assignedNameText !== void 0) {
    const assignedName2 = factory2.createStringLiteral(assignedNameText);
    return { assignedName: assignedName2, name };
  }
  if (isPropertyNameLiteral(name) || isPrivateIdentifier(name)) {
    const assignedName2 = factory2.createStringLiteralFromNode(name);
    return { assignedName: assignedName2, name };
  }
  if (isPropertyNameLiteral(name.expression) && !isIdentifier(name.expression)) {
    const assignedName2 = factory2.createStringLiteralFromNode(name.expression);
    return { assignedName: assignedName2, name };
  }
  const assignedName = factory2.getGeneratedNameForNode(name);
  context.hoistVariableDeclaration(assignedName);
  const key = context.getEmitHelperFactory().createPropKeyHelper(name.expression);
  const assignment = factory2.createAssignment(assignedName, key);
  const updatedName = factory2.updateComputedPropertyName(name, assignment);
  return { assignedName, name: updatedName };
}
function createClassNamedEvaluationHelperBlock(context, assignedName, thisExpression = context.factory.createThis()) {
  const { factory: factory2 } = context;
  const expression = context.getEmitHelperFactory().createSetFunctionNameHelper(thisExpression, assignedName);
  const statement = factory2.createExpressionStatement(expression);
  const body = factory2.createBlock(
    [statement],
    /*multiLine*/
    false
  );
  const block = factory2.createClassStaticBlockDeclaration(body);
  getOrCreateEmitNode(block).assignedName = assignedName;
  return block;
}
function isClassNamedEvaluationHelperBlock(node) {
  var _a;
  if (!isClassStaticBlockDeclaration(node) || node.body.statements.length !== 1) {
    return false;
  }
  const statement = node.body.statements[0];
  return isExpressionStatement(statement) && isCallToHelper(statement.expression, "___setFunctionName") && statement.expression.arguments.length >= 2 && statement.expression.arguments[1] === ((_a = node.emitNode) == null ? void 0 : _a.assignedName);
}
function classHasExplicitlyAssignedName(node) {
  var _a;
  return !!((_a = node.emitNode) == null ? void 0 : _a.assignedName) && some(node.members, isClassNamedEvaluationHelperBlock);
}
function classHasDeclaredOrExplicitlyAssignedName(node) {
  return !!node.name || classHasExplicitlyAssignedName(node);
}
function injectClassNamedEvaluationHelperBlockIfMissing(context, node, assignedName, thisExpression) {
  if (classHasExplicitlyAssignedName(node)) {
    return node;
  }
  const { factory: factory2 } = context;
  const namedEvaluationBlock = createClassNamedEvaluationHelperBlock(context, assignedName, thisExpression);
  if (node.name) {
    setSourceMapRange(namedEvaluationBlock.body.statements[0], node.name);
  }
  const insertionIndex = findIndex(node.members, isClassThisAssignmentBlock) + 1;
  const leading = node.members.slice(0, insertionIndex);
  const trailing = node.members.slice(insertionIndex);
  const members = factory2.createNodeArray([...leading, namedEvaluationBlock, ...trailing]);
  setTextRange(members, node.members);
  node = isClassDeclaration(node) ? factory2.updateClassDeclaration(
    node,
    node.modifiers,
    node.name,
    node.typeParameters,
    node.heritageClauses,
    members
  ) : factory2.updateClassExpression(
    node,
    node.modifiers,
    node.name,
    node.typeParameters,
    node.heritageClauses,
    members
  );
  getOrCreateEmitNode(node).assignedName = assignedName;
  return node;
}
function finishTransformNamedEvaluation(context, expression, assignedName, ignoreEmptyStringLiteral) {
  if (ignoreEmptyStringLiteral && isStringLiteral(assignedName) && isEmptyStringLiteral(assignedName)) {
    return expression;
  }
  const { factory: factory2 } = context;
  const innerExpression = skipOuterExpressions(expression);
  const updatedExpression = isClassExpression(innerExpression) ? cast(injectClassNamedEvaluationHelperBlockIfMissing(context, innerExpression, assignedName), isClassExpression) : context.getEmitHelperFactory().createSetFunctionNameHelper(innerExpression, assignedName);
  return factory2.restoreOuterExpressions(expression, updatedExpression);
}
function transformNamedEvaluationOfPropertyAssignment(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const { assignedName, name } = getAssignedNameOfPropertyName(context, node.name, assignedNameText);
  const initializer = finishTransformNamedEvaluation(context, node.initializer, assignedName, ignoreEmptyStringLiteral);
  return factory2.updatePropertyAssignment(
    node,
    name,
    initializer
  );
}
function transformNamedEvaluationOfShorthandAssignmentProperty(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const assignedName = assignedNameText !== void 0 ? factory2.createStringLiteral(assignedNameText) : getAssignedNameOfIdentifier(factory2, node.name, node.objectAssignmentInitializer);
  const objectAssignmentInitializer = finishTransformNamedEvaluation(context, node.objectAssignmentInitializer, assignedName, ignoreEmptyStringLiteral);
  return factory2.updateShorthandPropertyAssignment(
    node,
    node.name,
    objectAssignmentInitializer
  );
}
function transformNamedEvaluationOfVariableDeclaration(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const assignedName = assignedNameText !== void 0 ? factory2.createStringLiteral(assignedNameText) : getAssignedNameOfIdentifier(factory2, node.name, node.initializer);
  const initializer = finishTransformNamedEvaluation(context, node.initializer, assignedName, ignoreEmptyStringLiteral);
  return factory2.updateVariableDeclaration(
    node,
    node.name,
    node.exclamationToken,
    node.type,
    initializer
  );
}
function transformNamedEvaluationOfParameterDeclaration(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const assignedName = assignedNameText !== void 0 ? factory2.createStringLiteral(assignedNameText) : getAssignedNameOfIdentifier(factory2, node.name, node.initializer);
  const initializer = finishTransformNamedEvaluation(context, node.initializer, assignedName, ignoreEmptyStringLiteral);
  return factory2.updateParameterDeclaration(
    node,
    node.modifiers,
    node.dotDotDotToken,
    node.name,
    node.questionToken,
    node.type,
    initializer
  );
}
function transformNamedEvaluationOfBindingElement(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const assignedName = assignedNameText !== void 0 ? factory2.createStringLiteral(assignedNameText) : getAssignedNameOfIdentifier(factory2, node.name, node.initializer);
  const initializer = finishTransformNamedEvaluation(context, node.initializer, assignedName, ignoreEmptyStringLiteral);
  return factory2.updateBindingElement(
    node,
    node.dotDotDotToken,
    node.propertyName,
    node.name,
    initializer
  );
}
function transformNamedEvaluationOfPropertyDeclaration(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const { assignedName, name } = getAssignedNameOfPropertyName(context, node.name, assignedNameText);
  const initializer = finishTransformNamedEvaluation(context, node.initializer, assignedName, ignoreEmptyStringLiteral);
  return factory2.updatePropertyDeclaration(
    node,
    node.modifiers,
    name,
    node.questionToken ?? node.exclamationToken,
    node.type,
    initializer
  );
}
function transformNamedEvaluationOfAssignmentExpression(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const assignedName = assignedNameText !== void 0 ? factory2.createStringLiteral(assignedNameText) : getAssignedNameOfIdentifier(factory2, node.left, node.right);
  const right = finishTransformNamedEvaluation(context, node.right, assignedName, ignoreEmptyStringLiteral);
  return factory2.updateBinaryExpression(
    node,
    node.left,
    node.operatorToken,
    right
  );
}
function transformNamedEvaluationOfExportAssignment(context, node, ignoreEmptyStringLiteral, assignedNameText) {
  const { factory: factory2 } = context;
  const assignedName = assignedNameText !== void 0 ? factory2.createStringLiteral(assignedNameText) : factory2.createStringLiteral(node.isExportEquals ? "" : "default");
  const expression = finishTransformNamedEvaluation(context, node.expression, assignedName, ignoreEmptyStringLiteral);
  return factory2.updateExportAssignment(
    node,
    node.modifiers,
    expression
  );
}
function transformNamedEvaluation(context, node, ignoreEmptyStringLiteral, assignedName) {
  switch (node.kind) {
    case 303 /* PropertyAssignment */:
      return transformNamedEvaluationOfPropertyAssignment(context, node, ignoreEmptyStringLiteral, assignedName);
    case 304 /* ShorthandPropertyAssignment */:
      return transformNamedEvaluationOfShorthandAssignmentProperty(context, node, ignoreEmptyStringLiteral, assignedName);
    case 260 /* VariableDeclaration */:
      return transformNamedEvaluationOfVariableDeclaration(context, node, ignoreEmptyStringLiteral, assignedName);
    case 169 /* Parameter */:
      return transformNamedEvaluationOfParameterDeclaration(context, node, ignoreEmptyStringLiteral, assignedName);
    case 208 /* BindingElement */:
      return transformNamedEvaluationOfBindingElement(context, node, ignoreEmptyStringLiteral, assignedName);
    case 172 /* PropertyDeclaration */:
      return transformNamedEvaluationOfPropertyDeclaration(context, node, ignoreEmptyStringLiteral, assignedName);
    case 226 /* BinaryExpression */:
      return transformNamedEvaluationOfAssignmentExpression(context, node, ignoreEmptyStringLiteral, assignedName);
    case 277 /* ExportAssignment */:
      return transformNamedEvaluationOfExportAssignment(context, node, ignoreEmptyStringLiteral, assignedName);
  }
}

// src/compiler/transformers/taggedTemplate.ts
function processTaggedTemplateExpression(context, node, visitor, currentSourceFile, recordTaggedTemplateString, level) {
  const tag = visitNode(node.tag, visitor, isExpression);
  Debug.assert(tag);
  const templateArguments = [void 0];
  const cookedStrings = [];
  const rawStrings = [];
  const template = node.template;
  if (level === 0 /* LiftRestriction */ && !hasInvalidEscape(template)) {
    return visitEachChild(node, visitor, context);
  }
  const { factory: factory2 } = context;
  if (isNoSubstitutionTemplateLiteral(template)) {
    cookedStrings.push(createTemplateCooked(factory2, template));
    rawStrings.push(getRawLiteral(factory2, template, currentSourceFile));
  } else {
    cookedStrings.push(createTemplateCooked(factory2, template.head));
    rawStrings.push(getRawLiteral(factory2, template.head, currentSourceFile));
    for (const templateSpan of template.templateSpans) {
      cookedStrings.push(createTemplateCooked(factory2, templateSpan.literal));
      rawStrings.push(getRawLiteral(factory2, templateSpan.literal, currentSourceFile));
      templateArguments.push(Debug.checkDefined(visitNode(templateSpan.expression, visitor, isExpression)));
    }
  }
  const helperCall = context.getEmitHelperFactory().createTemplateObjectHelper(
    factory2.createArrayLiteralExpression(cookedStrings),
    factory2.createArrayLiteralExpression(rawStrings)
  );
  if (isExternalModule(currentSourceFile)) {
    const tempVar = factory2.createUniqueName("templateObject");
    recordTaggedTemplateString(tempVar);
    templateArguments[0] = factory2.createLogicalOr(
      tempVar,
      factory2.createAssignment(
        tempVar,
        helperCall
      )
    );
  } else {
    templateArguments[0] = helperCall;
  }
  return factory2.createCallExpression(
    tag,
    /*typeArguments*/
    void 0,
    templateArguments
  );
}
function createTemplateCooked(factory2, template) {
  return template.templateFlags & 26656 /* IsInvalid */ ? factory2.createVoidZero() : factory2.createStringLiteral(template.text);
}
function getRawLiteral(factory2, node, currentSourceFile) {
  let text = node.rawText;
  if (text === void 0) {
    Debug.assertIsDefined(currentSourceFile, "Template literal node is missing 'rawText' and does not have a source file. Possibly bad transform.");
    text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
    const isLast = node.kind === 15 /* NoSubstitutionTemplateLiteral */ || node.kind === 18 /* TemplateTail */;
    text = text.substring(1, text.length - (isLast ? 1 : 2));
  }
  text = text.replace(/\r\n?/g, "\n");
  return setTextRange(factory2.createStringLiteral(text), node);
}

// src/compiler/transformers/ts.ts
var USE_NEW_TYPE_METADATA_FORMAT = false;
function transformTypeScript(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    startLexicalEnvironment,
    resumeLexicalEnvironment,
    endLexicalEnvironment,
    hoistVariableDeclaration
  } = context;
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const moduleKind = getEmitModuleKind(compilerOptions);
  const legacyDecorators = !!compilerOptions.experimentalDecorators;
  const typeSerializer = compilerOptions.emitDecoratorMetadata ? createRuntimeTypeSerializer(context) : void 0;
  const previousOnEmitNode = context.onEmitNode;
  const previousOnSubstituteNode = context.onSubstituteNode;
  context.onEmitNode = onEmitNode;
  context.onSubstituteNode = onSubstituteNode;
  context.enableSubstitution(211 /* PropertyAccessExpression */);
  context.enableSubstitution(212 /* ElementAccessExpression */);
  let currentSourceFile;
  let currentNamespace;
  let currentNamespaceContainerName;
  let currentLexicalScope;
  let currentScopeFirstDeclarationsOfName;
  let currentClassHasParameterProperties;
  let enabledSubstitutions;
  let applicableSubstitutions;
  return transformSourceFileOrBundle;
  function transformSourceFileOrBundle(node) {
    if (node.kind === 308 /* Bundle */) {
      return transformBundle(node);
    }
    return transformSourceFile(node);
  }
  function transformBundle(node) {
    return factory2.createBundle(
      node.sourceFiles.map(transformSourceFile)
    );
  }
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    currentSourceFile = node;
    const visited = saveStateAndInvoke(node, visitSourceFile);
    addEmitHelpers(visited, context.readEmitHelpers());
    currentSourceFile = void 0;
    return visited;
  }
  function saveStateAndInvoke(node, f) {
    const savedCurrentScope = currentLexicalScope;
    const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
    const savedCurrentClassHasParameterProperties = currentClassHasParameterProperties;
    onBeforeVisitNode(node);
    const visited = f(node);
    if (currentLexicalScope !== savedCurrentScope) {
      currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
    }
    currentLexicalScope = savedCurrentScope;
    currentClassHasParameterProperties = savedCurrentClassHasParameterProperties;
    return visited;
  }
  function onBeforeVisitNode(node) {
    switch (node.kind) {
      case 307 /* SourceFile */:
      case 269 /* CaseBlock */:
      case 268 /* ModuleBlock */:
      case 241 /* Block */:
        currentLexicalScope = node;
        currentScopeFirstDeclarationsOfName = void 0;
        break;
      case 263 /* ClassDeclaration */:
      case 262 /* FunctionDeclaration */:
        if (hasSyntacticModifier(node, 128 /* Ambient */)) {
          break;
        }
        if (node.name) {
          recordEmittedDeclarationInScope(node);
        } else {
          Debug.assert(node.kind === 263 /* ClassDeclaration */ || hasSyntacticModifier(node, 2048 /* Default */));
        }
        break;
    }
  }
  function visitor(node) {
    return saveStateAndInvoke(node, visitorWorker);
  }
  function visitorWorker(node) {
    if (node.transformFlags & 1 /* ContainsTypeScript */) {
      return visitTypeScript(node);
    }
    return node;
  }
  function sourceElementVisitor(node) {
    return saveStateAndInvoke(node, sourceElementVisitorWorker);
  }
  function sourceElementVisitorWorker(node) {
    switch (node.kind) {
      case 272 /* ImportDeclaration */:
      case 271 /* ImportEqualsDeclaration */:
      case 277 /* ExportAssignment */:
      case 278 /* ExportDeclaration */:
        return visitElidableStatement(node);
      default:
        return visitorWorker(node);
    }
  }
  function isElisionBlocked(node) {
    const parsed = getParseTreeNode(node);
    if (parsed === node || isExportAssignment(node)) {
      return false;
    }
    if (!parsed || parsed.kind !== node.kind) {
      return true;
    }
    switch (node.kind) {
      case 272 /* ImportDeclaration */:
        Debug.assertNode(parsed, isImportDeclaration);
        if (node.importClause !== parsed.importClause) {
          return true;
        }
        if (node.attributes !== parsed.attributes) {
          return true;
        }
        break;
      case 271 /* ImportEqualsDeclaration */:
        Debug.assertNode(parsed, isImportEqualsDeclaration);
        if (node.name !== parsed.name) {
          return true;
        }
        if (node.isTypeOnly !== parsed.isTypeOnly) {
          return true;
        }
        if (node.moduleReference !== parsed.moduleReference && (isEntityName(node.moduleReference) || isEntityName(parsed.moduleReference))) {
          return true;
        }
        break;
      case 278 /* ExportDeclaration */:
        Debug.assertNode(parsed, isExportDeclaration);
        if (node.exportClause !== parsed.exportClause) {
          return true;
        }
        if (node.attributes !== parsed.attributes) {
          return true;
        }
        break;
    }
    return false;
  }
  function visitElidableStatement(node) {
    if (isElisionBlocked(node)) {
      if (node.transformFlags & 1 /* ContainsTypeScript */) {
        return visitEachChild(node, visitor, context);
      }
      return node;
    }
    switch (node.kind) {
      case 272 /* ImportDeclaration */:
        return visitImportDeclaration(node);
      case 271 /* ImportEqualsDeclaration */:
        return visitImportEqualsDeclaration(node);
      case 277 /* ExportAssignment */:
        return visitExportAssignment(node);
      case 278 /* ExportDeclaration */:
        return visitExportDeclaration(node);
      default:
        Debug.fail("Unhandled ellided statement");
    }
  }
  function namespaceElementVisitor(node) {
    return saveStateAndInvoke(node, namespaceElementVisitorWorker);
  }
  function namespaceElementVisitorWorker(node) {
    if (node.kind === 278 /* ExportDeclaration */ || node.kind === 272 /* ImportDeclaration */ || node.kind === 273 /* ImportClause */ || node.kind === 271 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 283 /* ExternalModuleReference */) {
      return void 0;
    } else if (node.transformFlags & 1 /* ContainsTypeScript */ || hasSyntacticModifier(node, 32 /* Export */)) {
      return visitTypeScript(node);
    }
    return node;
  }
  function getClassElementVisitor(parent) {
    return (node) => saveStateAndInvoke(node, (n) => classElementVisitorWorker(n, parent));
  }
  function classElementVisitorWorker(node, parent) {
    switch (node.kind) {
      case 176 /* Constructor */:
        return visitConstructor(node);
      case 172 /* PropertyDeclaration */:
        return visitPropertyDeclaration(node, parent);
      case 177 /* GetAccessor */:
        return visitGetAccessor(node, parent);
      case 178 /* SetAccessor */:
        return visitSetAccessor(node, parent);
      case 174 /* MethodDeclaration */:
        return visitMethodDeclaration(node, parent);
      case 175 /* ClassStaticBlockDeclaration */:
        return visitEachChild(node, visitor, context);
      case 240 /* SemicolonClassElement */:
        return node;
      case 181 /* IndexSignature */:
        return;
      default:
        return Debug.failBadSyntaxKind(node);
    }
  }
  function getObjectLiteralElementVisitor(parent) {
    return (node) => saveStateAndInvoke(node, (n) => objectLiteralElementVisitorWorker(n, parent));
  }
  function objectLiteralElementVisitorWorker(node, parent) {
    switch (node.kind) {
      case 303 /* PropertyAssignment */:
      case 304 /* ShorthandPropertyAssignment */:
      case 305 /* SpreadAssignment */:
        return visitor(node);
      case 177 /* GetAccessor */:
        return visitGetAccessor(node, parent);
      case 178 /* SetAccessor */:
        return visitSetAccessor(node, parent);
      case 174 /* MethodDeclaration */:
        return visitMethodDeclaration(node, parent);
      default:
        return Debug.failBadSyntaxKind(node);
    }
  }
  function decoratorElidingVisitor(node) {
    return isDecorator(node) ? void 0 : visitor(node);
  }
  function modifierElidingVisitor(node) {
    return isModifier(node) ? void 0 : visitor(node);
  }
  function modifierVisitor(node) {
    if (isDecorator(node)) return void 0;
    if (modifierToFlag(node.kind) & 28895 /* TypeScriptModifier */) {
      return void 0;
    } else if (currentNamespace && node.kind === 95 /* ExportKeyword */) {
      return void 0;
    }
    return node;
  }
  function visitTypeScript(node) {
    if (isStatement(node) && hasSyntacticModifier(node, 128 /* Ambient */)) {
      return factory2.createNotEmittedStatement(node);
    }
    switch (node.kind) {
      case 95 /* ExportKeyword */:
      case 90 /* DefaultKeyword */:
        return currentNamespace ? void 0 : node;
      case 125 /* PublicKeyword */:
      case 123 /* PrivateKeyword */:
      case 124 /* ProtectedKeyword */:
      case 128 /* AbstractKeyword */:
      case 164 /* OverrideKeyword */:
      case 87 /* ConstKeyword */:
      case 138 /* DeclareKeyword */:
      case 148 /* ReadonlyKeyword */:
      case 103 /* InKeyword */:
      case 147 /* OutKeyword */:
      case 188 /* ArrayType */:
      case 189 /* TupleType */:
      case 190 /* OptionalType */:
      case 191 /* RestType */:
      case 187 /* TypeLiteral */:
      case 182 /* TypePredicate */:
      case 168 /* TypeParameter */:
      case 133 /* AnyKeyword */:
      case 159 /* UnknownKeyword */:
      case 136 /* BooleanKeyword */:
      case 154 /* StringKeyword */:
      case 150 /* NumberKeyword */:
      case 146 /* NeverKeyword */:
      case 116 /* VoidKeyword */:
      case 155 /* SymbolKeyword */:
      case 185 /* ConstructorType */:
      case 184 /* FunctionType */:
      case 186 /* TypeQuery */:
      case 183 /* TypeReference */:
      case 192 /* UnionType */:
      case 193 /* IntersectionType */:
      case 194 /* ConditionalType */:
      case 196 /* ParenthesizedType */:
      case 197 /* ThisType */:
      case 198 /* TypeOperator */:
      case 199 /* IndexedAccessType */:
      case 200 /* MappedType */:
      case 201 /* LiteralType */:
      case 181 /* IndexSignature */:
        return void 0;
      case 265 /* TypeAliasDeclaration */:
        return factory2.createNotEmittedStatement(node);
      case 270 /* NamespaceExportDeclaration */:
        return void 0;
      case 264 /* InterfaceDeclaration */:
        return factory2.createNotEmittedStatement(node);
      case 263 /* ClassDeclaration */:
        return visitClassDeclaration(node);
      case 231 /* ClassExpression */:
        return visitClassExpression(node);
      case 298 /* HeritageClause */:
        return visitHeritageClause(node);
      case 233 /* ExpressionWithTypeArguments */:
        return visitExpressionWithTypeArguments(node);
      case 210 /* ObjectLiteralExpression */:
        return visitObjectLiteralExpression(node);
      case 176 /* Constructor */:
      case 172 /* PropertyDeclaration */:
      case 174 /* MethodDeclaration */:
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 175 /* ClassStaticBlockDeclaration */:
        return Debug.fail("Class and object literal elements must be visited with their respective visitors");
      case 262 /* FunctionDeclaration */:
        return visitFunctionDeclaration(node);
      case 218 /* FunctionExpression */:
        return visitFunctionExpression(node);
      case 219 /* ArrowFunction */:
        return visitArrowFunction(node);
      case 169 /* Parameter */:
        return visitParameter(node);
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(node);
      case 216 /* TypeAssertionExpression */:
      case 234 /* AsExpression */:
        return visitAssertionExpression(node);
      case 238 /* SatisfiesExpression */:
        return visitSatisfiesExpression(node);
      case 213 /* CallExpression */:
        return visitCallExpression(node);
      case 214 /* NewExpression */:
        return visitNewExpression(node);
      case 215 /* TaggedTemplateExpression */:
        return visitTaggedTemplateExpression(node);
      case 235 /* NonNullExpression */:
        return visitNonNullExpression(node);
      case 266 /* EnumDeclaration */:
        return visitEnumDeclaration(node);
      case 243 /* VariableStatement */:
        return visitVariableStatement(node);
      case 260 /* VariableDeclaration */:
        return visitVariableDeclaration(node);
      case 267 /* ModuleDeclaration */:
        return visitModuleDeclaration(node);
      case 271 /* ImportEqualsDeclaration */:
        return visitImportEqualsDeclaration(node);
      case 285 /* JsxSelfClosingElement */:
        return visitJsxSelfClosingElement(node);
      case 286 /* JsxOpeningElement */:
        return visitJsxJsxOpeningElement(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitSourceFile(node) {
    const alwaysStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") && !(isExternalModule(node) && moduleKind >= 5 /* ES2015 */) && !isJsonSourceFile(node);
    return factory2.updateSourceFile(
      node,
      visitLexicalEnvironment(
        node.statements,
        sourceElementVisitor,
        context,
        /*start*/
        0,
        alwaysStrict
      )
    );
  }
  function visitObjectLiteralExpression(node) {
    return factory2.updateObjectLiteralExpression(
      node,
      visitNodes2(node.properties, getObjectLiteralElementVisitor(node), isObjectLiteralElementLike)
    );
  }
  function getClassFacts(node) {
    let facts = 0 /* None */;
    if (some(getProperties(
      node,
      /*requireInitializer*/
      true,
      /*isStatic*/
      true
    ))) facts |= 1 /* HasStaticInitializedProperties */;
    const extendsClauseElement = getEffectiveBaseTypeNode(node);
    if (extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== 106 /* NullKeyword */) facts |= 64 /* IsDerivedClass */;
    if (classOrConstructorParameterIsDecorated(legacyDecorators, node)) facts |= 2 /* HasClassOrConstructorParameterDecorators */;
    if (childIsDecorated(legacyDecorators, node)) facts |= 4 /* HasMemberDecorators */;
    if (isExportOfNamespace(node)) facts |= 8 /* IsExportOfNamespace */;
    else if (isDefaultExternalModuleExport(node)) facts |= 32 /* IsDefaultExternalExport */;
    else if (isNamedExternalModuleExport(node)) facts |= 16 /* IsNamedExternalExport */;
    return facts;
  }
  function hasTypeScriptClassSyntax(node) {
    return !!(node.transformFlags & 8192 /* ContainsTypeScriptClassSyntax */);
  }
  function isClassLikeDeclarationWithTypeScriptSyntax(node) {
    return hasDecorators(node) || some(node.typeParameters) || some(node.heritageClauses, hasTypeScriptClassSyntax) || some(node.members, hasTypeScriptClassSyntax);
  }
  function visitClassDeclaration(node) {
    const facts = getClassFacts(node);
    const promoteToIIFE = languageVersion <= 1 /* ES5 */ && !!(facts & 7 /* MayNeedImmediatelyInvokedFunctionExpression */);
    if (!isClassLikeDeclarationWithTypeScriptSyntax(node) && !classOrConstructorParameterIsDecorated(legacyDecorators, node) && !isExportOfNamespace(node)) {
      return factory2.updateClassDeclaration(
        node,
        visitNodes2(node.modifiers, modifierVisitor, isModifier),
        node.name,
        /*typeParameters*/
        void 0,
        visitNodes2(node.heritageClauses, visitor, isHeritageClause),
        visitNodes2(node.members, getClassElementVisitor(node), isClassElement)
      );
    }
    if (promoteToIIFE) {
      context.startLexicalEnvironment();
    }
    const moveModifiers = promoteToIIFE || facts & 8 /* IsExportOfNamespace */;
    let modifiers = moveModifiers ? visitNodes2(node.modifiers, modifierElidingVisitor, isModifierLike) : visitNodes2(node.modifiers, visitor, isModifierLike);
    if (facts & 2 /* HasClassOrConstructorParameterDecorators */) {
      modifiers = injectClassTypeMetadata(modifiers, node);
    }
    const needsName = moveModifiers && !node.name || facts & 4 /* HasMemberDecorators */ || facts & 1 /* HasStaticInitializedProperties */;
    const name = needsName ? node.name ?? factory2.getGeneratedNameForNode(node) : node.name;
    const classDeclaration = factory2.updateClassDeclaration(
      node,
      modifiers,
      name,
      /*typeParameters*/
      void 0,
      visitNodes2(node.heritageClauses, visitor, isHeritageClause),
      transformClassMembers(node)
    );
    let emitFlags = getEmitFlags(node);
    if (facts & 1 /* HasStaticInitializedProperties */) {
      emitFlags |= 64 /* NoTrailingSourceMap */;
    }
    setEmitFlags(classDeclaration, emitFlags);
    let statement;
    if (promoteToIIFE) {
      const statements = [classDeclaration];
      const closingBraceLocation = createTokenRange(skipTrivia(currentSourceFile.text, node.members.end), 20 /* CloseBraceToken */);
      const localName = factory2.getInternalName(node);
      const outer = factory2.createPartiallyEmittedExpression(localName);
      setTextRangeEnd(outer, closingBraceLocation.end);
      setEmitFlags(outer, 3072 /* NoComments */);
      const returnStatement = factory2.createReturnStatement(outer);
      setTextRangePos(returnStatement, closingBraceLocation.pos);
      setEmitFlags(returnStatement, 3072 /* NoComments */ | 768 /* NoTokenSourceMaps */);
      statements.push(returnStatement);
      insertStatementsAfterStandardPrologue(statements, context.endLexicalEnvironment());
      const iife = factory2.createImmediatelyInvokedArrowFunction(statements);
      setInternalEmitFlags(iife, 1 /* TypeScriptClassWrapper */);
      const varDecl = factory2.createVariableDeclaration(
        factory2.getLocalName(
          node,
          /*allowComments*/
          false,
          /*allowSourceMaps*/
          false
        ),
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        iife
      );
      setOriginalNode(varDecl, node);
      const varStatement = factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList([varDecl], 1 /* Let */)
      );
      setOriginalNode(varStatement, node);
      setCommentRange(varStatement, node);
      setSourceMapRange(varStatement, moveRangePastDecorators(node));
      startOnNewLine(varStatement);
      statement = varStatement;
    } else {
      statement = classDeclaration;
    }
    if (moveModifiers) {
      if (facts & 8 /* IsExportOfNamespace */) {
        return [
          statement,
          createExportMemberAssignmentStatement(node)
        ];
      }
      if (facts & 32 /* IsDefaultExternalExport */) {
        return [
          statement,
          factory2.createExportDefault(factory2.getLocalName(
            node,
            /*allowComments*/
            false,
            /*allowSourceMaps*/
            true
          ))
        ];
      }
      if (facts & 16 /* IsNamedExternalExport */) {
        return [
          statement,
          factory2.createExternalModuleExport(factory2.getDeclarationName(
            node,
            /*allowComments*/
            false,
            /*allowSourceMaps*/
            true
          ))
        ];
      }
    }
    return statement;
  }
  function visitClassExpression(node) {
    let modifiers = visitNodes2(node.modifiers, modifierElidingVisitor, isModifierLike);
    if (classOrConstructorParameterIsDecorated(legacyDecorators, node)) {
      modifiers = injectClassTypeMetadata(modifiers, node);
    }
    return factory2.updateClassExpression(
      node,
      modifiers,
      node.name,
      /*typeParameters*/
      void 0,
      visitNodes2(node.heritageClauses, visitor, isHeritageClause),
      transformClassMembers(node)
    );
  }
  function transformClassMembers(node) {
    const members = visitNodes2(node.members, getClassElementVisitor(node), isClassElement);
    let newMembers;
    const constructor = getFirstConstructorWithBody(node);
    const parametersWithPropertyAssignments = constructor && filter(constructor.parameters, (p) => isParameterPropertyDeclaration(p, constructor));
    if (parametersWithPropertyAssignments) {
      for (const parameter of parametersWithPropertyAssignments) {
        const parameterProperty = factory2.createPropertyDeclaration(
          /*modifiers*/
          void 0,
          parameter.name,
          /*questionOrExclamationToken*/
          void 0,
          /*type*/
          void 0,
          /*initializer*/
          void 0
        );
        setOriginalNode(parameterProperty, parameter);
        newMembers = append(newMembers, parameterProperty);
      }
    }
    if (newMembers) {
      newMembers = addRange(newMembers, members);
      return setTextRange(
        factory2.createNodeArray(newMembers),
        /*location*/
        node.members
      );
    }
    return members;
  }
  function injectClassTypeMetadata(modifiers, node) {
    const metadata = getTypeMetadata(node, node);
    if (some(metadata)) {
      const modifiersArray = [];
      addRange(modifiersArray, takeWhile(modifiers, isExportOrDefaultModifier));
      addRange(modifiersArray, filter(modifiers, isDecorator));
      addRange(modifiersArray, metadata);
      addRange(modifiersArray, filter(skipWhile(modifiers, isExportOrDefaultModifier), isModifier));
      modifiers = setTextRange(factory2.createNodeArray(modifiersArray), modifiers);
    }
    return modifiers;
  }
  function injectClassElementTypeMetadata(modifiers, node, container) {
    if (isClassLike(container) && classElementOrClassElementParameterIsDecorated(legacyDecorators, node, container)) {
      const metadata = getTypeMetadata(node, container);
      if (some(metadata)) {
        const modifiersArray = [];
        addRange(modifiersArray, filter(modifiers, isDecorator));
        addRange(modifiersArray, metadata);
        addRange(modifiersArray, filter(modifiers, isModifier));
        modifiers = setTextRange(factory2.createNodeArray(modifiersArray), modifiers);
      }
    }
    return modifiers;
  }
  function getTypeMetadata(node, container) {
    if (!legacyDecorators) return void 0;
    return USE_NEW_TYPE_METADATA_FORMAT ? getNewTypeMetadata(node, container) : getOldTypeMetadata(node, container);
  }
  function getOldTypeMetadata(node, container) {
    if (typeSerializer) {
      let decorators;
      if (shouldAddTypeMetadata(node)) {
        const typeMetadata = emitHelpers().createMetadataHelper("design:type", typeSerializer.serializeTypeOfNode({ currentLexicalScope, currentNameScope: container }, node, container));
        decorators = append(decorators, factory2.createDecorator(typeMetadata));
      }
      if (shouldAddParamTypesMetadata(node)) {
        const paramTypesMetadata = emitHelpers().createMetadataHelper("design:paramtypes", typeSerializer.serializeParameterTypesOfNode({ currentLexicalScope, currentNameScope: container }, node, container));
        decorators = append(decorators, factory2.createDecorator(paramTypesMetadata));
      }
      if (shouldAddReturnTypeMetadata(node)) {
        const returnTypeMetadata = emitHelpers().createMetadataHelper("design:returntype", typeSerializer.serializeReturnTypeOfNode({ currentLexicalScope, currentNameScope: container }, node));
        decorators = append(decorators, factory2.createDecorator(returnTypeMetadata));
      }
      return decorators;
    }
  }
  function getNewTypeMetadata(node, container) {
    if (typeSerializer) {
      let properties;
      if (shouldAddTypeMetadata(node)) {
        const typeProperty = factory2.createPropertyAssignment("type", factory2.createArrowFunction(
          /*modifiers*/
          void 0,
          /*typeParameters*/
          void 0,
          [],
          /*type*/
          void 0,
          factory2.createToken(39 /* EqualsGreaterThanToken */),
          typeSerializer.serializeTypeOfNode({ currentLexicalScope, currentNameScope: container }, node, container)
        ));
        properties = append(properties, typeProperty);
      }
      if (shouldAddParamTypesMetadata(node)) {
        const paramTypeProperty = factory2.createPropertyAssignment("paramTypes", factory2.createArrowFunction(
          /*modifiers*/
          void 0,
          /*typeParameters*/
          void 0,
          [],
          /*type*/
          void 0,
          factory2.createToken(39 /* EqualsGreaterThanToken */),
          typeSerializer.serializeParameterTypesOfNode({ currentLexicalScope, currentNameScope: container }, node, container)
        ));
        properties = append(properties, paramTypeProperty);
      }
      if (shouldAddReturnTypeMetadata(node)) {
        const returnTypeProperty = factory2.createPropertyAssignment("returnType", factory2.createArrowFunction(
          /*modifiers*/
          void 0,
          /*typeParameters*/
          void 0,
          [],
          /*type*/
          void 0,
          factory2.createToken(39 /* EqualsGreaterThanToken */),
          typeSerializer.serializeReturnTypeOfNode({ currentLexicalScope, currentNameScope: container }, node)
        ));
        properties = append(properties, returnTypeProperty);
      }
      if (properties) {
        const typeInfoMetadata = emitHelpers().createMetadataHelper("design:typeinfo", factory2.createObjectLiteralExpression(
          properties,
          /*multiLine*/
          true
        ));
        return [factory2.createDecorator(typeInfoMetadata)];
      }
    }
  }
  function shouldAddTypeMetadata(node) {
    const kind = node.kind;
    return kind === 174 /* MethodDeclaration */ || kind === 177 /* GetAccessor */ || kind === 178 /* SetAccessor */ || kind === 172 /* PropertyDeclaration */;
  }
  function shouldAddReturnTypeMetadata(node) {
    return node.kind === 174 /* MethodDeclaration */;
  }
  function shouldAddParamTypesMetadata(node) {
    switch (node.kind) {
      case 263 /* ClassDeclaration */:
      case 231 /* ClassExpression */:
        return getFirstConstructorWithBody(node) !== void 0;
      case 174 /* MethodDeclaration */:
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
        return true;
    }
    return false;
  }
  function getExpressionForPropertyName(member, generateNameForComputedPropertyName) {
    const name = member.name;
    if (isPrivateIdentifier(name)) {
      return factory2.createIdentifier("");
    } else if (isComputedPropertyName(name)) {
      return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression) ? factory2.getGeneratedNameForNode(name) : name.expression;
    } else if (isIdentifier(name)) {
      return factory2.createStringLiteral(idText(name));
    } else {
      return factory2.cloneNode(name);
    }
  }
  function visitPropertyNameOfClassElement(member) {
    const name = member.name;
    if (isComputedPropertyName(name) && (!hasStaticModifier(member) && currentClassHasParameterProperties || hasDecorators(member) && legacyDecorators)) {
      const expression = visitNode(name.expression, visitor, isExpression);
      Debug.assert(expression);
      const innerExpression = skipPartiallyEmittedExpressions(expression);
      if (!isSimpleInlineableExpression(innerExpression)) {
        const generatedName = factory2.getGeneratedNameForNode(name);
        hoistVariableDeclaration(generatedName);
        return factory2.updateComputedPropertyName(name, factory2.createAssignment(generatedName, expression));
      }
    }
    return Debug.checkDefined(visitNode(name, visitor, isPropertyName));
  }
  function visitHeritageClause(node) {
    if (node.token === 119 /* ImplementsKeyword */) {
      return void 0;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitExpressionWithTypeArguments(node) {
    return factory2.updateExpressionWithTypeArguments(
      node,
      Debug.checkDefined(visitNode(node.expression, visitor, isLeftHandSideExpression)),
      /*typeArguments*/
      void 0
    );
  }
  function shouldEmitFunctionLikeDeclaration(node) {
    return !nodeIsMissing(node.body);
  }
  function visitPropertyDeclaration(node, parent) {
    const isAmbient = node.flags & 33554432 /* Ambient */ || hasSyntacticModifier(node, 64 /* Abstract */);
    if (isAmbient && !(legacyDecorators && hasDecorators(node))) {
      return void 0;
    }
    let modifiers = isClassLike(parent) ? !isAmbient ? visitNodes2(node.modifiers, visitor, isModifierLike) : visitNodes2(node.modifiers, modifierElidingVisitor, isModifierLike) : visitNodes2(node.modifiers, decoratorElidingVisitor, isModifierLike);
    modifiers = injectClassElementTypeMetadata(modifiers, node, parent);
    if (isAmbient) {
      return factory2.updatePropertyDeclaration(
        node,
        concatenate(modifiers, factory2.createModifiersFromModifierFlags(128 /* Ambient */)),
        Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
        /*questionOrExclamationToken*/
        void 0,
        /*type*/
        void 0,
        /*initializer*/
        void 0
      );
    }
    return factory2.updatePropertyDeclaration(
      node,
      modifiers,
      visitPropertyNameOfClassElement(node),
      /*questionOrExclamationToken*/
      void 0,
      /*type*/
      void 0,
      visitNode(node.initializer, visitor, isExpression)
    );
  }
  function visitConstructor(node) {
    if (!shouldEmitFunctionLikeDeclaration(node)) {
      return void 0;
    }
    return factory2.updateConstructorDeclaration(
      node,
      /*modifiers*/
      void 0,
      visitParameterList(node.parameters, visitor, context),
      transformConstructorBody(node.body, node)
    );
  }
  function transformConstructorBodyWorker(statementsOut, statementsIn, statementOffset, superPath, superPathDepth, initializerStatements) {
    const superStatementIndex = superPath[superPathDepth];
    const superStatement = statementsIn[superStatementIndex];
    addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, statementOffset, superStatementIndex - statementOffset));
    if (isTryStatement(superStatement)) {
      const tryBlockStatements = [];
      transformConstructorBodyWorker(
        tryBlockStatements,
        superStatement.tryBlock.statements,
        /*statementOffset*/
        0,
        superPath,
        superPathDepth + 1,
        initializerStatements
      );
      const tryBlockStatementsArray = factory2.createNodeArray(tryBlockStatements);
      setTextRange(tryBlockStatementsArray, superStatement.tryBlock.statements);
      statementsOut.push(factory2.updateTryStatement(
        superStatement,
        factory2.updateBlock(superStatement.tryBlock, tryBlockStatements),
        visitNode(superStatement.catchClause, visitor, isCatchClause),
        visitNode(superStatement.finallyBlock, visitor, isBlock)
      ));
    } else {
      addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, superStatementIndex, 1));
      addRange(statementsOut, initializerStatements);
    }
    addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, superStatementIndex + 1));
  }
  function transformConstructorBody(body, constructor) {
    const parametersWithPropertyAssignments = constructor && filter(constructor.parameters, (p) => isParameterPropertyDeclaration(p, constructor));
    if (!some(parametersWithPropertyAssignments)) {
      return visitFunctionBody(body, visitor, context);
    }
    let statements = [];
    resumeLexicalEnvironment();
    const prologueStatementCount = factory2.copyPrologue(
      body.statements,
      statements,
      /*ensureUseStrict*/
      false,
      visitor
    );
    const superPath = findSuperStatementIndexPath(body.statements, prologueStatementCount);
    const parameterPropertyAssignments = mapDefined(parametersWithPropertyAssignments, transformParameterWithPropertyAssignment);
    if (superPath.length) {
      transformConstructorBodyWorker(
        statements,
        body.statements,
        prologueStatementCount,
        superPath,
        /*superPathDepth*/
        0,
        parameterPropertyAssignments
      );
    } else {
      addRange(statements, parameterPropertyAssignments);
      addRange(statements, visitNodes2(body.statements, visitor, isStatement, prologueStatementCount));
    }
    statements = factory2.mergeLexicalEnvironment(statements, endLexicalEnvironment());
    const block = factory2.createBlock(
      setTextRange(factory2.createNodeArray(statements), body.statements),
      /*multiLine*/
      true
    );
    setTextRange(
      block,
      /*location*/
      body
    );
    setOriginalNode(block, body);
    return block;
  }
  function transformParameterWithPropertyAssignment(node) {
    const name = node.name;
    if (!isIdentifier(name)) {
      return void 0;
    }
    const propertyName = setParent(setTextRange(factory2.cloneNode(name), name), name.parent);
    setEmitFlags(propertyName, 3072 /* NoComments */ | 96 /* NoSourceMap */);
    const localName = setParent(setTextRange(factory2.cloneNode(name), name), name.parent);
    setEmitFlags(localName, 3072 /* NoComments */);
    return startOnNewLine(
      removeAllComments(
        setTextRange(
          setOriginalNode(
            factory2.createExpressionStatement(
              factory2.createAssignment(
                setTextRange(
                  factory2.createPropertyAccessExpression(
                    factory2.createThis(),
                    propertyName
                  ),
                  node.name
                ),
                localName
              )
            ),
            node
          ),
          moveRangePos(node, -1)
        )
      )
    );
  }
  function visitMethodDeclaration(node, parent) {
    if (!(node.transformFlags & 1 /* ContainsTypeScript */)) {
      return node;
    }
    if (!shouldEmitFunctionLikeDeclaration(node)) {
      return void 0;
    }
    let modifiers = isClassLike(parent) ? visitNodes2(node.modifiers, visitor, isModifierLike) : visitNodes2(node.modifiers, decoratorElidingVisitor, isModifierLike);
    modifiers = injectClassElementTypeMetadata(modifiers, node, parent);
    return factory2.updateMethodDeclaration(
      node,
      modifiers,
      node.asteriskToken,
      visitPropertyNameOfClassElement(node),
      /*questionToken*/
      void 0,
      /*typeParameters*/
      void 0,
      visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      visitFunctionBody(node.body, visitor, context)
    );
  }
  function shouldEmitAccessorDeclaration(node) {
    return !(nodeIsMissing(node.body) && hasSyntacticModifier(node, 64 /* Abstract */));
  }
  function visitGetAccessor(node, parent) {
    if (!(node.transformFlags & 1 /* ContainsTypeScript */)) {
      return node;
    }
    if (!shouldEmitAccessorDeclaration(node)) {
      return void 0;
    }
    let modifiers = isClassLike(parent) ? visitNodes2(node.modifiers, visitor, isModifierLike) : visitNodes2(node.modifiers, decoratorElidingVisitor, isModifierLike);
    modifiers = injectClassElementTypeMetadata(modifiers, node, parent);
    return factory2.updateGetAccessorDeclaration(
      node,
      modifiers,
      visitPropertyNameOfClassElement(node),
      visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      visitFunctionBody(node.body, visitor, context) || factory2.createBlock([])
    );
  }
  function visitSetAccessor(node, parent) {
    if (!(node.transformFlags & 1 /* ContainsTypeScript */)) {
      return node;
    }
    if (!shouldEmitAccessorDeclaration(node)) {
      return void 0;
    }
    let modifiers = isClassLike(parent) ? visitNodes2(node.modifiers, visitor, isModifierLike) : visitNodes2(node.modifiers, decoratorElidingVisitor, isModifierLike);
    modifiers = injectClassElementTypeMetadata(modifiers, node, parent);
    return factory2.updateSetAccessorDeclaration(
      node,
      modifiers,
      visitPropertyNameOfClassElement(node),
      visitParameterList(node.parameters, visitor, context),
      visitFunctionBody(node.body, visitor, context) || factory2.createBlock([])
    );
  }
  function visitFunctionDeclaration(node) {
    if (!shouldEmitFunctionLikeDeclaration(node)) {
      return factory2.createNotEmittedStatement(node);
    }
    const updated = factory2.updateFunctionDeclaration(
      node,
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      node.asteriskToken,
      node.name,
      /*typeParameters*/
      void 0,
      visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      visitFunctionBody(node.body, visitor, context) || factory2.createBlock([])
    );
    if (isExportOfNamespace(node)) {
      const statements = [updated];
      addExportMemberAssignment(statements, node);
      return statements;
    }
    return updated;
  }
  function visitFunctionExpression(node) {
    if (!shouldEmitFunctionLikeDeclaration(node)) {
      return factory2.createOmittedExpression();
    }
    const updated = factory2.updateFunctionExpression(
      node,
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      node.asteriskToken,
      node.name,
      /*typeParameters*/
      void 0,
      visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      visitFunctionBody(node.body, visitor, context) || factory2.createBlock([])
    );
    return updated;
  }
  function visitArrowFunction(node) {
    const updated = factory2.updateArrowFunction(
      node,
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      /*typeParameters*/
      void 0,
      visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      node.equalsGreaterThanToken,
      visitFunctionBody(node.body, visitor, context)
    );
    return updated;
  }
  function visitParameter(node) {
    if (parameterIsThisKeyword(node)) {
      return void 0;
    }
    const updated = factory2.updateParameterDeclaration(
      node,
      visitNodes2(node.modifiers, (node2) => isDecorator(node2) ? visitor(node2) : void 0, isModifierLike),
      node.dotDotDotToken,
      Debug.checkDefined(visitNode(node.name, visitor, isBindingName)),
      /*questionToken*/
      void 0,
      /*type*/
      void 0,
      visitNode(node.initializer, visitor, isExpression)
    );
    if (updated !== node) {
      setCommentRange(updated, node);
      setTextRange(updated, moveRangePastModifiers(node));
      setSourceMapRange(updated, moveRangePastModifiers(node));
      setEmitFlags(updated.name, 64 /* NoTrailingSourceMap */);
    }
    return updated;
  }
  function visitVariableStatement(node) {
    if (isExportOfNamespace(node)) {
      const variables = getInitializedVariables(node.declarationList);
      if (variables.length === 0) {
        return void 0;
      }
      return setTextRange(
        factory2.createExpressionStatement(
          factory2.inlineExpressions(
            map(variables, transformInitializedVariable)
          )
        ),
        node
      );
    } else {
      return visitEachChild(node, visitor, context);
    }
  }
  function transformInitializedVariable(node) {
    const name = node.name;
    if (isBindingPattern(name)) {
      return flattenDestructuringAssignment(
        node,
        visitor,
        context,
        0 /* All */,
        /*needsValue*/
        false,
        createNamespaceExportExpression
      );
    } else {
      return setTextRange(
        factory2.createAssignment(
          getNamespaceMemberNameWithSourceMapsAndWithoutComments(name),
          Debug.checkDefined(visitNode(node.initializer, visitor, isExpression))
        ),
        /*location*/
        node
      );
    }
  }
  function visitVariableDeclaration(node) {
    const updated = factory2.updateVariableDeclaration(
      node,
      Debug.checkDefined(visitNode(node.name, visitor, isBindingName)),
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      visitNode(node.initializer, visitor, isExpression)
    );
    if (node.type) {
      setTypeNode(updated.name, node.type);
    }
    return updated;
  }
  function visitParenthesizedExpression(node) {
    const innerExpression = skipOuterExpressions(node.expression, ~6 /* Assertions */);
    if (isAssertionExpression(innerExpression) || isSatisfiesExpression(innerExpression)) {
      const expression = visitNode(node.expression, visitor, isExpression);
      Debug.assert(expression);
      return factory2.createPartiallyEmittedExpression(expression, node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitAssertionExpression(node) {
    const expression = visitNode(node.expression, visitor, isExpression);
    Debug.assert(expression);
    return factory2.createPartiallyEmittedExpression(expression, node);
  }
  function visitNonNullExpression(node) {
    const expression = visitNode(node.expression, visitor, isLeftHandSideExpression);
    Debug.assert(expression);
    return factory2.createPartiallyEmittedExpression(expression, node);
  }
  function visitSatisfiesExpression(node) {
    const expression = visitNode(node.expression, visitor, isExpression);
    Debug.assert(expression);
    return factory2.createPartiallyEmittedExpression(expression, node);
  }
  function visitCallExpression(node) {
    return factory2.updateCallExpression(
      node,
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
      /*typeArguments*/
      void 0,
      visitNodes2(node.arguments, visitor, isExpression)
    );
  }
  function visitNewExpression(node) {
    return factory2.updateNewExpression(
      node,
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
      /*typeArguments*/
      void 0,
      visitNodes2(node.arguments, visitor, isExpression)
    );
  }
  function visitTaggedTemplateExpression(node) {
    return factory2.updateTaggedTemplateExpression(
      node,
      Debug.checkDefined(visitNode(node.tag, visitor, isExpression)),
      /*typeArguments*/
      void 0,
      Debug.checkDefined(visitNode(node.template, visitor, isTemplateLiteral))
    );
  }
  function visitJsxSelfClosingElement(node) {
    return factory2.updateJsxSelfClosingElement(
      node,
      Debug.checkDefined(visitNode(node.tagName, visitor, isJsxTagNameExpression)),
      /*typeArguments*/
      void 0,
      Debug.checkDefined(visitNode(node.attributes, visitor, isJsxAttributes))
    );
  }
  function visitJsxJsxOpeningElement(node) {
    return factory2.updateJsxOpeningElement(
      node,
      Debug.checkDefined(visitNode(node.tagName, visitor, isJsxTagNameExpression)),
      /*typeArguments*/
      void 0,
      Debug.checkDefined(visitNode(node.attributes, visitor, isJsxAttributes))
    );
  }
  function shouldEmitEnumDeclaration(node) {
    return !isEnumConst(node) || shouldPreserveConstEnums(compilerOptions);
  }
  function visitEnumDeclaration(node) {
    if (!shouldEmitEnumDeclaration(node)) {
      return factory2.createNotEmittedStatement(node);
    }
    const statements = [];
    let emitFlags = 4 /* AdviseOnEmitNode */;
    const varAdded = addVarForEnumOrModuleDeclaration(statements, node);
    if (varAdded) {
      if (moduleKind !== 4 /* System */ || currentLexicalScope !== currentSourceFile) {
        emitFlags |= 1024 /* NoLeadingComments */;
      }
    }
    const parameterName = getNamespaceParameterName(node);
    const containerName = getNamespaceContainerName(node);
    const exportName = isExportOfNamespace(node) ? factory2.getExternalModuleOrNamespaceExportName(
      currentNamespaceContainerName,
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    ) : factory2.getDeclarationName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    );
    let moduleArg = factory2.createLogicalOr(
      exportName,
      factory2.createAssignment(
        exportName,
        factory2.createObjectLiteralExpression()
      )
    );
    if (isExportOfNamespace(node)) {
      const localName = factory2.getLocalName(
        node,
        /*allowComments*/
        false,
        /*allowSourceMaps*/
        true
      );
      moduleArg = factory2.createAssignment(localName, moduleArg);
    }
    const enumStatement = factory2.createExpressionStatement(
      factory2.createCallExpression(
        factory2.createFunctionExpression(
          /*modifiers*/
          void 0,
          /*asteriskToken*/
          void 0,
          /*name*/
          void 0,
          /*typeParameters*/
          void 0,
          [factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            /*dotDotDotToken*/
            void 0,
            parameterName
          )],
          /*type*/
          void 0,
          transformEnumBody(node, containerName)
        ),
        /*typeArguments*/
        void 0,
        [moduleArg]
      )
    );
    setOriginalNode(enumStatement, node);
    if (varAdded) {
      setSyntheticLeadingComments(enumStatement, void 0);
      setSyntheticTrailingComments(enumStatement, void 0);
    }
    setTextRange(enumStatement, node);
    addEmitFlags(enumStatement, emitFlags);
    statements.push(enumStatement);
    return statements;
  }
  function transformEnumBody(node, localName) {
    const savedCurrentNamespaceLocalName = currentNamespaceContainerName;
    currentNamespaceContainerName = localName;
    const statements = [];
    startLexicalEnvironment();
    const members = map(node.members, transformEnumMember);
    insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
    addRange(statements, members);
    currentNamespaceContainerName = savedCurrentNamespaceLocalName;
    return factory2.createBlock(
      setTextRange(
        factory2.createNodeArray(statements),
        /*location*/
        node.members
      ),
      /*multiLine*/
      true
    );
  }
  function transformEnumMember(member) {
    const name = getExpressionForPropertyName(
      member,
      /*generateNameForComputedPropertyName*/
      false
    );
    const evaluated = resolver.getEnumMemberValue(member);
    const valueExpression = transformEnumMemberDeclarationValue(member, evaluated == null ? void 0 : evaluated.value);
    const innerAssignment = factory2.createAssignment(
      factory2.createElementAccessExpression(
        currentNamespaceContainerName,
        name
      ),
      valueExpression
    );
    const outerAssignment = typeof (evaluated == null ? void 0 : evaluated.value) === "string" || (evaluated == null ? void 0 : evaluated.isSyntacticallyString) ? innerAssignment : factory2.createAssignment(
      factory2.createElementAccessExpression(
        currentNamespaceContainerName,
        innerAssignment
      ),
      name
    );
    return setTextRange(
      factory2.createExpressionStatement(
        setTextRange(
          outerAssignment,
          member
        )
      ),
      member
    );
  }
  function transformEnumMemberDeclarationValue(member, constantValue) {
    if (constantValue !== void 0) {
      return typeof constantValue === "string" ? factory2.createStringLiteral(constantValue) : constantValue < 0 ? factory2.createPrefixUnaryExpression(41 /* MinusToken */, factory2.createNumericLiteral(-constantValue)) : factory2.createNumericLiteral(constantValue);
    } else {
      enableSubstitutionForNonQualifiedEnumMembers();
      if (member.initializer) {
        return Debug.checkDefined(visitNode(member.initializer, visitor, isExpression));
      } else {
        return factory2.createVoidZero();
      }
    }
  }
  function shouldEmitModuleDeclaration(nodeIn) {
    const node = getParseTreeNode(nodeIn, isModuleDeclaration);
    if (!node) {
      return true;
    }
    return isInstantiatedModule(node, shouldPreserveConstEnums(compilerOptions));
  }
  function recordEmittedDeclarationInScope(node) {
    if (!currentScopeFirstDeclarationsOfName) {
      currentScopeFirstDeclarationsOfName = /* @__PURE__ */ new Map();
    }
    const name = declaredNameInScope(node);
    if (!currentScopeFirstDeclarationsOfName.has(name)) {
      currentScopeFirstDeclarationsOfName.set(name, node);
    }
  }
  function isFirstEmittedDeclarationInScope(node) {
    if (currentScopeFirstDeclarationsOfName) {
      const name = declaredNameInScope(node);
      return currentScopeFirstDeclarationsOfName.get(name) === node;
    }
    return true;
  }
  function declaredNameInScope(node) {
    Debug.assertNode(node.name, isIdentifier);
    return node.name.escapedText;
  }
  function addVarForEnumOrModuleDeclaration(statements, node) {
    const varDecl = factory2.createVariableDeclaration(factory2.getLocalName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    ));
    const varFlags = currentLexicalScope.kind === 307 /* SourceFile */ ? 0 /* None */ : 1 /* Let */;
    const statement = factory2.createVariableStatement(
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      factory2.createVariableDeclarationList([varDecl], varFlags)
    );
    setOriginalNode(varDecl, node);
    setSyntheticLeadingComments(varDecl, void 0);
    setSyntheticTrailingComments(varDecl, void 0);
    setOriginalNode(statement, node);
    recordEmittedDeclarationInScope(node);
    if (isFirstEmittedDeclarationInScope(node)) {
      if (node.kind === 266 /* EnumDeclaration */) {
        setSourceMapRange(statement.declarationList, node);
      } else {
        setSourceMapRange(statement, node);
      }
      setCommentRange(statement, node);
      addEmitFlags(statement, 2048 /* NoTrailingComments */);
      statements.push(statement);
      return true;
    }
    return false;
  }
  function visitModuleDeclaration(node) {
    if (!shouldEmitModuleDeclaration(node)) {
      return factory2.createNotEmittedStatement(node);
    }
    Debug.assertNode(node.name, isIdentifier, "A TypeScript namespace should have an Identifier name.");
    enableSubstitutionForNamespaceExports();
    const statements = [];
    let emitFlags = 4 /* AdviseOnEmitNode */;
    const varAdded = addVarForEnumOrModuleDeclaration(statements, node);
    if (varAdded) {
      if (moduleKind !== 4 /* System */ || currentLexicalScope !== currentSourceFile) {
        emitFlags |= 1024 /* NoLeadingComments */;
      }
    }
    const parameterName = getNamespaceParameterName(node);
    const containerName = getNamespaceContainerName(node);
    const exportName = isExportOfNamespace(node) ? factory2.getExternalModuleOrNamespaceExportName(
      currentNamespaceContainerName,
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    ) : factory2.getDeclarationName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    );
    let moduleArg = factory2.createLogicalOr(
      exportName,
      factory2.createAssignment(
        exportName,
        factory2.createObjectLiteralExpression()
      )
    );
    if (isExportOfNamespace(node)) {
      const localName = factory2.getLocalName(
        node,
        /*allowComments*/
        false,
        /*allowSourceMaps*/
        true
      );
      moduleArg = factory2.createAssignment(localName, moduleArg);
    }
    const moduleStatement = factory2.createExpressionStatement(
      factory2.createCallExpression(
        factory2.createFunctionExpression(
          /*modifiers*/
          void 0,
          /*asteriskToken*/
          void 0,
          /*name*/
          void 0,
          /*typeParameters*/
          void 0,
          [factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            /*dotDotDotToken*/
            void 0,
            parameterName
          )],
          /*type*/
          void 0,
          transformModuleBody(node, containerName)
        ),
        /*typeArguments*/
        void 0,
        [moduleArg]
      )
    );
    setOriginalNode(moduleStatement, node);
    if (varAdded) {
      setSyntheticLeadingComments(moduleStatement, void 0);
      setSyntheticTrailingComments(moduleStatement, void 0);
    }
    setTextRange(moduleStatement, node);
    addEmitFlags(moduleStatement, emitFlags);
    statements.push(moduleStatement);
    return statements;
  }
  function transformModuleBody(node, namespaceLocalName) {
    const savedCurrentNamespaceContainerName = currentNamespaceContainerName;
    const savedCurrentNamespace = currentNamespace;
    const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
    currentNamespaceContainerName = namespaceLocalName;
    currentNamespace = node;
    currentScopeFirstDeclarationsOfName = void 0;
    const statements = [];
    startLexicalEnvironment();
    let statementsLocation;
    let blockLocation;
    if (node.body) {
      if (node.body.kind === 268 /* ModuleBlock */) {
        saveStateAndInvoke(node.body, (body) => addRange(statements, visitNodes2(body.statements, namespaceElementVisitor, isStatement)));
        statementsLocation = node.body.statements;
        blockLocation = node.body;
      } else {
        const result = visitModuleDeclaration(node.body);
        if (result) {
          if (isArray(result)) {
            addRange(statements, result);
          } else {
            statements.push(result);
          }
        }
        const moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
        statementsLocation = moveRangePos(moduleBlock.statements, -1);
      }
    }
    insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
    currentNamespaceContainerName = savedCurrentNamespaceContainerName;
    currentNamespace = savedCurrentNamespace;
    currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
    const block = factory2.createBlock(
      setTextRange(
        factory2.createNodeArray(statements),
        /*location*/
        statementsLocation
      ),
      /*multiLine*/
      true
    );
    setTextRange(block, blockLocation);
    if (!node.body || node.body.kind !== 268 /* ModuleBlock */) {
      setEmitFlags(block, getEmitFlags(block) | 3072 /* NoComments */);
    }
    return block;
  }
  function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
    if (moduleDeclaration.body.kind === 267 /* ModuleDeclaration */) {
      const recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
      return recursiveInnerModule || moduleDeclaration.body;
    }
  }
  function visitImportDeclaration(node) {
    if (!node.importClause) {
      return node;
    }
    if (node.importClause.isTypeOnly) {
      return void 0;
    }
    const importClause = visitNode(node.importClause, visitImportClause, isImportClause);
    return importClause ? factory2.updateImportDeclaration(
      node,
      /*modifiers*/
      void 0,
      importClause,
      node.moduleSpecifier,
      node.attributes
    ) : void 0;
  }
  function visitImportClause(node) {
    Debug.assert(!node.isTypeOnly);
    const name = shouldEmitAliasDeclaration(node) ? node.name : void 0;
    const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings);
    return name || namedBindings ? factory2.updateImportClause(
      node,
      /*isTypeOnly*/
      false,
      name,
      namedBindings
    ) : void 0;
  }
  function visitNamedImportBindings(node) {
    if (node.kind === 274 /* NamespaceImport */) {
      return shouldEmitAliasDeclaration(node) ? node : void 0;
    } else {
      const allowEmpty = compilerOptions.verbatimModuleSyntax;
      const elements = visitNodes2(node.elements, visitImportSpecifier, isImportSpecifier);
      return allowEmpty || some(elements) ? factory2.updateNamedImports(node, elements) : void 0;
    }
  }
  function visitImportSpecifier(node) {
    return !node.isTypeOnly && shouldEmitAliasDeclaration(node) ? node : void 0;
  }
  function visitExportAssignment(node) {
    return compilerOptions.verbatimModuleSyntax || resolver.isValueAliasDeclaration(node) ? visitEachChild(node, visitor, context) : void 0;
  }
  function visitExportDeclaration(node) {
    if (node.isTypeOnly) {
      return void 0;
    }
    if (!node.exportClause || isNamespaceExport(node.exportClause)) {
      return node;
    }
    const allowEmpty = !!compilerOptions.verbatimModuleSyntax;
    const exportClause = visitNode(
      node.exportClause,
      (bindings) => visitNamedExportBindings(bindings, allowEmpty),
      isNamedExportBindings
    );
    return exportClause ? factory2.updateExportDeclaration(
      node,
      /*modifiers*/
      void 0,
      node.isTypeOnly,
      exportClause,
      node.moduleSpecifier,
      node.attributes
    ) : void 0;
  }
  function visitNamedExports(node, allowEmpty) {
    const elements = visitNodes2(node.elements, visitExportSpecifier, isExportSpecifier);
    return allowEmpty || some(elements) ? factory2.updateNamedExports(node, elements) : void 0;
  }
  function visitNamespaceExports(node) {
    return factory2.updateNamespaceExport(node, Debug.checkDefined(visitNode(node.name, visitor, isIdentifier)));
  }
  function visitNamedExportBindings(node, allowEmpty) {
    return isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node, allowEmpty);
  }
  function visitExportSpecifier(node) {
    return !node.isTypeOnly && (compilerOptions.verbatimModuleSyntax || resolver.isValueAliasDeclaration(node)) ? node : void 0;
  }
  function shouldEmitImportEqualsDeclaration(node) {
    return shouldEmitAliasDeclaration(node) || !isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node);
  }
  function visitImportEqualsDeclaration(node) {
    if (node.isTypeOnly) {
      return void 0;
    }
    if (isExternalModuleImportEqualsDeclaration(node)) {
      const isReferenced = shouldEmitAliasDeclaration(node);
      return isReferenced ? visitEachChild(node, visitor, context) : void 0;
    }
    if (!shouldEmitImportEqualsDeclaration(node)) {
      return void 0;
    }
    const moduleReference = createExpressionFromEntityName(factory2, node.moduleReference);
    setEmitFlags(moduleReference, 3072 /* NoComments */ | 4096 /* NoNestedComments */);
    if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) {
      return setOriginalNode(
        setTextRange(
          factory2.createVariableStatement(
            visitNodes2(node.modifiers, modifierVisitor, isModifier),
            factory2.createVariableDeclarationList([
              setOriginalNode(
                factory2.createVariableDeclaration(
                  node.name,
                  /*exclamationToken*/
                  void 0,
                  /*type*/
                  void 0,
                  moduleReference
                ),
                node
              )
            ])
          ),
          node
        ),
        node
      );
    } else {
      return setOriginalNode(
        createNamespaceExport(
          node.name,
          moduleReference,
          node
        ),
        node
      );
    }
  }
  function isExportOfNamespace(node) {
    return currentNamespace !== void 0 && hasSyntacticModifier(node, 32 /* Export */);
  }
  function isExternalModuleExport(node) {
    return currentNamespace === void 0 && hasSyntacticModifier(node, 32 /* Export */);
  }
  function isNamedExternalModuleExport(node) {
    return isExternalModuleExport(node) && !hasSyntacticModifier(node, 2048 /* Default */);
  }
  function isDefaultExternalModuleExport(node) {
    return isExternalModuleExport(node) && hasSyntacticModifier(node, 2048 /* Default */);
  }
  function createExportMemberAssignmentStatement(node) {
    const expression = factory2.createAssignment(
      factory2.getExternalModuleOrNamespaceExportName(
        currentNamespaceContainerName,
        node,
        /*allowComments*/
        false,
        /*allowSourceMaps*/
        true
      ),
      factory2.getLocalName(node)
    );
    setSourceMapRange(expression, createRange(node.name ? node.name.pos : node.pos, node.end));
    const statement = factory2.createExpressionStatement(expression);
    setSourceMapRange(statement, createRange(-1, node.end));
    return statement;
  }
  function addExportMemberAssignment(statements, node) {
    statements.push(createExportMemberAssignmentStatement(node));
  }
  function createNamespaceExport(exportName, exportValue, location) {
    return setTextRange(
      factory2.createExpressionStatement(
        factory2.createAssignment(
          factory2.getNamespaceMemberName(
            currentNamespaceContainerName,
            exportName,
            /*allowComments*/
            false,
            /*allowSourceMaps*/
            true
          ),
          exportValue
        )
      ),
      location
    );
  }
  function createNamespaceExportExpression(exportName, exportValue, location) {
    return setTextRange(factory2.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
  }
  function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name) {
    return factory2.getNamespaceMemberName(
      currentNamespaceContainerName,
      name,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    );
  }
  function getNamespaceParameterName(node) {
    const name = factory2.getGeneratedNameForNode(node);
    setSourceMapRange(name, node.name);
    return name;
  }
  function getNamespaceContainerName(node) {
    return factory2.getGeneratedNameForNode(node);
  }
  function enableSubstitutionForNonQualifiedEnumMembers() {
    if ((enabledSubstitutions & 8 /* NonQualifiedEnumMembers */) === 0) {
      enabledSubstitutions |= 8 /* NonQualifiedEnumMembers */;
      context.enableSubstitution(80 /* Identifier */);
    }
  }
  function enableSubstitutionForNamespaceExports() {
    if ((enabledSubstitutions & 2 /* NamespaceExports */) === 0) {
      enabledSubstitutions |= 2 /* NamespaceExports */;
      context.enableSubstitution(80 /* Identifier */);
      context.enableSubstitution(304 /* ShorthandPropertyAssignment */);
      context.enableEmitNotification(267 /* ModuleDeclaration */);
    }
  }
  function isTransformedModuleDeclaration(node) {
    return getOriginalNode(node).kind === 267 /* ModuleDeclaration */;
  }
  function isTransformedEnumDeclaration(node) {
    return getOriginalNode(node).kind === 266 /* EnumDeclaration */;
  }
  function onEmitNode(hint, node, emitCallback) {
    const savedApplicableSubstitutions = applicableSubstitutions;
    const savedCurrentSourceFile = currentSourceFile;
    if (isSourceFile(node)) {
      currentSourceFile = node;
    }
    if (enabledSubstitutions & 2 /* NamespaceExports */ && isTransformedModuleDeclaration(node)) {
      applicableSubstitutions |= 2 /* NamespaceExports */;
    }
    if (enabledSubstitutions & 8 /* NonQualifiedEnumMembers */ && isTransformedEnumDeclaration(node)) {
      applicableSubstitutions |= 8 /* NonQualifiedEnumMembers */;
    }
    previousOnEmitNode(hint, node, emitCallback);
    applicableSubstitutions = savedApplicableSubstitutions;
    currentSourceFile = savedCurrentSourceFile;
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (hint === 1 /* Expression */) {
      return substituteExpression(node);
    } else if (isShorthandPropertyAssignment(node)) {
      return substituteShorthandPropertyAssignment(node);
    }
    return node;
  }
  function substituteShorthandPropertyAssignment(node) {
    if (enabledSubstitutions & 2 /* NamespaceExports */) {
      const name = node.name;
      const exportedName = trySubstituteNamespaceExportedName(name);
      if (exportedName) {
        if (node.objectAssignmentInitializer) {
          const initializer = factory2.createAssignment(exportedName, node.objectAssignmentInitializer);
          return setTextRange(factory2.createPropertyAssignment(name, initializer), node);
        }
        return setTextRange(factory2.createPropertyAssignment(name, exportedName), node);
      }
    }
    return node;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 80 /* Identifier */:
        return substituteExpressionIdentifier(node);
      case 211 /* PropertyAccessExpression */:
        return substitutePropertyAccessExpression(node);
      case 212 /* ElementAccessExpression */:
        return substituteElementAccessExpression(node);
    }
    return node;
  }
  function substituteExpressionIdentifier(node) {
    return trySubstituteNamespaceExportedName(node) || node;
  }
  function trySubstituteNamespaceExportedName(node) {
    if (enabledSubstitutions & applicableSubstitutions && !isGeneratedIdentifier(node) && !isLocalName(node)) {
      const container = resolver.getReferencedExportContainer(
        node,
        /*prefixLocals*/
        false
      );
      if (container && container.kind !== 307 /* SourceFile */) {
        const substitute = applicableSubstitutions & 2 /* NamespaceExports */ && container.kind === 267 /* ModuleDeclaration */ || applicableSubstitutions & 8 /* NonQualifiedEnumMembers */ && container.kind === 266 /* EnumDeclaration */;
        if (substitute) {
          return setTextRange(
            factory2.createPropertyAccessExpression(factory2.getGeneratedNameForNode(container), node),
            /*location*/
            node
          );
        }
      }
    }
    return void 0;
  }
  function substitutePropertyAccessExpression(node) {
    return substituteConstantValue(node);
  }
  function substituteElementAccessExpression(node) {
    return substituteConstantValue(node);
  }
  function safeMultiLineComment(value) {
    return value.replace(/\*\//g, "*_/");
  }
  function substituteConstantValue(node) {
    const constantValue = tryGetConstEnumValue(node);
    if (constantValue !== void 0) {
      setConstantValue(node, constantValue);
      const substitute = typeof constantValue === "string" ? factory2.createStringLiteral(constantValue) : constantValue < 0 ? factory2.createPrefixUnaryExpression(41 /* MinusToken */, factory2.createNumericLiteral(-constantValue)) : factory2.createNumericLiteral(constantValue);
      if (!compilerOptions.removeComments) {
        const originalNode = getOriginalNode(node, isAccessExpression);
        addSyntheticTrailingComment(substitute, 3 /* MultiLineCommentTrivia */, ` ${safeMultiLineComment(getTextOfNode(originalNode))} `);
      }
      return substitute;
    }
    return node;
  }
  function tryGetConstEnumValue(node) {
    if (getIsolatedModules(compilerOptions)) {
      return void 0;
    }
    return isPropertyAccessExpression(node) || isElementAccessExpression(node) ? resolver.getConstantValue(node) : void 0;
  }
  function shouldEmitAliasDeclaration(node) {
    return compilerOptions.verbatimModuleSyntax || isInJSFile(node) || resolver.isReferencedAliasDeclaration(node);
  }
}

// src/compiler/transformers/classFields.ts
function transformClassFields(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    hoistVariableDeclaration,
    endLexicalEnvironment,
    startLexicalEnvironment,
    resumeLexicalEnvironment,
    addBlockScopedVariable
  } = context;
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const useDefineForClassFields = getUseDefineForClassFields(compilerOptions);
  const legacyDecorators = !!compilerOptions.experimentalDecorators;
  const shouldTransformInitializersUsingSet = !useDefineForClassFields;
  const shouldTransformInitializersUsingDefine = useDefineForClassFields && languageVersion < 9 /* ES2022 */;
  const shouldTransformInitializers = shouldTransformInitializersUsingSet || shouldTransformInitializersUsingDefine;
  const shouldTransformPrivateElementsOrClassStaticBlocks = languageVersion < 9 /* ES2022 */;
  const shouldTransformAutoAccessors = languageVersion < 99 /* ESNext */ ? -1 /* True */ : !useDefineForClassFields ? 3 /* Maybe */ : 0 /* False */;
  const shouldTransformThisInStaticInitializers = languageVersion < 9 /* ES2022 */;
  const shouldTransformSuperInStaticInitializers = shouldTransformThisInStaticInitializers && languageVersion >= 2 /* ES2015 */;
  const shouldTransformAnything = shouldTransformInitializers || shouldTransformPrivateElementsOrClassStaticBlocks || shouldTransformAutoAccessors === -1 /* True */;
  const previousOnSubstituteNode = context.onSubstituteNode;
  context.onSubstituteNode = onSubstituteNode;
  const previousOnEmitNode = context.onEmitNode;
  context.onEmitNode = onEmitNode;
  let shouldTransformPrivateStaticElementsInFile = false;
  let enabledSubstitutions;
  let classAliases;
  let pendingExpressions;
  let pendingStatements;
  let lexicalEnvironment;
  const lexicalEnvironmentMap = /* @__PURE__ */ new Map();
  const noSubstitution = /* @__PURE__ */ new Set();
  let currentClassContainer;
  let currentClassElement;
  let shouldSubstituteThisWithClassThis = false;
  let previousShouldSubstituteThisWithClassThis = false;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    lexicalEnvironment = void 0;
    shouldTransformPrivateStaticElementsInFile = !!(getInternalEmitFlags(node) & 32 /* TransformPrivateStaticElements */);
    if (!shouldTransformAnything && !shouldTransformPrivateStaticElementsInFile) {
      return node;
    }
    const visited = visitEachChild(node, visitor, context);
    addEmitHelpers(visited, context.readEmitHelpers());
    return visited;
  }
  function modifierVisitor(node) {
    switch (node.kind) {
      case 129 /* AccessorKeyword */:
        return shouldTransformAutoAccessorsInCurrentClass() ? void 0 : node;
      default:
        return tryCast(node, isModifier);
    }
  }
  function visitor(node) {
    if (!(node.transformFlags & 16777216 /* ContainsClassFields */) && !(node.transformFlags & 134234112 /* ContainsLexicalThisOrSuper */)) {
      return node;
    }
    switch (node.kind) {
      case 129 /* AccessorKeyword */:
        return Debug.fail("Use `modifierVisitor` instead.");
      case 263 /* ClassDeclaration */:
        return visitClassDeclaration(node);
      case 231 /* ClassExpression */:
        return visitClassExpression(node);
      case 175 /* ClassStaticBlockDeclaration */:
      case 172 /* PropertyDeclaration */:
        return Debug.fail("Use `classElementVisitor` instead.");
      case 303 /* PropertyAssignment */:
        return visitPropertyAssignment(node);
      case 243 /* VariableStatement */:
        return visitVariableStatement(node);
      case 260 /* VariableDeclaration */:
        return visitVariableDeclaration(node);
      case 169 /* Parameter */:
        return visitParameterDeclaration(node);
      case 208 /* BindingElement */:
        return visitBindingElement(node);
      case 277 /* ExportAssignment */:
        return visitExportAssignment(node);
      case 81 /* PrivateIdentifier */:
        return visitPrivateIdentifier(node);
      case 211 /* PropertyAccessExpression */:
        return visitPropertyAccessExpression(node);
      case 212 /* ElementAccessExpression */:
        return visitElementAccessExpression(node);
      case 224 /* PrefixUnaryExpression */:
      case 225 /* PostfixUnaryExpression */:
        return visitPreOrPostfixUnaryExpression(
          node,
          /*discarded*/
          false
        );
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(
          node,
          /*discarded*/
          false
        );
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(
          node,
          /*discarded*/
          false
        );
      case 213 /* CallExpression */:
        return visitCallExpression(node);
      case 244 /* ExpressionStatement */:
        return visitExpressionStatement(node);
      case 215 /* TaggedTemplateExpression */:
        return visitTaggedTemplateExpression(node);
      case 248 /* ForStatement */:
        return visitForStatement(node);
      case 110 /* ThisKeyword */:
        return visitThisExpression(node);
      case 262 /* FunctionDeclaration */:
      case 218 /* FunctionExpression */:
        return setCurrentClassElementAnd(
          /*classElement*/
          void 0,
          fallbackVisitor,
          node
        );
      case 176 /* Constructor */:
      case 174 /* MethodDeclaration */:
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */: {
        return setCurrentClassElementAnd(
          node,
          fallbackVisitor,
          node
        );
      }
      default:
        return fallbackVisitor(node);
    }
  }
  function fallbackVisitor(node) {
    return visitEachChild(node, visitor, context);
  }
  function discardedValueVisitor(node) {
    switch (node.kind) {
      case 224 /* PrefixUnaryExpression */:
      case 225 /* PostfixUnaryExpression */:
        return visitPreOrPostfixUnaryExpression(
          node,
          /*discarded*/
          true
        );
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(
          node,
          /*discarded*/
          true
        );
      case 355 /* CommaListExpression */:
        return visitCommaListExpression(
          node,
          /*discarded*/
          true
        );
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(
          node,
          /*discarded*/
          true
        );
      default:
        return visitor(node);
    }
  }
  function heritageClauseVisitor(node) {
    switch (node.kind) {
      case 298 /* HeritageClause */:
        return visitEachChild(node, heritageClauseVisitor, context);
      case 233 /* ExpressionWithTypeArguments */:
        return visitExpressionWithTypeArgumentsInHeritageClause(node);
      default:
        return visitor(node);
    }
  }
  function assignmentTargetVisitor(node) {
    switch (node.kind) {
      case 210 /* ObjectLiteralExpression */:
      case 209 /* ArrayLiteralExpression */:
        return visitAssignmentPattern(node);
      default:
        return visitor(node);
    }
  }
  function classElementVisitor(node) {
    switch (node.kind) {
      case 176 /* Constructor */:
        return setCurrentClassElementAnd(
          node,
          visitConstructorDeclaration,
          node
        );
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 174 /* MethodDeclaration */:
        return setCurrentClassElementAnd(
          node,
          visitMethodOrAccessorDeclaration,
          node
        );
      case 172 /* PropertyDeclaration */:
        return setCurrentClassElementAnd(
          node,
          visitPropertyDeclaration,
          node
        );
      case 175 /* ClassStaticBlockDeclaration */:
        return setCurrentClassElementAnd(
          node,
          visitClassStaticBlockDeclaration,
          node
        );
      case 167 /* ComputedPropertyName */:
        return visitComputedPropertyName(node);
      case 240 /* SemicolonClassElement */:
        return node;
      default:
        return isModifierLike(node) ? modifierVisitor(node) : visitor(node);
    }
  }
  function propertyNameVisitor(node) {
    switch (node.kind) {
      case 167 /* ComputedPropertyName */:
        return visitComputedPropertyName(node);
      default:
        return visitor(node);
    }
  }
  function accessorFieldResultVisitor(node) {
    switch (node.kind) {
      case 172 /* PropertyDeclaration */:
        return transformFieldInitializer(node);
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
        return classElementVisitor(node);
      default:
        Debug.assertMissingNode(node, "Expected node to either be a PropertyDeclaration, GetAccessorDeclaration, or SetAccessorDeclaration");
        break;
    }
  }
  function visitPrivateIdentifier(node) {
    if (!shouldTransformPrivateElementsOrClassStaticBlocks) {
      return node;
    }
    if (isStatement(node.parent)) {
      return node;
    }
    return setOriginalNode(factory2.createIdentifier(""), node);
  }
  function transformPrivateIdentifierInInExpression(node) {
    const info = accessPrivateIdentifier2(node.left);
    if (info) {
      const receiver = visitNode(node.right, visitor, isExpression);
      return setOriginalNode(
        emitHelpers().createClassPrivateFieldInHelper(info.brandCheckIdentifier, receiver),
        node
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitPropertyAssignment(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitVariableStatement(node) {
    const savedPendingStatements = pendingStatements;
    pendingStatements = [];
    const visitedNode = visitEachChild(node, visitor, context);
    const statement = some(pendingStatements) ? [visitedNode, ...pendingStatements] : visitedNode;
    pendingStatements = savedPendingStatements;
    return statement;
  }
  function visitVariableDeclaration(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitParameterDeclaration(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitBindingElement(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitExportAssignment(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(
        context,
        node,
        /*ignoreEmptyStringLiteral*/
        true,
        node.isExportEquals ? "" : "default"
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function injectPendingExpressions(expression) {
    if (some(pendingExpressions)) {
      if (isParenthesizedExpression(expression)) {
        pendingExpressions.push(expression.expression);
        expression = factory2.updateParenthesizedExpression(expression, factory2.inlineExpressions(pendingExpressions));
      } else {
        pendingExpressions.push(expression);
        expression = factory2.inlineExpressions(pendingExpressions);
      }
      pendingExpressions = void 0;
    }
    return expression;
  }
  function visitComputedPropertyName(node) {
    const expression = visitNode(node.expression, visitor, isExpression);
    return factory2.updateComputedPropertyName(node, injectPendingExpressions(expression));
  }
  function visitConstructorDeclaration(node) {
    if (currentClassContainer) {
      return transformConstructor(node, currentClassContainer);
    }
    return fallbackVisitor(node);
  }
  function shouldTransformClassElementToWeakMap(node) {
    if (shouldTransformPrivateElementsOrClassStaticBlocks) return true;
    if (hasStaticModifier(node) && getInternalEmitFlags(node) & 32 /* TransformPrivateStaticElements */) return true;
    return false;
  }
  function visitMethodOrAccessorDeclaration(node) {
    Debug.assert(!hasDecorators(node));
    if (!isPrivateIdentifierClassElementDeclaration(node) || !shouldTransformClassElementToWeakMap(node)) {
      return visitEachChild(node, classElementVisitor, context);
    }
    const info = accessPrivateIdentifier2(node.name);
    Debug.assert(info, "Undeclared private name for property declaration.");
    if (!info.isValid) {
      return node;
    }
    const functionName = getHoistedFunctionName(node);
    if (functionName) {
      getPendingExpressions().push(
        factory2.createAssignment(
          functionName,
          factory2.createFunctionExpression(
            filter(node.modifiers, (m) => isModifier(m) && !isStaticModifier(m) && !isAccessorModifier(m)),
            node.asteriskToken,
            functionName,
            /*typeParameters*/
            void 0,
            visitParameterList(node.parameters, visitor, context),
            /*type*/
            void 0,
            visitFunctionBody(node.body, visitor, context)
          )
        )
      );
    }
    return void 0;
  }
  function setCurrentClassElementAnd(classElement, visitor2, arg) {
    if (classElement !== currentClassElement) {
      const savedCurrentClassElement = currentClassElement;
      currentClassElement = classElement;
      const result = visitor2(arg);
      currentClassElement = savedCurrentClassElement;
      return result;
    }
    return visitor2(arg);
  }
  function getHoistedFunctionName(node) {
    Debug.assert(isPrivateIdentifier(node.name));
    const info = accessPrivateIdentifier2(node.name);
    Debug.assert(info, "Undeclared private name for property declaration.");
    if (info.kind === "m" /* Method */) {
      return info.methodName;
    }
    if (info.kind === "a" /* Accessor */) {
      if (isGetAccessor(node)) {
        return info.getterName;
      }
      if (isSetAccessor(node)) {
        return info.setterName;
      }
    }
  }
  function tryGetClassThis() {
    const lex = getClassLexicalEnvironment();
    return lex.classThis ?? lex.classConstructor ?? (currentClassContainer == null ? void 0 : currentClassContainer.name);
  }
  function transformAutoAccessor(node) {
    const commentRange = getCommentRange(node);
    const sourceMapRange = getSourceMapRange(node);
    const name = node.name;
    let getterName = name;
    let setterName = name;
    if (isComputedPropertyName(name) && !isSimpleInlineableExpression(name.expression)) {
      const cacheAssignment = findComputedPropertyNameCacheAssignment(name);
      if (cacheAssignment) {
        getterName = factory2.updateComputedPropertyName(name, visitNode(name.expression, visitor, isExpression));
        setterName = factory2.updateComputedPropertyName(name, cacheAssignment.left);
      } else {
        const temp = factory2.createTempVariable(hoistVariableDeclaration);
        setSourceMapRange(temp, name.expression);
        const expression = visitNode(name.expression, visitor, isExpression);
        const assignment = factory2.createAssignment(temp, expression);
        setSourceMapRange(assignment, name.expression);
        getterName = factory2.updateComputedPropertyName(name, assignment);
        setterName = factory2.updateComputedPropertyName(name, temp);
      }
    }
    const modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
    const backingField = createAccessorPropertyBackingField(factory2, node, modifiers, node.initializer);
    setOriginalNode(backingField, node);
    setEmitFlags(backingField, 3072 /* NoComments */);
    setSourceMapRange(backingField, sourceMapRange);
    const receiver = isStatic(node) ? tryGetClassThis() ?? factory2.createThis() : factory2.createThis();
    const getter = createAccessorPropertyGetRedirector(factory2, node, modifiers, getterName, receiver);
    setOriginalNode(getter, node);
    setCommentRange(getter, commentRange);
    setSourceMapRange(getter, sourceMapRange);
    const setterModifiers = factory2.createModifiersFromModifierFlags(modifiersToFlags(modifiers));
    const setter = createAccessorPropertySetRedirector(factory2, node, setterModifiers, setterName, receiver);
    setOriginalNode(setter, node);
    setEmitFlags(setter, 3072 /* NoComments */);
    setSourceMapRange(setter, sourceMapRange);
    return visitArray([backingField, getter, setter], accessorFieldResultVisitor, isClassElement);
  }
  function transformPrivateFieldInitializer(node) {
    if (shouldTransformClassElementToWeakMap(node)) {
      const info = accessPrivateIdentifier2(node.name);
      Debug.assert(info, "Undeclared private name for property declaration.");
      if (!info.isValid) {
        return node;
      }
      if (info.isStatic && !shouldTransformPrivateElementsOrClassStaticBlocks) {
        const statement = transformPropertyOrClassStaticBlock(node, factory2.createThis());
        if (statement) {
          return factory2.createClassStaticBlockDeclaration(factory2.createBlock(
            [statement],
            /*multiLine*/
            true
          ));
        }
      }
      return void 0;
    }
    if (shouldTransformInitializersUsingSet && !isStatic(node) && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) && lexicalEnvironment.data.facts & 16 /* WillHoistInitializersToConstructor */) {
      return factory2.updatePropertyDeclaration(
        node,
        visitNodes2(node.modifiers, visitor, isModifierLike),
        node.name,
        /*questionOrExclamationToken*/
        void 0,
        /*type*/
        void 0,
        /*initializer*/
        void 0
      );
    }
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node);
    }
    return factory2.updatePropertyDeclaration(
      node,
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      visitNode(node.name, propertyNameVisitor, isPropertyName),
      /*questionOrExclamationToken*/
      void 0,
      /*type*/
      void 0,
      visitNode(node.initializer, visitor, isExpression)
    );
  }
  function transformPublicFieldInitializer(node) {
    if (shouldTransformInitializers && !isAutoAccessorPropertyDeclaration(node)) {
      const expr = getPropertyNameExpressionIfNeeded(
        node.name,
        /*shouldHoist*/
        !!node.initializer || useDefineForClassFields
      );
      if (expr) {
        getPendingExpressions().push(...flattenCommaList(expr));
      }
      if (isStatic(node) && !shouldTransformPrivateElementsOrClassStaticBlocks) {
        const initializerStatement = transformPropertyOrClassStaticBlock(node, factory2.createThis());
        if (initializerStatement) {
          const staticBlock = factory2.createClassStaticBlockDeclaration(
            factory2.createBlock([initializerStatement])
          );
          setOriginalNode(staticBlock, node);
          setCommentRange(staticBlock, node);
          setCommentRange(initializerStatement, { pos: -1, end: -1 });
          setSyntheticLeadingComments(initializerStatement, void 0);
          setSyntheticTrailingComments(initializerStatement, void 0);
          return staticBlock;
        }
      }
      return void 0;
    }
    return factory2.updatePropertyDeclaration(
      node,
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      visitNode(node.name, propertyNameVisitor, isPropertyName),
      /*questionOrExclamationToken*/
      void 0,
      /*type*/
      void 0,
      visitNode(node.initializer, visitor, isExpression)
    );
  }
  function transformFieldInitializer(node) {
    Debug.assert(!hasDecorators(node), "Decorators should already have been transformed and elided.");
    return isPrivateIdentifierClassElementDeclaration(node) ? transformPrivateFieldInitializer(node) : transformPublicFieldInitializer(node);
  }
  function shouldTransformAutoAccessorsInCurrentClass() {
    return shouldTransformAutoAccessors === -1 /* True */ || shouldTransformAutoAccessors === 3 /* Maybe */ && !!(lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) && !!(lexicalEnvironment.data.facts & 16 /* WillHoistInitializersToConstructor */);
  }
  function visitPropertyDeclaration(node) {
    if (isAutoAccessorPropertyDeclaration(node) && (shouldTransformAutoAccessorsInCurrentClass() || hasStaticModifier(node) && getInternalEmitFlags(node) & 32 /* TransformPrivateStaticElements */)) {
      return transformAutoAccessor(node);
    }
    return transformFieldInitializer(node);
  }
  function shouldForceDynamicThis() {
    return !!currentClassElement && hasStaticModifier(currentClassElement) && isAccessor(currentClassElement) && isAutoAccessorPropertyDeclaration(getOriginalNode(currentClassElement));
  }
  function ensureDynamicThisIfNeeded(node) {
    if (shouldForceDynamicThis()) {
      const innerExpression = skipOuterExpressions(node);
      if (innerExpression.kind === 110 /* ThisKeyword */) {
        noSubstitution.add(innerExpression);
      }
    }
  }
  function createPrivateIdentifierAccess(info, receiver) {
    receiver = visitNode(receiver, visitor, isExpression);
    ensureDynamicThisIfNeeded(receiver);
    return createPrivateIdentifierAccessHelper(info, receiver);
  }
  function createPrivateIdentifierAccessHelper(info, receiver) {
    setCommentRange(receiver, moveRangePos(receiver, -1));
    switch (info.kind) {
      case "a" /* Accessor */:
        return emitHelpers().createClassPrivateFieldGetHelper(
          receiver,
          info.brandCheckIdentifier,
          info.kind,
          info.getterName
        );
      case "m" /* Method */:
        return emitHelpers().createClassPrivateFieldGetHelper(
          receiver,
          info.brandCheckIdentifier,
          info.kind,
          info.methodName
        );
      case "f" /* Field */:
        return emitHelpers().createClassPrivateFieldGetHelper(
          receiver,
          info.brandCheckIdentifier,
          info.kind,
          info.isStatic ? info.variableName : void 0
        );
      case "untransformed":
        return Debug.fail("Access helpers should not be created for untransformed private elements");
      default:
        Debug.assertNever(info, "Unknown private element type");
    }
  }
  function visitPropertyAccessExpression(node) {
    if (isPrivateIdentifier(node.name)) {
      const privateIdentifierInfo = accessPrivateIdentifier2(node.name);
      if (privateIdentifierInfo) {
        return setTextRange(
          setOriginalNode(
            createPrivateIdentifierAccess(privateIdentifierInfo, node.expression),
            node
          ),
          node
        );
      }
    }
    if (shouldTransformSuperInStaticInitializers && currentClassElement && isSuperProperty(node) && isIdentifier(node.name) && isStaticPropertyDeclarationOrClassStaticBlock(currentClassElement) && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data)) {
      const { classConstructor, superClassReference, facts } = lexicalEnvironment.data;
      if (facts & 1 /* ClassWasDecorated */) {
        return visitInvalidSuperProperty(node);
      }
      if (classConstructor && superClassReference) {
        const superProperty = factory2.createReflectGetCall(
          superClassReference,
          factory2.createStringLiteralFromNode(node.name),
          classConstructor
        );
        setOriginalNode(superProperty, node.expression);
        setTextRange(superProperty, node.expression);
        return superProperty;
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitElementAccessExpression(node) {
    if (shouldTransformSuperInStaticInitializers && currentClassElement && isSuperProperty(node) && isStaticPropertyDeclarationOrClassStaticBlock(currentClassElement) && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data)) {
      const { classConstructor, superClassReference, facts } = lexicalEnvironment.data;
      if (facts & 1 /* ClassWasDecorated */) {
        return visitInvalidSuperProperty(node);
      }
      if (classConstructor && superClassReference) {
        const superProperty = factory2.createReflectGetCall(
          superClassReference,
          visitNode(node.argumentExpression, visitor, isExpression),
          classConstructor
        );
        setOriginalNode(superProperty, node.expression);
        setTextRange(superProperty, node.expression);
        return superProperty;
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitPreOrPostfixUnaryExpression(node, discarded) {
    if (node.operator === 46 /* PlusPlusToken */ || node.operator === 47 /* MinusMinusToken */) {
      const operand = skipParentheses(node.operand);
      if (isPrivateIdentifierPropertyAccessExpression(operand)) {
        let info;
        if (info = accessPrivateIdentifier2(operand.name)) {
          const receiver = visitNode(operand.expression, visitor, isExpression);
          ensureDynamicThisIfNeeded(receiver);
          const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver);
          let expression = createPrivateIdentifierAccess(info, readExpression);
          const temp = isPrefixUnaryExpression(node) || discarded ? void 0 : factory2.createTempVariable(hoistVariableDeclaration);
          expression = expandPreOrPostfixIncrementOrDecrementExpression(factory2, node, expression, hoistVariableDeclaration, temp);
          expression = createPrivateIdentifierAssignment(
            info,
            initializeExpression || readExpression,
            expression,
            64 /* EqualsToken */
          );
          setOriginalNode(expression, node);
          setTextRange(expression, node);
          if (temp) {
            expression = factory2.createComma(expression, temp);
            setTextRange(expression, node);
          }
          return expression;
        }
      } else if (shouldTransformSuperInStaticInitializers && currentClassElement && isSuperProperty(operand) && isStaticPropertyDeclarationOrClassStaticBlock(currentClassElement) && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data)) {
        const { classConstructor, superClassReference, facts } = lexicalEnvironment.data;
        if (facts & 1 /* ClassWasDecorated */) {
          const expression = visitInvalidSuperProperty(operand);
          return isPrefixUnaryExpression(node) ? factory2.updatePrefixUnaryExpression(node, expression) : factory2.updatePostfixUnaryExpression(node, expression);
        }
        if (classConstructor && superClassReference) {
          let setterName;
          let getterName;
          if (isPropertyAccessExpression(operand)) {
            if (isIdentifier(operand.name)) {
              getterName = setterName = factory2.createStringLiteralFromNode(operand.name);
            }
          } else {
            if (isSimpleInlineableExpression(operand.argumentExpression)) {
              getterName = setterName = operand.argumentExpression;
            } else {
              getterName = factory2.createTempVariable(hoistVariableDeclaration);
              setterName = factory2.createAssignment(getterName, visitNode(operand.argumentExpression, visitor, isExpression));
            }
          }
          if (setterName && getterName) {
            let expression = factory2.createReflectGetCall(superClassReference, getterName, classConstructor);
            setTextRange(expression, operand);
            const temp = discarded ? void 0 : factory2.createTempVariable(hoistVariableDeclaration);
            expression = expandPreOrPostfixIncrementOrDecrementExpression(factory2, node, expression, hoistVariableDeclaration, temp);
            expression = factory2.createReflectSetCall(superClassReference, setterName, expression, classConstructor);
            setOriginalNode(expression, node);
            setTextRange(expression, node);
            if (temp) {
              expression = factory2.createComma(expression, temp);
              setTextRange(expression, node);
            }
            return expression;
          }
        }
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitForStatement(node) {
    return factory2.updateForStatement(
      node,
      visitNode(node.initializer, discardedValueVisitor, isForInitializer),
      visitNode(node.condition, visitor, isExpression),
      visitNode(node.incrementor, discardedValueVisitor, isExpression),
      visitIterationBody(node.statement, visitor, context)
    );
  }
  function visitExpressionStatement(node) {
    return factory2.updateExpressionStatement(
      node,
      visitNode(node.expression, discardedValueVisitor, isExpression)
    );
  }
  function createCopiableReceiverExpr(receiver) {
    const clone = nodeIsSynthesized(receiver) ? receiver : factory2.cloneNode(receiver);
    if (receiver.kind === 110 /* ThisKeyword */ && noSubstitution.has(receiver)) {
      noSubstitution.add(clone);
    }
    if (isSimpleInlineableExpression(receiver)) {
      return { readExpression: clone, initializeExpression: void 0 };
    }
    const readExpression = factory2.createTempVariable(hoistVariableDeclaration);
    const initializeExpression = factory2.createAssignment(readExpression, clone);
    return { readExpression, initializeExpression };
  }
  function visitCallExpression(node) {
    var _a;
    if (isPrivateIdentifierPropertyAccessExpression(node.expression) && accessPrivateIdentifier2(node.expression.name)) {
      const { thisArg, target } = factory2.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion);
      if (isCallChain(node)) {
        return factory2.updateCallChain(
          node,
          factory2.createPropertyAccessChain(visitNode(target, visitor, isExpression), node.questionDotToken, "call"),
          /*questionDotToken*/
          void 0,
          /*typeArguments*/
          void 0,
          [visitNode(thisArg, visitor, isExpression), ...visitNodes2(node.arguments, visitor, isExpression)]
        );
      }
      return factory2.updateCallExpression(
        node,
        factory2.createPropertyAccessExpression(visitNode(target, visitor, isExpression), "call"),
        /*typeArguments*/
        void 0,
        [visitNode(thisArg, visitor, isExpression), ...visitNodes2(node.arguments, visitor, isExpression)]
      );
    }
    if (shouldTransformSuperInStaticInitializers && currentClassElement && isSuperProperty(node.expression) && isStaticPropertyDeclarationOrClassStaticBlock(currentClassElement) && ((_a = lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) == null ? void 0 : _a.classConstructor)) {
      const invocation = factory2.createFunctionCallCall(
        visitNode(node.expression, visitor, isExpression),
        lexicalEnvironment.data.classConstructor,
        visitNodes2(node.arguments, visitor, isExpression)
      );
      setOriginalNode(invocation, node);
      setTextRange(invocation, node);
      return invocation;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitTaggedTemplateExpression(node) {
    var _a;
    if (isPrivateIdentifierPropertyAccessExpression(node.tag) && accessPrivateIdentifier2(node.tag.name)) {
      const { thisArg, target } = factory2.createCallBinding(node.tag, hoistVariableDeclaration, languageVersion);
      return factory2.updateTaggedTemplateExpression(
        node,
        factory2.createCallExpression(
          factory2.createPropertyAccessExpression(visitNode(target, visitor, isExpression), "bind"),
          /*typeArguments*/
          void 0,
          [visitNode(thisArg, visitor, isExpression)]
        ),
        /*typeArguments*/
        void 0,
        visitNode(node.template, visitor, isTemplateLiteral)
      );
    }
    if (shouldTransformSuperInStaticInitializers && currentClassElement && isSuperProperty(node.tag) && isStaticPropertyDeclarationOrClassStaticBlock(currentClassElement) && ((_a = lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) == null ? void 0 : _a.classConstructor)) {
      const invocation = factory2.createFunctionBindCall(
        visitNode(node.tag, visitor, isExpression),
        lexicalEnvironment.data.classConstructor,
        []
      );
      setOriginalNode(invocation, node);
      setTextRange(invocation, node);
      return factory2.updateTaggedTemplateExpression(
        node,
        invocation,
        /*typeArguments*/
        void 0,
        visitNode(node.template, visitor, isTemplateLiteral)
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function transformClassStaticBlockDeclaration(node) {
    if (lexicalEnvironment) {
      lexicalEnvironmentMap.set(getOriginalNode(node), lexicalEnvironment);
    }
    if (shouldTransformPrivateElementsOrClassStaticBlocks) {
      if (isClassThisAssignmentBlock(node)) {
        const result = visitNode(node.body.statements[0].expression, visitor, isExpression);
        if (isAssignmentExpression(
          result,
          /*excludeCompoundAssignment*/
          true
        ) && result.left === result.right) {
          return void 0;
        }
        return result;
      }
      if (isClassNamedEvaluationHelperBlock(node)) {
        return visitNode(node.body.statements[0].expression, visitor, isExpression);
      }
      startLexicalEnvironment();
      let statements = setCurrentClassElementAnd(
        node,
        (statements2) => visitNodes2(statements2, visitor, isStatement),
        node.body.statements
      );
      statements = factory2.mergeLexicalEnvironment(statements, endLexicalEnvironment());
      const iife = factory2.createImmediatelyInvokedArrowFunction(statements);
      setOriginalNode(skipParentheses(iife.expression), node);
      addEmitFlags(skipParentheses(iife.expression), 4 /* AdviseOnEmitNode */);
      setOriginalNode(iife, node);
      setTextRange(iife, node);
      return iife;
    }
  }
  function isAnonymousClassNeedingAssignedName(node) {
    if (isClassExpression(node) && !node.name) {
      const staticPropertiesOrClassStaticBlocks = getStaticPropertiesAndClassStaticBlock(node);
      if (some(staticPropertiesOrClassStaticBlocks, isClassNamedEvaluationHelperBlock)) {
        return false;
      }
      const hasTransformableStatics = (shouldTransformPrivateElementsOrClassStaticBlocks || !!(getInternalEmitFlags(node) && 32 /* TransformPrivateStaticElements */)) && some(staticPropertiesOrClassStaticBlocks, (node2) => isClassStaticBlockDeclaration(node2) || isPrivateIdentifierClassElementDeclaration(node2) || shouldTransformInitializers && isInitializedProperty(node2));
      return hasTransformableStatics;
    }
    return false;
  }
  function visitBinaryExpression(node, discarded) {
    if (isDestructuringAssignment(node)) {
      const savedPendingExpressions = pendingExpressions;
      pendingExpressions = void 0;
      node = factory2.updateBinaryExpression(
        node,
        visitNode(node.left, assignmentTargetVisitor, isExpression),
        node.operatorToken,
        visitNode(node.right, visitor, isExpression)
      );
      const expr = some(pendingExpressions) ? factory2.inlineExpressions(compact([...pendingExpressions, node])) : node;
      pendingExpressions = savedPendingExpressions;
      return expr;
    }
    if (isAssignmentExpression(node)) {
      if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
        node = transformNamedEvaluation(context, node);
        Debug.assertNode(node, isAssignmentExpression);
      }
      const left = skipOuterExpressions(node.left, 8 /* PartiallyEmittedExpressions */ | 1 /* Parentheses */);
      if (isPrivateIdentifierPropertyAccessExpression(left)) {
        const info = accessPrivateIdentifier2(left.name);
        if (info) {
          return setTextRange(
            setOriginalNode(
              createPrivateIdentifierAssignment(info, left.expression, node.right, node.operatorToken.kind),
              node
            ),
            node
          );
        }
      } else if (shouldTransformSuperInStaticInitializers && currentClassElement && isSuperProperty(node.left) && isStaticPropertyDeclarationOrClassStaticBlock(currentClassElement) && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data)) {
        const { classConstructor, superClassReference, facts } = lexicalEnvironment.data;
        if (facts & 1 /* ClassWasDecorated */) {
          return factory2.updateBinaryExpression(
            node,
            visitInvalidSuperProperty(node.left),
            node.operatorToken,
            visitNode(node.right, visitor, isExpression)
          );
        }
        if (classConstructor && superClassReference) {
          let setterName = isElementAccessExpression(node.left) ? visitNode(node.left.argumentExpression, visitor, isExpression) : isIdentifier(node.left.name) ? factory2.createStringLiteralFromNode(node.left.name) : void 0;
          if (setterName) {
            let expression = visitNode(node.right, visitor, isExpression);
            if (isCompoundAssignment(node.operatorToken.kind)) {
              let getterName = setterName;
              if (!isSimpleInlineableExpression(setterName)) {
                getterName = factory2.createTempVariable(hoistVariableDeclaration);
                setterName = factory2.createAssignment(getterName, setterName);
              }
              const superPropertyGet = factory2.createReflectGetCall(
                superClassReference,
                getterName,
                classConstructor
              );
              setOriginalNode(superPropertyGet, node.left);
              setTextRange(superPropertyGet, node.left);
              expression = factory2.createBinaryExpression(
                superPropertyGet,
                getNonAssignmentOperatorForCompoundAssignment(node.operatorToken.kind),
                expression
              );
              setTextRange(expression, node);
            }
            const temp = discarded ? void 0 : factory2.createTempVariable(hoistVariableDeclaration);
            if (temp) {
              expression = factory2.createAssignment(temp, expression);
              setTextRange(temp, node);
            }
            expression = factory2.createReflectSetCall(
              superClassReference,
              setterName,
              expression,
              classConstructor
            );
            setOriginalNode(expression, node);
            setTextRange(expression, node);
            if (temp) {
              expression = factory2.createComma(expression, temp);
              setTextRange(expression, node);
            }
            return expression;
          }
        }
      }
    }
    if (isPrivateIdentifierInExpression(node)) {
      return transformPrivateIdentifierInInExpression(node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCommaListExpression(node, discarded) {
    const elements = discarded ? visitCommaListElements(node.elements, discardedValueVisitor) : visitCommaListElements(node.elements, visitor, discardedValueVisitor);
    return factory2.updateCommaListExpression(node, elements);
  }
  function visitParenthesizedExpression(node, discarded) {
    const visitorFunc = discarded ? discardedValueVisitor : visitor;
    const expression = visitNode(node.expression, visitorFunc, isExpression);
    return factory2.updateParenthesizedExpression(node, expression);
  }
  function createPrivateIdentifierAssignment(info, receiver, right, operator) {
    receiver = visitNode(receiver, visitor, isExpression);
    right = visitNode(right, visitor, isExpression);
    ensureDynamicThisIfNeeded(receiver);
    if (isCompoundAssignment(operator)) {
      const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver);
      receiver = initializeExpression || readExpression;
      right = factory2.createBinaryExpression(
        createPrivateIdentifierAccessHelper(info, readExpression),
        getNonAssignmentOperatorForCompoundAssignment(operator),
        right
      );
    }
    setCommentRange(receiver, moveRangePos(receiver, -1));
    switch (info.kind) {
      case "a" /* Accessor */:
        return emitHelpers().createClassPrivateFieldSetHelper(
          receiver,
          info.brandCheckIdentifier,
          right,
          info.kind,
          info.setterName
        );
      case "m" /* Method */:
        return emitHelpers().createClassPrivateFieldSetHelper(
          receiver,
          info.brandCheckIdentifier,
          right,
          info.kind,
          /*f*/
          void 0
        );
      case "f" /* Field */:
        return emitHelpers().createClassPrivateFieldSetHelper(
          receiver,
          info.brandCheckIdentifier,
          right,
          info.kind,
          info.isStatic ? info.variableName : void 0
        );
      case "untransformed":
        return Debug.fail("Access helpers should not be created for untransformed private elements");
      default:
        Debug.assertNever(info, "Unknown private element type");
    }
  }
  function getPrivateInstanceMethodsAndAccessors(node) {
    return filter(node.members, isNonStaticMethodOrAccessorWithPrivateName);
  }
  function getClassFacts(node) {
    var _a;
    let facts = 0 /* None */;
    const original = getOriginalNode(node);
    if (isClassLike(original) && classOrConstructorParameterIsDecorated(legacyDecorators, original)) {
      facts |= 1 /* ClassWasDecorated */;
    }
    if (shouldTransformPrivateElementsOrClassStaticBlocks && (classHasClassThisAssignment(node) || classHasExplicitlyAssignedName(node))) {
      facts |= 2 /* NeedsClassConstructorReference */;
    }
    let containsPublicInstanceFields = false;
    let containsInitializedPublicInstanceFields = false;
    let containsInstancePrivateElements = false;
    let containsInstanceAutoAccessors = false;
    for (const member of node.members) {
      if (isStatic(member)) {
        if (member.name && (isPrivateIdentifier(member.name) || isAutoAccessorPropertyDeclaration(member)) && shouldTransformPrivateElementsOrClassStaticBlocks) {
          facts |= 2 /* NeedsClassConstructorReference */;
        } else if (isAutoAccessorPropertyDeclaration(member) && shouldTransformAutoAccessors === -1 /* True */ && !node.name && !((_a = node.emitNode) == null ? void 0 : _a.classThis)) {
          facts |= 2 /* NeedsClassConstructorReference */;
        }
        if (isPropertyDeclaration(member) || isClassStaticBlockDeclaration(member)) {
          if (shouldTransformThisInStaticInitializers && member.transformFlags & 16384 /* ContainsLexicalThis */) {
            facts |= 8 /* NeedsSubstitutionForThisInClassStaticField */;
            if (!(facts & 1 /* ClassWasDecorated */)) {
              facts |= 2 /* NeedsClassConstructorReference */;
            }
          }
          if (shouldTransformSuperInStaticInitializers && member.transformFlags & 134217728 /* ContainsLexicalSuper */) {
            if (!(facts & 1 /* ClassWasDecorated */)) {
              facts |= 2 /* NeedsClassConstructorReference */ | 4 /* NeedsClassSuperReference */;
            }
          }
        }
      } else if (!hasAbstractModifier(getOriginalNode(member))) {
        if (isAutoAccessorPropertyDeclaration(member)) {
          containsInstanceAutoAccessors = true;
          containsInstancePrivateElements || (containsInstancePrivateElements = isPrivateIdentifierClassElementDeclaration(member));
        } else if (isPrivateIdentifierClassElementDeclaration(member)) {
          containsInstancePrivateElements = true;
          if (resolver.hasNodeCheckFlag(member, 262144 /* ContainsConstructorReference */)) {
            facts |= 2 /* NeedsClassConstructorReference */;
          }
        } else if (isPropertyDeclaration(member)) {
          containsPublicInstanceFields = true;
          containsInitializedPublicInstanceFields || (containsInitializedPublicInstanceFields = !!member.initializer);
        }
      }
    }
    const willHoistInitializersToConstructor = shouldTransformInitializersUsingDefine && containsPublicInstanceFields || shouldTransformInitializersUsingSet && containsInitializedPublicInstanceFields || shouldTransformPrivateElementsOrClassStaticBlocks && containsInstancePrivateElements || shouldTransformPrivateElementsOrClassStaticBlocks && containsInstanceAutoAccessors && shouldTransformAutoAccessors === -1 /* True */;
    if (willHoistInitializersToConstructor) {
      facts |= 16 /* WillHoistInitializersToConstructor */;
    }
    return facts;
  }
  function visitExpressionWithTypeArgumentsInHeritageClause(node) {
    var _a;
    const facts = ((_a = lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) == null ? void 0 : _a.facts) || 0 /* None */;
    if (facts & 4 /* NeedsClassSuperReference */) {
      const temp = factory2.createTempVariable(
        hoistVariableDeclaration,
        /*reservedInNestedScopes*/
        true
      );
      getClassLexicalEnvironment().superClassReference = temp;
      return factory2.updateExpressionWithTypeArguments(
        node,
        factory2.createAssignment(
          temp,
          visitNode(node.expression, visitor, isExpression)
        ),
        /*typeArguments*/
        void 0
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitInNewClassLexicalEnvironment(node, visitor2) {
    var _a;
    const savedCurrentClassContainer = currentClassContainer;
    const savedPendingExpressions = pendingExpressions;
    const savedLexicalEnvironment = lexicalEnvironment;
    currentClassContainer = node;
    pendingExpressions = void 0;
    startClassLexicalEnvironment();
    const shouldAlwaysTransformPrivateStaticElements = getInternalEmitFlags(node) & 32 /* TransformPrivateStaticElements */;
    if (shouldTransformPrivateElementsOrClassStaticBlocks || shouldAlwaysTransformPrivateStaticElements) {
      const name = getNameOfDeclaration(node);
      if (name && isIdentifier(name)) {
        getPrivateIdentifierEnvironment().data.className = name;
      } else if ((_a = node.emitNode) == null ? void 0 : _a.assignedName) {
        if (isStringLiteral(node.emitNode.assignedName)) {
          if (node.emitNode.assignedName.textSourceNode && isIdentifier(node.emitNode.assignedName.textSourceNode)) {
            getPrivateIdentifierEnvironment().data.className = node.emitNode.assignedName.textSourceNode;
          } else if (isIdentifierText(node.emitNode.assignedName.text, languageVersion)) {
            const prefixName = factory2.createIdentifier(node.emitNode.assignedName.text);
            getPrivateIdentifierEnvironment().data.className = prefixName;
          }
        }
      }
    }
    if (shouldTransformPrivateElementsOrClassStaticBlocks) {
      const privateInstanceMethodsAndAccessors = getPrivateInstanceMethodsAndAccessors(node);
      if (some(privateInstanceMethodsAndAccessors)) {
        getPrivateIdentifierEnvironment().data.weakSetName = createHoistedVariableForClass(
          "instances",
          privateInstanceMethodsAndAccessors[0].name
        );
      }
    }
    const facts = getClassFacts(node);
    if (facts) {
      getClassLexicalEnvironment().facts = facts;
    }
    if (facts & 8 /* NeedsSubstitutionForThisInClassStaticField */) {
      enableSubstitutionForClassStaticThisOrSuperReference();
    }
    const result = visitor2(node, facts);
    endClassLexicalEnvironment();
    Debug.assert(lexicalEnvironment === savedLexicalEnvironment);
    currentClassContainer = savedCurrentClassContainer;
    pendingExpressions = savedPendingExpressions;
    return result;
  }
  function visitClassDeclaration(node) {
    return visitInNewClassLexicalEnvironment(node, visitClassDeclarationInNewClassLexicalEnvironment);
  }
  function visitClassDeclarationInNewClassLexicalEnvironment(node, facts) {
    var _a, _b;
    let pendingClassReferenceAssignment;
    if (facts & 2 /* NeedsClassConstructorReference */) {
      if (shouldTransformPrivateElementsOrClassStaticBlocks && ((_a = node.emitNode) == null ? void 0 : _a.classThis)) {
        getClassLexicalEnvironment().classConstructor = node.emitNode.classThis;
        pendingClassReferenceAssignment = factory2.createAssignment(node.emitNode.classThis, factory2.getInternalName(node));
      } else {
        const temp = factory2.createTempVariable(
          hoistVariableDeclaration,
          /*reservedInNestedScopes*/
          true
        );
        getClassLexicalEnvironment().classConstructor = factory2.cloneNode(temp);
        pendingClassReferenceAssignment = factory2.createAssignment(temp, factory2.getInternalName(node));
      }
    }
    if ((_b = node.emitNode) == null ? void 0 : _b.classThis) {
      getClassLexicalEnvironment().classThis = node.emitNode.classThis;
    }
    const isClassWithConstructorReference = resolver.hasNodeCheckFlag(node, 262144 /* ContainsConstructorReference */);
    const isExport = hasSyntacticModifier(node, 32 /* Export */);
    const isDefault = hasSyntacticModifier(node, 2048 /* Default */);
    let modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
    const heritageClauses = visitNodes2(node.heritageClauses, heritageClauseVisitor, isHeritageClause);
    const { members, prologue } = transformClassMembers(node);
    const statements = [];
    if (pendingClassReferenceAssignment) {
      getPendingExpressions().unshift(pendingClassReferenceAssignment);
    }
    if (some(pendingExpressions)) {
      statements.push(factory2.createExpressionStatement(factory2.inlineExpressions(pendingExpressions)));
    }
    if (shouldTransformInitializersUsingSet || shouldTransformPrivateElementsOrClassStaticBlocks || getInternalEmitFlags(node) & 32 /* TransformPrivateStaticElements */) {
      const staticProperties = getStaticPropertiesAndClassStaticBlock(node);
      if (some(staticProperties)) {
        addPropertyOrClassStaticBlockStatements(statements, staticProperties, factory2.getInternalName(node));
      }
    }
    if (statements.length > 0 && isExport && isDefault) {
      modifiers = visitNodes2(modifiers, (node2) => isExportOrDefaultModifier(node2) ? void 0 : node2, isModifier);
      statements.push(factory2.createExportAssignment(
        /*modifiers*/
        void 0,
        /*isExportEquals*/
        false,
        factory2.getLocalName(
          node,
          /*allowComments*/
          false,
          /*allowSourceMaps*/
          true
        )
      ));
    }
    const alias = getClassLexicalEnvironment().classConstructor;
    if (isClassWithConstructorReference && alias) {
      enableSubstitutionForClassAliases();
      classAliases[getOriginalNodeId(node)] = alias;
    }
    const classDecl = factory2.updateClassDeclaration(
      node,
      modifiers,
      node.name,
      /*typeParameters*/
      void 0,
      heritageClauses,
      members
    );
    statements.unshift(classDecl);
    if (prologue) {
      statements.unshift(factory2.createExpressionStatement(prologue));
    }
    return statements;
  }
  function visitClassExpression(node) {
    return visitInNewClassLexicalEnvironment(node, visitClassExpressionInNewClassLexicalEnvironment);
  }
  function visitClassExpressionInNewClassLexicalEnvironment(node, facts) {
    var _a, _b, _c;
    const isDecoratedClassDeclaration = !!(facts & 1 /* ClassWasDecorated */);
    const staticPropertiesOrClassStaticBlocks = getStaticPropertiesAndClassStaticBlock(node);
    const isClassWithConstructorReference = resolver.hasNodeCheckFlag(node, 262144 /* ContainsConstructorReference */);
    const requiresBlockScopedVar = resolver.hasNodeCheckFlag(node, 32768 /* BlockScopedBindingInLoop */);
    let temp;
    function createClassTempVar() {
      var _a2;
      if (shouldTransformPrivateElementsOrClassStaticBlocks && ((_a2 = node.emitNode) == null ? void 0 : _a2.classThis)) {
        return getClassLexicalEnvironment().classConstructor = node.emitNode.classThis;
      }
      const temp2 = factory2.createTempVariable(
        requiresBlockScopedVar ? addBlockScopedVariable : hoistVariableDeclaration,
        /*reservedInNestedScopes*/
        true
      );
      getClassLexicalEnvironment().classConstructor = factory2.cloneNode(temp2);
      return temp2;
    }
    if ((_a = node.emitNode) == null ? void 0 : _a.classThis) {
      getClassLexicalEnvironment().classThis = node.emitNode.classThis;
    }
    if (facts & 2 /* NeedsClassConstructorReference */) {
      temp ?? (temp = createClassTempVar());
    }
    const modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
    const heritageClauses = visitNodes2(node.heritageClauses, heritageClauseVisitor, isHeritageClause);
    const { members, prologue } = transformClassMembers(node);
    const classExpression = factory2.updateClassExpression(
      node,
      modifiers,
      node.name,
      /*typeParameters*/
      void 0,
      heritageClauses,
      members
    );
    const expressions = [];
    if (prologue) {
      expressions.push(prologue);
    }
    const hasTransformableStatics = (shouldTransformPrivateElementsOrClassStaticBlocks || getInternalEmitFlags(node) & 32 /* TransformPrivateStaticElements */) && some(staticPropertiesOrClassStaticBlocks, (node2) => isClassStaticBlockDeclaration(node2) || isPrivateIdentifierClassElementDeclaration(node2) || shouldTransformInitializers && isInitializedProperty(node2));
    if (hasTransformableStatics || some(pendingExpressions)) {
      if (isDecoratedClassDeclaration) {
        Debug.assertIsDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration.");
        if (some(pendingExpressions)) {
          addRange(pendingStatements, map(pendingExpressions, factory2.createExpressionStatement));
        }
        if (some(staticPropertiesOrClassStaticBlocks)) {
          addPropertyOrClassStaticBlockStatements(pendingStatements, staticPropertiesOrClassStaticBlocks, ((_b = node.emitNode) == null ? void 0 : _b.classThis) ?? factory2.getInternalName(node));
        }
        if (temp) {
          expressions.push(factory2.createAssignment(temp, classExpression));
        } else if (shouldTransformPrivateElementsOrClassStaticBlocks && ((_c = node.emitNode) == null ? void 0 : _c.classThis)) {
          expressions.push(factory2.createAssignment(node.emitNode.classThis, classExpression));
        } else {
          expressions.push(classExpression);
        }
      } else {
        temp ?? (temp = createClassTempVar());
        if (isClassWithConstructorReference) {
          enableSubstitutionForClassAliases();
          const alias = factory2.cloneNode(temp);
          alias.emitNode.autoGenerate.flags &= ~8 /* ReservedInNestedScopes */;
          classAliases[getOriginalNodeId(node)] = alias;
        }
        expressions.push(factory2.createAssignment(temp, classExpression));
        addRange(expressions, pendingExpressions);
        addRange(expressions, generateInitializedPropertyExpressionsOrClassStaticBlock(staticPropertiesOrClassStaticBlocks, temp));
        expressions.push(factory2.cloneNode(temp));
      }
    } else {
      expressions.push(classExpression);
    }
    if (expressions.length > 1) {
      addEmitFlags(classExpression, 131072 /* Indented */);
      expressions.forEach(startOnNewLine);
    }
    return factory2.inlineExpressions(expressions);
  }
  function visitClassStaticBlockDeclaration(node) {
    if (!shouldTransformPrivateElementsOrClassStaticBlocks) {
      return visitEachChild(node, visitor, context);
    }
    return void 0;
  }
  function visitThisExpression(node) {
    if (shouldTransformThisInStaticInitializers && currentClassElement && isClassStaticBlockDeclaration(currentClassElement) && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data)) {
      const { classThis, classConstructor } = lexicalEnvironment.data;
      return classThis ?? classConstructor ?? node;
    }
    return node;
  }
  function transformClassMembers(node) {
    const shouldTransformPrivateStaticElementsInClass = !!(getInternalEmitFlags(node) & 32 /* TransformPrivateStaticElements */);
    if (shouldTransformPrivateElementsOrClassStaticBlocks || shouldTransformPrivateStaticElementsInFile) {
      for (const member of node.members) {
        if (isPrivateIdentifierClassElementDeclaration(member)) {
          if (shouldTransformClassElementToWeakMap(member)) {
            addPrivateIdentifierToEnvironment(member, member.name, addPrivateIdentifierClassElementToEnvironment);
          } else {
            const privateEnv = getPrivateIdentifierEnvironment();
            setPrivateIdentifier(privateEnv, member.name, { kind: "untransformed" });
          }
        }
      }
      if (shouldTransformPrivateElementsOrClassStaticBlocks) {
        if (some(getPrivateInstanceMethodsAndAccessors(node))) {
          createBrandCheckWeakSetForPrivateMethods();
        }
      }
      if (shouldTransformAutoAccessorsInCurrentClass()) {
        for (const member of node.members) {
          if (isAutoAccessorPropertyDeclaration(member)) {
            const storageName = factory2.getGeneratedPrivateNameForNode(
              member.name,
              /*prefix*/
              void 0,
              "_accessor_storage"
            );
            if (shouldTransformPrivateElementsOrClassStaticBlocks || shouldTransformPrivateStaticElementsInClass && hasStaticModifier(member)) {
              addPrivateIdentifierToEnvironment(member, storageName, addPrivateIdentifierPropertyDeclarationToEnvironment);
            } else {
              const privateEnv = getPrivateIdentifierEnvironment();
              setPrivateIdentifier(privateEnv, storageName, { kind: "untransformed" });
            }
          }
        }
      }
    }
    let members = visitNodes2(node.members, classElementVisitor, isClassElement);
    let syntheticConstructor;
    if (!some(members, isConstructorDeclaration)) {
      syntheticConstructor = transformConstructor(
        /*constructor*/
        void 0,
        node
      );
    }
    let prologue;
    let syntheticStaticBlock;
    if (!shouldTransformPrivateElementsOrClassStaticBlocks && some(pendingExpressions)) {
      let statement = factory2.createExpressionStatement(factory2.inlineExpressions(pendingExpressions));
      if (statement.transformFlags & 134234112 /* ContainsLexicalThisOrSuper */) {
        const temp = factory2.createTempVariable(hoistVariableDeclaration);
        const arrow = factory2.createArrowFunction(
          /*modifiers*/
          void 0,
          /*typeParameters*/
          void 0,
          /*parameters*/
          [],
          /*type*/
          void 0,
          /*equalsGreaterThanToken*/
          void 0,
          factory2.createBlock([statement])
        );
        prologue = factory2.createAssignment(temp, arrow);
        statement = factory2.createExpressionStatement(factory2.createCallExpression(
          temp,
          /*typeArguments*/
          void 0,
          []
        ));
      }
      const block = factory2.createBlock([statement]);
      syntheticStaticBlock = factory2.createClassStaticBlockDeclaration(block);
      pendingExpressions = void 0;
    }
    if (syntheticConstructor || syntheticStaticBlock) {
      let membersArray;
      const classThisAssignmentBlock = find(members, isClassThisAssignmentBlock);
      const classNamedEvaluationHelperBlock = find(members, isClassNamedEvaluationHelperBlock);
      membersArray = append(membersArray, classThisAssignmentBlock);
      membersArray = append(membersArray, classNamedEvaluationHelperBlock);
      membersArray = append(membersArray, syntheticConstructor);
      membersArray = append(membersArray, syntheticStaticBlock);
      const remainingMembers = classThisAssignmentBlock || classNamedEvaluationHelperBlock ? filter(members, (member) => member !== classThisAssignmentBlock && member !== classNamedEvaluationHelperBlock) : members;
      membersArray = addRange(membersArray, remainingMembers);
      members = setTextRange(
        factory2.createNodeArray(membersArray),
        /*location*/
        node.members
      );
    }
    return { members, prologue };
  }
  function createBrandCheckWeakSetForPrivateMethods() {
    const { weakSetName } = getPrivateIdentifierEnvironment().data;
    Debug.assert(weakSetName, "weakSetName should be set in private identifier environment");
    getPendingExpressions().push(
      factory2.createAssignment(
        weakSetName,
        factory2.createNewExpression(
          factory2.createIdentifier("WeakSet"),
          /*typeArguments*/
          void 0,
          []
        )
      )
    );
  }
  function transformConstructor(constructor, container) {
    constructor = visitNode(constructor, visitor, isConstructorDeclaration);
    if (!(lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) || !(lexicalEnvironment.data.facts & 16 /* WillHoistInitializersToConstructor */)) {
      return constructor;
    }
    const extendsClauseElement = getEffectiveBaseTypeNode(container);
    const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== 106 /* NullKeyword */);
    const parameters = visitParameterList(constructor ? constructor.parameters : void 0, visitor, context);
    const body = transformConstructorBody(container, constructor, isDerivedClass);
    if (!body) {
      return constructor;
    }
    if (constructor) {
      Debug.assert(parameters);
      return factory2.updateConstructorDeclaration(
        constructor,
        /*modifiers*/
        void 0,
        parameters,
        body
      );
    }
    return startOnNewLine(
      setOriginalNode(
        setTextRange(
          factory2.createConstructorDeclaration(
            /*modifiers*/
            void 0,
            parameters ?? [],
            body
          ),
          constructor || container
        ),
        constructor
      )
    );
  }
  function transformConstructorBodyWorker(statementsOut, statementsIn, statementOffset, superPath, superPathDepth, initializerStatements, constructor) {
    const superStatementIndex = superPath[superPathDepth];
    const superStatement = statementsIn[superStatementIndex];
    addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, statementOffset, superStatementIndex - statementOffset));
    statementOffset = superStatementIndex + 1;
    if (isTryStatement(superStatement)) {
      const tryBlockStatements = [];
      transformConstructorBodyWorker(
        tryBlockStatements,
        superStatement.tryBlock.statements,
        /*statementOffset*/
        0,
        superPath,
        superPathDepth + 1,
        initializerStatements,
        constructor
      );
      const tryBlockStatementsArray = factory2.createNodeArray(tryBlockStatements);
      setTextRange(tryBlockStatementsArray, superStatement.tryBlock.statements);
      statementsOut.push(factory2.updateTryStatement(
        superStatement,
        factory2.updateBlock(superStatement.tryBlock, tryBlockStatements),
        visitNode(superStatement.catchClause, visitor, isCatchClause),
        visitNode(superStatement.finallyBlock, visitor, isBlock)
      ));
    } else {
      addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, superStatementIndex, 1));
      while (statementOffset < statementsIn.length) {
        const statement = statementsIn[statementOffset];
        if (isParameterPropertyDeclaration(getOriginalNode(statement), constructor)) {
          statementOffset++;
        } else {
          break;
        }
      }
      addRange(statementsOut, initializerStatements);
    }
    addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, statementOffset));
  }
  function transformConstructorBody(node, constructor, isDerivedClass) {
    const instanceProperties = getProperties(
      node,
      /*requireInitializer*/
      false,
      /*isStatic*/
      false
    );
    let properties = instanceProperties;
    if (!useDefineForClassFields) {
      properties = filter(properties, (property) => !!property.initializer || isPrivateIdentifier(property.name) || hasAccessorModifier(property));
    }
    const privateMethodsAndAccessors = getPrivateInstanceMethodsAndAccessors(node);
    const needsConstructorBody = some(properties) || some(privateMethodsAndAccessors);
    if (!constructor && !needsConstructorBody) {
      return visitFunctionBody(
        /*node*/
        void 0,
        visitor,
        context
      );
    }
    resumeLexicalEnvironment();
    const needsSyntheticConstructor = !constructor && isDerivedClass;
    let statementOffset = 0;
    let statements = [];
    const initializerStatements = [];
    const receiver = factory2.createThis();
    addInstanceMethodStatements(initializerStatements, privateMethodsAndAccessors, receiver);
    if (constructor) {
      const parameterProperties = filter(instanceProperties, (prop) => isParameterPropertyDeclaration(getOriginalNode(prop), constructor));
      const nonParameterProperties = filter(properties, (prop) => !isParameterPropertyDeclaration(getOriginalNode(prop), constructor));
      addPropertyOrClassStaticBlockStatements(initializerStatements, parameterProperties, receiver);
      addPropertyOrClassStaticBlockStatements(initializerStatements, nonParameterProperties, receiver);
    } else {
      addPropertyOrClassStaticBlockStatements(initializerStatements, properties, receiver);
    }
    if (constructor == null ? void 0 : constructor.body) {
      statementOffset = factory2.copyPrologue(
        constructor.body.statements,
        statements,
        /*ensureUseStrict*/
        false,
        visitor
      );
      const superStatementIndices = findSuperStatementIndexPath(constructor.body.statements, statementOffset);
      if (superStatementIndices.length) {
        transformConstructorBodyWorker(
          statements,
          constructor.body.statements,
          statementOffset,
          superStatementIndices,
          /*superPathDepth*/
          0,
          initializerStatements,
          constructor
        );
      } else {
        while (statementOffset < constructor.body.statements.length) {
          const statement = constructor.body.statements[statementOffset];
          if (isParameterPropertyDeclaration(getOriginalNode(statement), constructor)) {
            statementOffset++;
          } else {
            break;
          }
        }
        addRange(statements, initializerStatements);
        addRange(statements, visitNodes2(constructor.body.statements, visitor, isStatement, statementOffset));
      }
    } else {
      if (needsSyntheticConstructor) {
        statements.push(
          factory2.createExpressionStatement(
            factory2.createCallExpression(
              factory2.createSuper(),
              /*typeArguments*/
              void 0,
              [factory2.createSpreadElement(factory2.createIdentifier("arguments"))]
            )
          )
        );
      }
      addRange(statements, initializerStatements);
    }
    statements = factory2.mergeLexicalEnvironment(statements, endLexicalEnvironment());
    if (statements.length === 0 && !constructor) {
      return void 0;
    }
    const multiLine = (constructor == null ? void 0 : constructor.body) && constructor.body.statements.length >= statements.length ? constructor.body.multiLine ?? statements.length > 0 : statements.length > 0;
    return setTextRange(
      factory2.createBlock(
        setTextRange(
          factory2.createNodeArray(statements),
          /*location*/
          constructor ? constructor.body.statements : node.members
        ),
        multiLine
      ),
      /*location*/
      constructor ? constructor.body : void 0
    );
  }
  function addPropertyOrClassStaticBlockStatements(statements, properties, receiver) {
    for (const property of properties) {
      if (isStatic(property) && !shouldTransformPrivateElementsOrClassStaticBlocks) {
        continue;
      }
      const statement = transformPropertyOrClassStaticBlock(property, receiver);
      if (!statement) {
        continue;
      }
      statements.push(statement);
    }
  }
  function transformPropertyOrClassStaticBlock(property, receiver) {
    const expression = isClassStaticBlockDeclaration(property) ? setCurrentClassElementAnd(property, transformClassStaticBlockDeclaration, property) : transformProperty(property, receiver);
    if (!expression) {
      return void 0;
    }
    const statement = factory2.createExpressionStatement(expression);
    setOriginalNode(statement, property);
    addEmitFlags(statement, getEmitFlags(property) & 3072 /* NoComments */);
    setCommentRange(statement, property);
    const propertyOriginalNode = getOriginalNode(property);
    if (isParameter(propertyOriginalNode)) {
      setSourceMapRange(statement, propertyOriginalNode);
      removeAllComments(statement);
    } else {
      setSourceMapRange(statement, moveRangePastModifiers(property));
    }
    setSyntheticLeadingComments(expression, void 0);
    setSyntheticTrailingComments(expression, void 0);
    if (hasAccessorModifier(propertyOriginalNode)) {
      addEmitFlags(statement, 3072 /* NoComments */);
    }
    return statement;
  }
  function generateInitializedPropertyExpressionsOrClassStaticBlock(propertiesOrClassStaticBlocks, receiver) {
    const expressions = [];
    for (const property of propertiesOrClassStaticBlocks) {
      const expression = isClassStaticBlockDeclaration(property) ? setCurrentClassElementAnd(property, transformClassStaticBlockDeclaration, property) : setCurrentClassElementAnd(
        property,
        () => transformProperty(property, receiver),
        /*arg*/
        void 0
      );
      if (!expression) {
        continue;
      }
      startOnNewLine(expression);
      setOriginalNode(expression, property);
      addEmitFlags(expression, getEmitFlags(property) & 3072 /* NoComments */);
      setSourceMapRange(expression, moveRangePastModifiers(property));
      setCommentRange(expression, property);
      expressions.push(expression);
    }
    return expressions;
  }
  function transformProperty(property, receiver) {
    var _a;
    const savedCurrentClassElement = currentClassElement;
    const transformed = transformPropertyWorker(property, receiver);
    if (transformed && hasStaticModifier(property) && ((_a = lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) == null ? void 0 : _a.facts)) {
      setOriginalNode(transformed, property);
      addEmitFlags(transformed, 4 /* AdviseOnEmitNode */);
      setSourceMapRange(transformed, getSourceMapRange(property.name));
      lexicalEnvironmentMap.set(getOriginalNode(property), lexicalEnvironment);
    }
    currentClassElement = savedCurrentClassElement;
    return transformed;
  }
  function transformPropertyWorker(property, receiver) {
    const emitAssignment = !useDefineForClassFields;
    if (isNamedEvaluation(property, isAnonymousClassNeedingAssignedName)) {
      property = transformNamedEvaluation(context, property);
    }
    const propertyName = hasAccessorModifier(property) ? factory2.getGeneratedPrivateNameForNode(property.name) : isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression) ? factory2.updateComputedPropertyName(property.name, factory2.getGeneratedNameForNode(property.name)) : property.name;
    if (hasStaticModifier(property)) {
      currentClassElement = property;
    }
    if (isPrivateIdentifier(propertyName) && shouldTransformClassElementToWeakMap(property)) {
      const privateIdentifierInfo = accessPrivateIdentifier2(propertyName);
      if (privateIdentifierInfo) {
        if (privateIdentifierInfo.kind === "f" /* Field */) {
          if (!privateIdentifierInfo.isStatic) {
            return createPrivateInstanceFieldInitializer(
              factory2,
              receiver,
              visitNode(property.initializer, visitor, isExpression),
              privateIdentifierInfo.brandCheckIdentifier
            );
          } else {
            return createPrivateStaticFieldInitializer(
              factory2,
              privateIdentifierInfo.variableName,
              visitNode(property.initializer, visitor, isExpression)
            );
          }
        } else {
          return void 0;
        }
      } else {
        Debug.fail("Undeclared private name for property declaration.");
      }
    }
    if ((isPrivateIdentifier(propertyName) || hasStaticModifier(property)) && !property.initializer) {
      return void 0;
    }
    const propertyOriginalNode = getOriginalNode(property);
    if (hasSyntacticModifier(propertyOriginalNode, 64 /* Abstract */)) {
      return void 0;
    }
    let initializer = visitNode(property.initializer, visitor, isExpression);
    if (isParameterPropertyDeclaration(propertyOriginalNode, propertyOriginalNode.parent) && isIdentifier(propertyName)) {
      const localName = factory2.cloneNode(propertyName);
      if (initializer) {
        if (isParenthesizedExpression(initializer) && isCommaExpression(initializer.expression) && isCallToHelper(initializer.expression.left, "___runInitializers") && isVoidExpression(initializer.expression.right) && isNumericLiteral(initializer.expression.right.expression)) {
          initializer = initializer.expression.left;
        }
        initializer = factory2.inlineExpressions([initializer, localName]);
      } else {
        initializer = localName;
      }
      setEmitFlags(propertyName, 3072 /* NoComments */ | 96 /* NoSourceMap */);
      setSourceMapRange(localName, propertyOriginalNode.name);
      setEmitFlags(localName, 3072 /* NoComments */);
    } else {
      initializer ?? (initializer = factory2.createVoidZero());
    }
    if (emitAssignment || isPrivateIdentifier(propertyName)) {
      const memberAccess = createMemberAccessForPropertyName(
        factory2,
        receiver,
        propertyName,
        /*location*/
        propertyName
      );
      addEmitFlags(memberAccess, 1024 /* NoLeadingComments */);
      const expression = factory2.createAssignment(memberAccess, initializer);
      return expression;
    } else {
      const name = isComputedPropertyName(propertyName) ? propertyName.expression : isIdentifier(propertyName) ? factory2.createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) : propertyName;
      const descriptor = factory2.createPropertyDescriptor({ value: initializer, configurable: true, writable: true, enumerable: true });
      return factory2.createObjectDefinePropertyCall(receiver, name, descriptor);
    }
  }
  function enableSubstitutionForClassAliases() {
    if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
      enabledSubstitutions |= 1 /* ClassAliases */;
      context.enableSubstitution(80 /* Identifier */);
      classAliases = [];
    }
  }
  function enableSubstitutionForClassStaticThisOrSuperReference() {
    if ((enabledSubstitutions & 2 /* ClassStaticThisOrSuperReference */) === 0) {
      enabledSubstitutions |= 2 /* ClassStaticThisOrSuperReference */;
      context.enableSubstitution(110 /* ThisKeyword */);
      context.enableEmitNotification(262 /* FunctionDeclaration */);
      context.enableEmitNotification(218 /* FunctionExpression */);
      context.enableEmitNotification(176 /* Constructor */);
      context.enableEmitNotification(177 /* GetAccessor */);
      context.enableEmitNotification(178 /* SetAccessor */);
      context.enableEmitNotification(174 /* MethodDeclaration */);
      context.enableEmitNotification(172 /* PropertyDeclaration */);
      context.enableEmitNotification(167 /* ComputedPropertyName */);
    }
  }
  function addInstanceMethodStatements(statements, methods, receiver) {
    if (!shouldTransformPrivateElementsOrClassStaticBlocks || !some(methods)) {
      return;
    }
    const { weakSetName } = getPrivateIdentifierEnvironment().data;
    Debug.assert(weakSetName, "weakSetName should be set in private identifier environment");
    statements.push(
      factory2.createExpressionStatement(
        createPrivateInstanceMethodInitializer(factory2, receiver, weakSetName)
      )
    );
  }
  function visitInvalidSuperProperty(node) {
    return isPropertyAccessExpression(node) ? factory2.updatePropertyAccessExpression(
      node,
      factory2.createVoidZero(),
      node.name
    ) : factory2.updateElementAccessExpression(
      node,
      factory2.createVoidZero(),
      visitNode(node.argumentExpression, visitor, isExpression)
    );
  }
  function getPropertyNameExpressionIfNeeded(name, shouldHoist) {
    if (isComputedPropertyName(name)) {
      const cacheAssignment = findComputedPropertyNameCacheAssignment(name);
      const expression = visitNode(name.expression, visitor, isExpression);
      const innerExpression = skipPartiallyEmittedExpressions(expression);
      const inlinable = isSimpleInlineableExpression(innerExpression);
      const alreadyTransformed = !!cacheAssignment || isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left);
      if (!alreadyTransformed && !inlinable && shouldHoist) {
        const generatedName = factory2.getGeneratedNameForNode(name);
        if (resolver.hasNodeCheckFlag(name, 32768 /* BlockScopedBindingInLoop */)) {
          addBlockScopedVariable(generatedName);
        } else {
          hoistVariableDeclaration(generatedName);
        }
        return factory2.createAssignment(generatedName, expression);
      }
      return inlinable || isIdentifier(innerExpression) ? void 0 : expression;
    }
  }
  function startClassLexicalEnvironment() {
    lexicalEnvironment = { previous: lexicalEnvironment, data: void 0 };
  }
  function endClassLexicalEnvironment() {
    lexicalEnvironment = lexicalEnvironment == null ? void 0 : lexicalEnvironment.previous;
  }
  function getClassLexicalEnvironment() {
    Debug.assert(lexicalEnvironment);
    return lexicalEnvironment.data ?? (lexicalEnvironment.data = {
      facts: 0 /* None */,
      classConstructor: void 0,
      classThis: void 0,
      superClassReference: void 0
      // privateIdentifierEnvironment: undefined,
    });
  }
  function getPrivateIdentifierEnvironment() {
    Debug.assert(lexicalEnvironment);
    return lexicalEnvironment.privateEnv ?? (lexicalEnvironment.privateEnv = newPrivateEnvironment({
      className: void 0,
      weakSetName: void 0
    }));
  }
  function getPendingExpressions() {
    return pendingExpressions ?? (pendingExpressions = []);
  }
  function addPrivateIdentifierClassElementToEnvironment(node, name, lex, privateEnv, isStatic2, isValid, previousInfo) {
    if (isAutoAccessorPropertyDeclaration(node)) {
      addPrivateIdentifierAutoAccessorPropertyDeclarationToEnvironment(node, name, lex, privateEnv, isStatic2, isValid, previousInfo);
    } else if (isPropertyDeclaration(node)) {
      addPrivateIdentifierPropertyDeclarationToEnvironment(node, name, lex, privateEnv, isStatic2, isValid, previousInfo);
    } else if (isMethodDeclaration(node)) {
      addPrivateIdentifierMethodDeclarationToEnvironment(node, name, lex, privateEnv, isStatic2, isValid, previousInfo);
    } else if (isGetAccessorDeclaration(node)) {
      addPrivateIdentifierGetAccessorDeclarationToEnvironment(node, name, lex, privateEnv, isStatic2, isValid, previousInfo);
    } else if (isSetAccessorDeclaration(node)) {
      addPrivateIdentifierSetAccessorDeclarationToEnvironment(node, name, lex, privateEnv, isStatic2, isValid, previousInfo);
    }
  }
  function addPrivateIdentifierPropertyDeclarationToEnvironment(_node, name, lex, privateEnv, isStatic2, isValid, _previousInfo) {
    if (isStatic2) {
      const brandCheckIdentifier = Debug.checkDefined(lex.classThis ?? lex.classConstructor, "classConstructor should be set in private identifier environment");
      const variableName = createHoistedVariableForPrivateName(name);
      setPrivateIdentifier(privateEnv, name, {
        kind: "f" /* Field */,
        isStatic: true,
        brandCheckIdentifier,
        variableName,
        isValid
      });
    } else {
      const weakMapName = createHoistedVariableForPrivateName(name);
      setPrivateIdentifier(privateEnv, name, {
        kind: "f" /* Field */,
        isStatic: false,
        brandCheckIdentifier: weakMapName,
        isValid
      });
      getPendingExpressions().push(factory2.createAssignment(
        weakMapName,
        factory2.createNewExpression(
          factory2.createIdentifier("WeakMap"),
          /*typeArguments*/
          void 0,
          []
        )
      ));
    }
  }
  function addPrivateIdentifierMethodDeclarationToEnvironment(_node, name, lex, privateEnv, isStatic2, isValid, _previousInfo) {
    const methodName = createHoistedVariableForPrivateName(name);
    const brandCheckIdentifier = isStatic2 ? Debug.checkDefined(lex.classThis ?? lex.classConstructor, "classConstructor should be set in private identifier environment") : Debug.checkDefined(privateEnv.data.weakSetName, "weakSetName should be set in private identifier environment");
    setPrivateIdentifier(privateEnv, name, {
      kind: "m" /* Method */,
      methodName,
      brandCheckIdentifier,
      isStatic: isStatic2,
      isValid
    });
  }
  function addPrivateIdentifierGetAccessorDeclarationToEnvironment(_node, name, lex, privateEnv, isStatic2, isValid, previousInfo) {
    const getterName = createHoistedVariableForPrivateName(name, "_get");
    const brandCheckIdentifier = isStatic2 ? Debug.checkDefined(lex.classThis ?? lex.classConstructor, "classConstructor should be set in private identifier environment") : Debug.checkDefined(privateEnv.data.weakSetName, "weakSetName should be set in private identifier environment");
    if ((previousInfo == null ? void 0 : previousInfo.kind) === "a" /* Accessor */ && previousInfo.isStatic === isStatic2 && !previousInfo.getterName) {
      previousInfo.getterName = getterName;
    } else {
      setPrivateIdentifier(privateEnv, name, {
        kind: "a" /* Accessor */,
        getterName,
        setterName: void 0,
        brandCheckIdentifier,
        isStatic: isStatic2,
        isValid
      });
    }
  }
  function addPrivateIdentifierSetAccessorDeclarationToEnvironment(_node, name, lex, privateEnv, isStatic2, isValid, previousInfo) {
    const setterName = createHoistedVariableForPrivateName(name, "_set");
    const brandCheckIdentifier = isStatic2 ? Debug.checkDefined(lex.classThis ?? lex.classConstructor, "classConstructor should be set in private identifier environment") : Debug.checkDefined(privateEnv.data.weakSetName, "weakSetName should be set in private identifier environment");
    if ((previousInfo == null ? void 0 : previousInfo.kind) === "a" /* Accessor */ && previousInfo.isStatic === isStatic2 && !previousInfo.setterName) {
      previousInfo.setterName = setterName;
    } else {
      setPrivateIdentifier(privateEnv, name, {
        kind: "a" /* Accessor */,
        getterName: void 0,
        setterName,
        brandCheckIdentifier,
        isStatic: isStatic2,
        isValid
      });
    }
  }
  function addPrivateIdentifierAutoAccessorPropertyDeclarationToEnvironment(_node, name, lex, privateEnv, isStatic2, isValid, _previousInfo) {
    const getterName = createHoistedVariableForPrivateName(name, "_get");
    const setterName = createHoistedVariableForPrivateName(name, "_set");
    const brandCheckIdentifier = isStatic2 ? Debug.checkDefined(lex.classThis ?? lex.classConstructor, "classConstructor should be set in private identifier environment") : Debug.checkDefined(privateEnv.data.weakSetName, "weakSetName should be set in private identifier environment");
    setPrivateIdentifier(privateEnv, name, {
      kind: "a" /* Accessor */,
      getterName,
      setterName,
      brandCheckIdentifier,
      isStatic: isStatic2,
      isValid
    });
  }
  function addPrivateIdentifierToEnvironment(node, name, addDeclaration) {
    const lex = getClassLexicalEnvironment();
    const privateEnv = getPrivateIdentifierEnvironment();
    const previousInfo = getPrivateIdentifier(privateEnv, name);
    const isStatic2 = hasStaticModifier(node);
    const isValid = !isReservedPrivateName(name) && previousInfo === void 0;
    addDeclaration(node, name, lex, privateEnv, isStatic2, isValid, previousInfo);
  }
  function createHoistedVariableForClass(name, node, suffix) {
    const { className } = getPrivateIdentifierEnvironment().data;
    const prefix = className ? { prefix: "_", node: className, suffix: "_" } : "_";
    const identifier = typeof name === "object" ? factory2.getGeneratedNameForNode(name, 16 /* Optimistic */ | 8 /* ReservedInNestedScopes */, prefix, suffix) : typeof name === "string" ? factory2.createUniqueName(name, 16 /* Optimistic */, prefix, suffix) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0,
      /*reservedInNestedScopes*/
      true,
      prefix,
      suffix
    );
    if (resolver.hasNodeCheckFlag(node, 32768 /* BlockScopedBindingInLoop */)) {
      addBlockScopedVariable(identifier);
    } else {
      hoistVariableDeclaration(identifier);
    }
    return identifier;
  }
  function createHoistedVariableForPrivateName(name, suffix) {
    const text = tryGetTextOfPropertyName(name);
    return createHoistedVariableForClass((text == null ? void 0 : text.substring(1)) ?? name, name, suffix);
  }
  function accessPrivateIdentifier2(name) {
    const info = accessPrivateIdentifier(lexicalEnvironment, name);
    return (info == null ? void 0 : info.kind) === "untransformed" ? void 0 : info;
  }
  function wrapPrivateIdentifierForDestructuringTarget(node) {
    const parameter = factory2.getGeneratedNameForNode(node);
    const info = accessPrivateIdentifier2(node.name);
    if (!info) {
      return visitEachChild(node, visitor, context);
    }
    let receiver = node.expression;
    if (isThisProperty(node) || isSuperProperty(node) || !isSimpleCopiableExpression(node.expression)) {
      receiver = factory2.createTempVariable(
        hoistVariableDeclaration,
        /*reservedInNestedScopes*/
        true
      );
      getPendingExpressions().push(factory2.createBinaryExpression(receiver, 64 /* EqualsToken */, visitNode(node.expression, visitor, isExpression)));
    }
    return factory2.createAssignmentTargetWrapper(
      parameter,
      createPrivateIdentifierAssignment(
        info,
        receiver,
        parameter,
        64 /* EqualsToken */
      )
    );
  }
  function visitDestructuringAssignmentTarget(node) {
    if (isObjectLiteralExpression(node) || isArrayLiteralExpression(node)) {
      return visitAssignmentPattern(node);
    }
    if (isPrivateIdentifierPropertyAccessExpression(node)) {
      return wrapPrivateIdentifierForDestructuringTarget(node);
    } else if (shouldTransformSuperInStaticInitializers && currentClassElement && isSuperProperty(node) && isStaticPropertyDeclarationOrClassStaticBlock(currentClassElement) && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data)) {
      const { classConstructor, superClassReference, facts } = lexicalEnvironment.data;
      if (facts & 1 /* ClassWasDecorated */) {
        return visitInvalidSuperProperty(node);
      } else if (classConstructor && superClassReference) {
        const name = isElementAccessExpression(node) ? visitNode(node.argumentExpression, visitor, isExpression) : isIdentifier(node.name) ? factory2.createStringLiteralFromNode(node.name) : void 0;
        if (name) {
          const temp = factory2.createTempVariable(
            /*recordTempVariable*/
            void 0
          );
          return factory2.createAssignmentTargetWrapper(
            temp,
            factory2.createReflectSetCall(
              superClassReference,
              name,
              temp,
              classConstructor
            )
          );
        }
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentElement(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node);
    }
    if (isAssignmentExpression(
      node,
      /*excludeCompoundAssignment*/
      true
    )) {
      const left = visitDestructuringAssignmentTarget(node.left);
      const right = visitNode(node.right, visitor, isExpression);
      return factory2.updateBinaryExpression(node, left, node.operatorToken, right);
    }
    return visitDestructuringAssignmentTarget(node);
  }
  function visitAssignmentRestElement(node) {
    if (isLeftHandSideExpression(node.expression)) {
      const expression = visitDestructuringAssignmentTarget(node.expression);
      return factory2.updateSpreadElement(node, expression);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitArrayAssignmentElement(node) {
    if (isArrayBindingOrAssignmentElement(node)) {
      if (isSpreadElement(node)) return visitAssignmentRestElement(node);
      if (!isOmittedExpression(node)) return visitAssignmentElement(node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentProperty(node) {
    const name = visitNode(node.name, visitor, isPropertyName);
    if (isAssignmentExpression(
      node.initializer,
      /*excludeCompoundAssignment*/
      true
    )) {
      const assignmentElement = visitAssignmentElement(node.initializer);
      return factory2.updatePropertyAssignment(node, name, assignmentElement);
    }
    if (isLeftHandSideExpression(node.initializer)) {
      const assignmentElement = visitDestructuringAssignmentTarget(node.initializer);
      return factory2.updatePropertyAssignment(node, name, assignmentElement);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitShorthandAssignmentProperty(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentRestProperty(node) {
    if (isLeftHandSideExpression(node.expression)) {
      const expression = visitDestructuringAssignmentTarget(node.expression);
      return factory2.updateSpreadAssignment(node, expression);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitObjectAssignmentElement(node) {
    Debug.assertNode(node, isObjectBindingOrAssignmentElement);
    if (isSpreadAssignment(node)) return visitAssignmentRestProperty(node);
    if (isShorthandPropertyAssignment(node)) return visitShorthandAssignmentProperty(node);
    if (isPropertyAssignment(node)) return visitAssignmentProperty(node);
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentPattern(node) {
    if (isArrayLiteralExpression(node)) {
      return factory2.updateArrayLiteralExpression(
        node,
        visitNodes2(node.elements, visitArrayAssignmentElement, isExpression)
      );
    } else {
      return factory2.updateObjectLiteralExpression(
        node,
        visitNodes2(node.properties, visitObjectAssignmentElement, isObjectLiteralElementLike)
      );
    }
  }
  function onEmitNode(hint, node, emitCallback) {
    const original = getOriginalNode(node);
    const lex = lexicalEnvironmentMap.get(original);
    if (lex) {
      const savedLexicalEnvironment = lexicalEnvironment;
      const savedPreviousShouldSubstituteThisWithClassThis = previousShouldSubstituteThisWithClassThis;
      lexicalEnvironment = lex;
      previousShouldSubstituteThisWithClassThis = shouldSubstituteThisWithClassThis;
      shouldSubstituteThisWithClassThis = !isClassStaticBlockDeclaration(original) || !(getInternalEmitFlags(original) & 32 /* TransformPrivateStaticElements */);
      previousOnEmitNode(hint, node, emitCallback);
      shouldSubstituteThisWithClassThis = previousShouldSubstituteThisWithClassThis;
      previousShouldSubstituteThisWithClassThis = savedPreviousShouldSubstituteThisWithClassThis;
      lexicalEnvironment = savedLexicalEnvironment;
      return;
    }
    switch (node.kind) {
      case 218 /* FunctionExpression */:
        if (isArrowFunction(original) || getEmitFlags(node) & 524288 /* AsyncFunctionBody */) {
          break;
        }
      case 262 /* FunctionDeclaration */:
      case 176 /* Constructor */:
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 174 /* MethodDeclaration */:
      case 172 /* PropertyDeclaration */: {
        const savedLexicalEnvironment = lexicalEnvironment;
        const savedPreviousShouldSubstituteThisWithClassThis = previousShouldSubstituteThisWithClassThis;
        lexicalEnvironment = void 0;
        previousShouldSubstituteThisWithClassThis = shouldSubstituteThisWithClassThis;
        shouldSubstituteThisWithClassThis = false;
        previousOnEmitNode(hint, node, emitCallback);
        shouldSubstituteThisWithClassThis = previousShouldSubstituteThisWithClassThis;
        previousShouldSubstituteThisWithClassThis = savedPreviousShouldSubstituteThisWithClassThis;
        lexicalEnvironment = savedLexicalEnvironment;
        return;
      }
      case 167 /* ComputedPropertyName */: {
        const savedLexicalEnvironment = lexicalEnvironment;
        const savedShouldSubstituteThisWithClassThis = shouldSubstituteThisWithClassThis;
        lexicalEnvironment = lexicalEnvironment == null ? void 0 : lexicalEnvironment.previous;
        shouldSubstituteThisWithClassThis = previousShouldSubstituteThisWithClassThis;
        previousOnEmitNode(hint, node, emitCallback);
        shouldSubstituteThisWithClassThis = savedShouldSubstituteThisWithClassThis;
        lexicalEnvironment = savedLexicalEnvironment;
        return;
      }
    }
    previousOnEmitNode(hint, node, emitCallback);
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (hint === 1 /* Expression */) {
      return substituteExpression(node);
    }
    return node;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 80 /* Identifier */:
        return substituteExpressionIdentifier(node);
      case 110 /* ThisKeyword */:
        return substituteThisExpression(node);
    }
    return node;
  }
  function substituteThisExpression(node) {
    if (enabledSubstitutions & 2 /* ClassStaticThisOrSuperReference */ && (lexicalEnvironment == null ? void 0 : lexicalEnvironment.data) && !noSubstitution.has(node)) {
      const { facts, classConstructor, classThis } = lexicalEnvironment.data;
      const substituteThis = shouldSubstituteThisWithClassThis ? classThis ?? classConstructor : classConstructor;
      if (substituteThis) {
        return setTextRange(
          setOriginalNode(
            factory2.cloneNode(substituteThis),
            node
          ),
          node
        );
      }
      if (facts & 1 /* ClassWasDecorated */ && legacyDecorators) {
        return factory2.createParenthesizedExpression(factory2.createVoidZero());
      }
    }
    return node;
  }
  function substituteExpressionIdentifier(node) {
    return trySubstituteClassAlias(node) || node;
  }
  function trySubstituteClassAlias(node) {
    if (enabledSubstitutions & 1 /* ClassAliases */) {
      if (resolver.hasNodeCheckFlag(node, 536870912 /* ConstructorReference */)) {
        const declaration = resolver.getReferencedValueDeclaration(node);
        if (declaration) {
          const classAlias = classAliases[declaration.id];
          if (classAlias) {
            const clone = factory2.cloneNode(classAlias);
            setSourceMapRange(clone, node);
            setCommentRange(clone, node);
            return clone;
          }
        }
      }
    }
    return void 0;
  }
}
function createPrivateStaticFieldInitializer(factory2, variableName, initializer) {
  return factory2.createAssignment(
    variableName,
    factory2.createObjectLiteralExpression([
      factory2.createPropertyAssignment("value", initializer || factory2.createVoidZero())
    ])
  );
}
function createPrivateInstanceFieldInitializer(factory2, receiver, initializer, weakMapName) {
  return factory2.createCallExpression(
    factory2.createPropertyAccessExpression(weakMapName, "set"),
    /*typeArguments*/
    void 0,
    [receiver, initializer || factory2.createVoidZero()]
  );
}
function createPrivateInstanceMethodInitializer(factory2, receiver, weakSetName) {
  return factory2.createCallExpression(
    factory2.createPropertyAccessExpression(weakSetName, "add"),
    /*typeArguments*/
    void 0,
    [receiver]
  );
}
function isReservedPrivateName(node) {
  return !isGeneratedPrivateIdentifier(node) && node.escapedText === "#constructor";
}
function isPrivateIdentifierInExpression(node) {
  return isPrivateIdentifier(node.left) && node.operatorToken.kind === 103 /* InKeyword */;
}
function isStaticPropertyDeclaration2(node) {
  return isPropertyDeclaration(node) && hasStaticModifier(node);
}
function isStaticPropertyDeclarationOrClassStaticBlock(node) {
  return isClassStaticBlockDeclaration(node) || isStaticPropertyDeclaration2(node);
}

// src/compiler/transformers/typeSerializer.ts
function createRuntimeTypeSerializer(context) {
  const {
    factory: factory2,
    hoistVariableDeclaration
  } = context;
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
  let currentLexicalScope;
  let currentNameScope;
  return {
    serializeTypeNode: (serializerContext, node) => setSerializerContextAnd(serializerContext, serializeTypeNode, node),
    serializeTypeOfNode: (serializerContext, node, container) => setSerializerContextAnd(serializerContext, serializeTypeOfNode, node, container),
    serializeParameterTypesOfNode: (serializerContext, node, container) => setSerializerContextAnd(serializerContext, serializeParameterTypesOfNode, node, container),
    serializeReturnTypeOfNode: (serializerContext, node) => setSerializerContextAnd(serializerContext, serializeReturnTypeOfNode, node)
  };
  function setSerializerContextAnd(serializerContext, cb, node, arg) {
    const savedCurrentLexicalScope = currentLexicalScope;
    const savedCurrentNameScope = currentNameScope;
    currentLexicalScope = serializerContext.currentLexicalScope;
    currentNameScope = serializerContext.currentNameScope;
    const result = arg === void 0 ? cb(node) : cb(node, arg);
    currentLexicalScope = savedCurrentLexicalScope;
    currentNameScope = savedCurrentNameScope;
    return result;
  }
  function getAccessorTypeNode(node, container) {
    const accessors = getAllAccessorDeclarations(container.members, node);
    return accessors.setAccessor && getSetAccessorTypeAnnotationNode(accessors.setAccessor) || accessors.getAccessor && getEffectiveReturnTypeNode(accessors.getAccessor);
  }
  function serializeTypeOfNode(node, container) {
    switch (node.kind) {
      case 172 /* PropertyDeclaration */:
      case 169 /* Parameter */:
        return serializeTypeNode(node.type);
      case 178 /* SetAccessor */:
      case 177 /* GetAccessor */:
        return serializeTypeNode(getAccessorTypeNode(node, container));
      case 263 /* ClassDeclaration */:
      case 231 /* ClassExpression */:
      case 174 /* MethodDeclaration */:
        return factory2.createIdentifier("Function");
      default:
        return factory2.createVoidZero();
    }
  }
  function serializeParameterTypesOfNode(node, container) {
    const valueDeclaration = isClassLike(node) ? getFirstConstructorWithBody(node) : isFunctionLike(node) && nodeIsPresent(node.body) ? node : void 0;
    const expressions = [];
    if (valueDeclaration) {
      const parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container);
      const numParameters = parameters.length;
      for (let i = 0; i < numParameters; i++) {
        const parameter = parameters[i];
        if (i === 0 && isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
          continue;
        }
        if (parameter.dotDotDotToken) {
          expressions.push(serializeTypeNode(getRestParameterElementType(parameter.type)));
        } else {
          expressions.push(serializeTypeOfNode(parameter, container));
        }
      }
    }
    return factory2.createArrayLiteralExpression(expressions);
  }
  function getParametersOfDecoratedDeclaration(node, container) {
    if (container && node.kind === 177 /* GetAccessor */) {
      const { setAccessor } = getAllAccessorDeclarations(container.members, node);
      if (setAccessor) {
        return setAccessor.parameters;
      }
    }
    return node.parameters;
  }
  function serializeReturnTypeOfNode(node) {
    if (isFunctionLike(node) && node.type) {
      return serializeTypeNode(node.type);
    } else if (isAsyncFunction(node)) {
      return factory2.createIdentifier("Promise");
    }
    return factory2.createVoidZero();
  }
  function serializeTypeNode(node) {
    if (node === void 0) {
      return factory2.createIdentifier("Object");
    }
    node = skipTypeParentheses(node);
    switch (node.kind) {
      case 116 /* VoidKeyword */:
      case 157 /* UndefinedKeyword */:
      case 146 /* NeverKeyword */:
        return factory2.createVoidZero();
      case 184 /* FunctionType */:
      case 185 /* ConstructorType */:
        return factory2.createIdentifier("Function");
      case 188 /* ArrayType */:
      case 189 /* TupleType */:
        return factory2.createIdentifier("Array");
      case 182 /* TypePredicate */:
        return node.assertsModifier ? factory2.createVoidZero() : factory2.createIdentifier("Boolean");
      case 136 /* BooleanKeyword */:
        return factory2.createIdentifier("Boolean");
      case 203 /* TemplateLiteralType */:
      case 154 /* StringKeyword */:
        return factory2.createIdentifier("String");
      case 151 /* ObjectKeyword */:
        return factory2.createIdentifier("Object");
      case 201 /* LiteralType */:
        return serializeLiteralOfLiteralTypeNode(node.literal);
      case 150 /* NumberKeyword */:
        return factory2.createIdentifier("Number");
      case 163 /* BigIntKeyword */:
        return getGlobalConstructor("BigInt", 7 /* ES2020 */);
      case 155 /* SymbolKeyword */:
        return getGlobalConstructor("Symbol", 2 /* ES2015 */);
      case 183 /* TypeReference */:
        return serializeTypeReferenceNode(node);
      case 193 /* IntersectionType */:
        return serializeUnionOrIntersectionConstituents(
          node.types,
          /*isIntersection*/
          true
        );
      case 192 /* UnionType */:
        return serializeUnionOrIntersectionConstituents(
          node.types,
          /*isIntersection*/
          false
        );
      case 194 /* ConditionalType */:
        return serializeUnionOrIntersectionConstituents(
          [node.trueType, node.falseType],
          /*isIntersection*/
          false
        );
      case 198 /* TypeOperator */:
        if (node.operator === 148 /* ReadonlyKeyword */) {
          return serializeTypeNode(node.type);
        }
        break;
      case 186 /* TypeQuery */:
      case 199 /* IndexedAccessType */:
      case 200 /* MappedType */:
      case 187 /* TypeLiteral */:
      case 133 /* AnyKeyword */:
      case 159 /* UnknownKeyword */:
      case 197 /* ThisType */:
      case 205 /* ImportType */:
        break;
      case 312 /* JSDocAllType */:
      case 313 /* JSDocUnknownType */:
      case 317 /* JSDocFunctionType */:
      case 318 /* JSDocVariadicType */:
      case 319 /* JSDocNamepathType */:
        break;
      case 314 /* JSDocNullableType */:
      case 315 /* JSDocNonNullableType */:
      case 316 /* JSDocOptionalType */:
        return serializeTypeNode(node.type);
      default:
        return Debug.failBadSyntaxKind(node);
    }
    return factory2.createIdentifier("Object");
  }
  function serializeLiteralOfLiteralTypeNode(node) {
    switch (node.kind) {
      case 11 /* StringLiteral */:
      case 15 /* NoSubstitutionTemplateLiteral */:
        return factory2.createIdentifier("String");
      case 224 /* PrefixUnaryExpression */: {
        const operand = node.operand;
        switch (operand.kind) {
          case 9 /* NumericLiteral */:
          case 10 /* BigIntLiteral */:
            return serializeLiteralOfLiteralTypeNode(operand);
          default:
            return Debug.failBadSyntaxKind(operand);
        }
      }
      case 9 /* NumericLiteral */:
        return factory2.createIdentifier("Number");
      case 10 /* BigIntLiteral */:
        return getGlobalConstructor("BigInt", 7 /* ES2020 */);
      case 112 /* TrueKeyword */:
      case 97 /* FalseKeyword */:
        return factory2.createIdentifier("Boolean");
      case 106 /* NullKeyword */:
        return factory2.createVoidZero();
      default:
        return Debug.failBadSyntaxKind(node);
    }
  }
  function serializeUnionOrIntersectionConstituents(types, isIntersection) {
    let serializedType;
    for (let typeNode of types) {
      typeNode = skipTypeParentheses(typeNode);
      if (typeNode.kind === 146 /* NeverKeyword */) {
        if (isIntersection) return factory2.createVoidZero();
        continue;
      }
      if (typeNode.kind === 159 /* UnknownKeyword */) {
        if (!isIntersection) return factory2.createIdentifier("Object");
        continue;
      }
      if (typeNode.kind === 133 /* AnyKeyword */) {
        return factory2.createIdentifier("Object");
      }
      if (!strictNullChecks && (isLiteralTypeNode(typeNode) && typeNode.literal.kind === 106 /* NullKeyword */ || typeNode.kind === 157 /* UndefinedKeyword */)) {
        continue;
      }
      const serializedConstituent = serializeTypeNode(typeNode);
      if (isIdentifier(serializedConstituent) && serializedConstituent.escapedText === "Object") {
        return serializedConstituent;
      }
      if (serializedType) {
        if (!equateSerializedTypeNodes(serializedType, serializedConstituent)) {
          return factory2.createIdentifier("Object");
        }
      } else {
        serializedType = serializedConstituent;
      }
    }
    return serializedType ?? factory2.createVoidZero();
  }
  function equateSerializedTypeNodes(left, right) {
    return (
      // temp vars used in fallback
      isGeneratedIdentifier(left) ? isGeneratedIdentifier(right) : (
        // entity names
        isIdentifier(left) ? isIdentifier(right) && left.escapedText === right.escapedText : isPropertyAccessExpression(left) ? isPropertyAccessExpression(right) && equateSerializedTypeNodes(left.expression, right.expression) && equateSerializedTypeNodes(left.name, right.name) : (
          // `void 0`
          isVoidExpression(left) ? isVoidExpression(right) && isNumericLiteral(left.expression) && left.expression.text === "0" && isNumericLiteral(right.expression) && right.expression.text === "0" : (
            // `"undefined"` or `"function"` in `typeof` checks
            isStringLiteral(left) ? isStringLiteral(right) && left.text === right.text : (
              // used in `typeof` checks for fallback
              isTypeOfExpression(left) ? isTypeOfExpression(right) && equateSerializedTypeNodes(left.expression, right.expression) : (
                // parens in `typeof` checks with temps
                isParenthesizedExpression(left) ? isParenthesizedExpression(right) && equateSerializedTypeNodes(left.expression, right.expression) : (
                  // conditionals used in fallback
                  isConditionalExpression(left) ? isConditionalExpression(right) && equateSerializedTypeNodes(left.condition, right.condition) && equateSerializedTypeNodes(left.whenTrue, right.whenTrue) && equateSerializedTypeNodes(left.whenFalse, right.whenFalse) : (
                    // logical binary and assignments used in fallback
                    isBinaryExpression(left) ? isBinaryExpression(right) && left.operatorToken.kind === right.operatorToken.kind && equateSerializedTypeNodes(left.left, right.left) && equateSerializedTypeNodes(left.right, right.right) : false
                  )
                )
              )
            )
          )
        )
      )
    );
  }
  function serializeTypeReferenceNode(node) {
    const kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentNameScope ?? currentLexicalScope);
    switch (kind) {
      case 0 /* Unknown */:
        if (findAncestor(node, (n) => n.parent && isConditionalTypeNode(n.parent) && (n.parent.trueType === n || n.parent.falseType === n))) {
          return factory2.createIdentifier("Object");
        }
        const serialized = serializeEntityNameAsExpressionFallback(node.typeName);
        const temp = factory2.createTempVariable(hoistVariableDeclaration);
        return factory2.createConditionalExpression(
          factory2.createTypeCheck(factory2.createAssignment(temp, serialized), "function"),
          /*questionToken*/
          void 0,
          temp,
          /*colonToken*/
          void 0,
          factory2.createIdentifier("Object")
        );
      case 1 /* TypeWithConstructSignatureAndValue */:
        return serializeEntityNameAsExpression(node.typeName);
      case 2 /* VoidNullableOrNeverType */:
        return factory2.createVoidZero();
      case 4 /* BigIntLikeType */:
        return getGlobalConstructor("BigInt", 7 /* ES2020 */);
      case 6 /* BooleanType */:
        return factory2.createIdentifier("Boolean");
      case 3 /* NumberLikeType */:
        return factory2.createIdentifier("Number");
      case 5 /* StringLikeType */:
        return factory2.createIdentifier("String");
      case 7 /* ArrayLikeType */:
        return factory2.createIdentifier("Array");
      case 8 /* ESSymbolType */:
        return getGlobalConstructor("Symbol", 2 /* ES2015 */);
      case 10 /* TypeWithCallSignature */:
        return factory2.createIdentifier("Function");
      case 9 /* Promise */:
        return factory2.createIdentifier("Promise");
      case 11 /* ObjectType */:
        return factory2.createIdentifier("Object");
      default:
        return Debug.assertNever(kind);
    }
  }
  function createCheckedValue(left, right) {
    return factory2.createLogicalAnd(
      factory2.createStrictInequality(factory2.createTypeOfExpression(left), factory2.createStringLiteral("undefined")),
      right
    );
  }
  function serializeEntityNameAsExpressionFallback(node) {
    if (node.kind === 80 /* Identifier */) {
      const copied = serializeEntityNameAsExpression(node);
      return createCheckedValue(copied, copied);
    }
    if (node.left.kind === 80 /* Identifier */) {
      return createCheckedValue(serializeEntityNameAsExpression(node.left), serializeEntityNameAsExpression(node));
    }
    const left = serializeEntityNameAsExpressionFallback(node.left);
    const temp = factory2.createTempVariable(hoistVariableDeclaration);
    return factory2.createLogicalAnd(
      factory2.createLogicalAnd(
        left.left,
        factory2.createStrictInequality(factory2.createAssignment(temp, left.right), factory2.createVoidZero())
      ),
      factory2.createPropertyAccessExpression(temp, node.right)
    );
  }
  function serializeEntityNameAsExpression(node) {
    switch (node.kind) {
      case 80 /* Identifier */:
        const name = setParent(setTextRange(parseNodeFactory.cloneNode(node), node), node.parent);
        name.original = void 0;
        setParent(name, getParseTreeNode(currentLexicalScope));
        return name;
      case 166 /* QualifiedName */:
        return serializeQualifiedNameAsExpression(node);
    }
  }
  function serializeQualifiedNameAsExpression(node) {
    return factory2.createPropertyAccessExpression(serializeEntityNameAsExpression(node.left), node.right);
  }
  function getGlobalConstructorWithFallback(name) {
    return factory2.createConditionalExpression(
      factory2.createTypeCheck(factory2.createIdentifier(name), "function"),
      /*questionToken*/
      void 0,
      factory2.createIdentifier(name),
      /*colonToken*/
      void 0,
      factory2.createIdentifier("Object")
    );
  }
  function getGlobalConstructor(name, minLanguageVersion) {
    return languageVersion < minLanguageVersion ? getGlobalConstructorWithFallback(name) : factory2.createIdentifier(name);
  }
}

// src/compiler/transformers/legacyDecorators.ts
function transformLegacyDecorators(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    hoistVariableDeclaration
  } = context;
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const previousOnSubstituteNode = context.onSubstituteNode;
  context.onSubstituteNode = onSubstituteNode;
  let classAliases;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    const visited = visitEachChild(node, visitor, context);
    addEmitHelpers(visited, context.readEmitHelpers());
    return visited;
  }
  function modifierVisitor(node) {
    return isDecorator(node) ? void 0 : node;
  }
  function visitor(node) {
    if (!(node.transformFlags & 33554432 /* ContainsDecorators */)) {
      return node;
    }
    switch (node.kind) {
      case 170 /* Decorator */:
        return void 0;
      case 263 /* ClassDeclaration */:
        return visitClassDeclaration(node);
      case 231 /* ClassExpression */:
        return visitClassExpression(node);
      case 176 /* Constructor */:
        return visitConstructorDeclaration(node);
      case 174 /* MethodDeclaration */:
        return visitMethodDeclaration(node);
      case 178 /* SetAccessor */:
        return visitSetAccessorDeclaration(node);
      case 177 /* GetAccessor */:
        return visitGetAccessorDeclaration(node);
      case 172 /* PropertyDeclaration */:
        return visitPropertyDeclaration(node);
      case 169 /* Parameter */:
        return visitParameterDeclaration(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitClassDeclaration(node) {
    if (!(classOrConstructorParameterIsDecorated(
      /*useLegacyDecorators*/
      true,
      node
    ) || childIsDecorated(
      /*useLegacyDecorators*/
      true,
      node
    ))) {
      return visitEachChild(node, visitor, context);
    }
    const statements = classOrConstructorParameterIsDecorated(
      /*useLegacyDecorators*/
      true,
      node
    ) ? transformClassDeclarationWithClassDecorators(node, node.name) : transformClassDeclarationWithoutClassDecorators(node, node.name);
    return singleOrMany(statements);
  }
  function decoratorContainsPrivateIdentifierInExpression(decorator) {
    return !!(decorator.transformFlags & 536870912 /* ContainsPrivateIdentifierInExpression */);
  }
  function parameterDecoratorsContainPrivateIdentifierInExpression(parameterDecorators) {
    return some(parameterDecorators, decoratorContainsPrivateIdentifierInExpression);
  }
  function hasClassElementWithDecoratorContainingPrivateIdentifierInExpression(node) {
    for (const member of node.members) {
      if (!canHaveDecorators(member)) continue;
      const allDecorators = getAllDecoratorsOfClassElement(
        member,
        node,
        /*useLegacyDecorators*/
        true
      );
      if (some(allDecorators == null ? void 0 : allDecorators.decorators, decoratorContainsPrivateIdentifierInExpression)) return true;
      if (some(allDecorators == null ? void 0 : allDecorators.parameters, parameterDecoratorsContainPrivateIdentifierInExpression)) return true;
    }
    return false;
  }
  function transformDecoratorsOfClassElements(node, members) {
    let decorationStatements = [];
    addClassElementDecorationStatements(
      decorationStatements,
      node,
      /*isStatic*/
      false
    );
    addClassElementDecorationStatements(
      decorationStatements,
      node,
      /*isStatic*/
      true
    );
    if (hasClassElementWithDecoratorContainingPrivateIdentifierInExpression(node)) {
      members = setTextRange(
        factory2.createNodeArray([
          ...members,
          factory2.createClassStaticBlockDeclaration(
            factory2.createBlock(
              decorationStatements,
              /*multiLine*/
              true
            )
          )
        ]),
        members
      );
      decorationStatements = void 0;
    }
    return { decorationStatements, members };
  }
  function transformClassDeclarationWithoutClassDecorators(node, name) {
    const modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
    const heritageClauses = visitNodes2(node.heritageClauses, visitor, isHeritageClause);
    let members = visitNodes2(node.members, visitor, isClassElement);
    let decorationStatements = [];
    ({ members, decorationStatements } = transformDecoratorsOfClassElements(node, members));
    const updated = factory2.updateClassDeclaration(
      node,
      modifiers,
      name,
      /*typeParameters*/
      void 0,
      heritageClauses,
      members
    );
    return addRange([updated], decorationStatements);
  }
  function transformClassDeclarationWithClassDecorators(node, name) {
    const isExport = hasSyntacticModifier(node, 32 /* Export */);
    const isDefault = hasSyntacticModifier(node, 2048 /* Default */);
    const modifiers = visitNodes2(node.modifiers, (node2) => isExportOrDefaultModifier(node2) || isDecorator(node2) ? void 0 : node2, isModifierLike);
    const location = moveRangePastModifiers(node);
    const classAlias = getClassAliasIfNeeded(node);
    const declName = languageVersion < 2 /* ES2015 */ ? factory2.getInternalName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    ) : factory2.getLocalName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    );
    const heritageClauses = visitNodes2(node.heritageClauses, visitor, isHeritageClause);
    let members = visitNodes2(node.members, visitor, isClassElement);
    let decorationStatements = [];
    ({ members, decorationStatements } = transformDecoratorsOfClassElements(node, members));
    const assignClassAliasInStaticBlock = languageVersion >= 9 /* ES2022 */ && !!classAlias && some(members, (member) => isPropertyDeclaration(member) && hasSyntacticModifier(member, 256 /* Static */) || isClassStaticBlockDeclaration(member));
    if (assignClassAliasInStaticBlock) {
      members = setTextRange(
        factory2.createNodeArray([
          factory2.createClassStaticBlockDeclaration(
            factory2.createBlock([
              factory2.createExpressionStatement(
                factory2.createAssignment(classAlias, factory2.createThis())
              )
            ])
          ),
          ...members
        ]),
        members
      );
    }
    const classExpression = factory2.createClassExpression(
      modifiers,
      name && isGeneratedIdentifier(name) ? void 0 : name,
      /*typeParameters*/
      void 0,
      heritageClauses,
      members
    );
    setOriginalNode(classExpression, node);
    setTextRange(classExpression, location);
    const varInitializer = classAlias && !assignClassAliasInStaticBlock ? factory2.createAssignment(classAlias, classExpression) : classExpression;
    const varDecl = factory2.createVariableDeclaration(
      declName,
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      varInitializer
    );
    setOriginalNode(varDecl, node);
    const varDeclList = factory2.createVariableDeclarationList([varDecl], 1 /* Let */);
    const varStatement = factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      varDeclList
    );
    setOriginalNode(varStatement, node);
    setTextRange(varStatement, location);
    setCommentRange(varStatement, node);
    const statements = [varStatement];
    addRange(statements, decorationStatements);
    addConstructorDecorationStatement(statements, node);
    if (isExport) {
      if (isDefault) {
        const exportStatement = factory2.createExportDefault(declName);
        statements.push(exportStatement);
      } else {
        const exportStatement = factory2.createExternalModuleExport(factory2.getDeclarationName(node));
        statements.push(exportStatement);
      }
    }
    return statements;
  }
  function visitClassExpression(node) {
    return factory2.updateClassExpression(
      node,
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      node.name,
      /*typeParameters*/
      void 0,
      visitNodes2(node.heritageClauses, visitor, isHeritageClause),
      visitNodes2(node.members, visitor, isClassElement)
    );
  }
  function visitConstructorDeclaration(node) {
    return factory2.updateConstructorDeclaration(
      node,
      visitNodes2(node.modifiers, modifierVisitor, isModifier),
      visitNodes2(node.parameters, visitor, isParameter),
      visitNode(node.body, visitor, isBlock)
    );
  }
  function finishClassElement(updated, original) {
    if (updated !== original) {
      setCommentRange(updated, original);
      setSourceMapRange(updated, moveRangePastModifiers(original));
    }
    return updated;
  }
  function visitMethodDeclaration(node) {
    return finishClassElement(
      factory2.updateMethodDeclaration(
        node,
        visitNodes2(node.modifiers, modifierVisitor, isModifier),
        node.asteriskToken,
        Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
        /*questionToken*/
        void 0,
        /*typeParameters*/
        void 0,
        visitNodes2(node.parameters, visitor, isParameter),
        /*type*/
        void 0,
        visitNode(node.body, visitor, isBlock)
      ),
      node
    );
  }
  function visitGetAccessorDeclaration(node) {
    return finishClassElement(
      factory2.updateGetAccessorDeclaration(
        node,
        visitNodes2(node.modifiers, modifierVisitor, isModifier),
        Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
        visitNodes2(node.parameters, visitor, isParameter),
        /*type*/
        void 0,
        visitNode(node.body, visitor, isBlock)
      ),
      node
    );
  }
  function visitSetAccessorDeclaration(node) {
    return finishClassElement(
      factory2.updateSetAccessorDeclaration(
        node,
        visitNodes2(node.modifiers, modifierVisitor, isModifier),
        Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
        visitNodes2(node.parameters, visitor, isParameter),
        visitNode(node.body, visitor, isBlock)
      ),
      node
    );
  }
  function visitPropertyDeclaration(node) {
    if (node.flags & 33554432 /* Ambient */ || hasSyntacticModifier(node, 128 /* Ambient */)) {
      return void 0;
    }
    return finishClassElement(
      factory2.updatePropertyDeclaration(
        node,
        visitNodes2(node.modifiers, modifierVisitor, isModifier),
        Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)),
        /*questionOrExclamationToken*/
        void 0,
        /*type*/
        void 0,
        visitNode(node.initializer, visitor, isExpression)
      ),
      node
    );
  }
  function visitParameterDeclaration(node) {
    const updated = factory2.updateParameterDeclaration(
      node,
      elideNodes(factory2, node.modifiers),
      node.dotDotDotToken,
      Debug.checkDefined(visitNode(node.name, visitor, isBindingName)),
      /*questionToken*/
      void 0,
      /*type*/
      void 0,
      visitNode(node.initializer, visitor, isExpression)
    );
    if (updated !== node) {
      setCommentRange(updated, node);
      setTextRange(updated, moveRangePastModifiers(node));
      setSourceMapRange(updated, moveRangePastModifiers(node));
      setEmitFlags(updated.name, 64 /* NoTrailingSourceMap */);
    }
    return updated;
  }
  function isSyntheticMetadataDecorator(node) {
    return isCallToHelper(node.expression, "___metadata");
  }
  function transformAllDecoratorsOfDeclaration(allDecorators) {
    if (!allDecorators) {
      return void 0;
    }
    const { false: decorators, true: metadata } = groupBy(allDecorators.decorators, isSyntheticMetadataDecorator);
    const decoratorExpressions = [];
    addRange(decoratorExpressions, map(decorators, transformDecorator));
    addRange(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
    addRange(decoratorExpressions, map(metadata, transformDecorator));
    return decoratorExpressions;
  }
  function addClassElementDecorationStatements(statements, node, isStatic2) {
    addRange(statements, map(generateClassElementDecorationExpressions(node, isStatic2), (expr) => factory2.createExpressionStatement(expr)));
  }
  function isDecoratedClassElement(member, isStaticElement, parent) {
    return nodeOrChildIsDecorated(
      /*useLegacyDecorators*/
      true,
      member,
      parent
    ) && isStaticElement === isStatic(member);
  }
  function getDecoratedClassElements(node, isStatic2) {
    return filter(node.members, (m) => isDecoratedClassElement(m, isStatic2, node));
  }
  function generateClassElementDecorationExpressions(node, isStatic2) {
    const members = getDecoratedClassElements(node, isStatic2);
    let expressions;
    for (const member of members) {
      expressions = append(expressions, generateClassElementDecorationExpression(node, member));
    }
    return expressions;
  }
  function generateClassElementDecorationExpression(node, member) {
    const allDecorators = getAllDecoratorsOfClassElement(
      member,
      node,
      /*useLegacyDecorators*/
      true
    );
    const decoratorExpressions = transformAllDecoratorsOfDeclaration(allDecorators);
    if (!decoratorExpressions) {
      return void 0;
    }
    const prefix = getClassMemberPrefix(node, member);
    const memberName = getExpressionForPropertyName(
      member,
      /*generateNameForComputedPropertyName*/
      !hasSyntacticModifier(member, 128 /* Ambient */)
    );
    const descriptor = isPropertyDeclaration(member) && !hasAccessorModifier(member) ? factory2.createVoidZero() : factory2.createNull();
    const helper = emitHelpers().createDecorateHelper(
      decoratorExpressions,
      prefix,
      memberName,
      descriptor
    );
    setEmitFlags(helper, 3072 /* NoComments */);
    setSourceMapRange(helper, moveRangePastModifiers(member));
    return helper;
  }
  function addConstructorDecorationStatement(statements, node) {
    const expression = generateConstructorDecorationExpression(node);
    if (expression) {
      statements.push(setOriginalNode(factory2.createExpressionStatement(expression), node));
    }
  }
  function generateConstructorDecorationExpression(node) {
    const allDecorators = getAllDecoratorsOfClass(node);
    const decoratorExpressions = transformAllDecoratorsOfDeclaration(allDecorators);
    if (!decoratorExpressions) {
      return void 0;
    }
    const classAlias = classAliases && classAliases[getOriginalNodeId(node)];
    const localName = languageVersion < 2 /* ES2015 */ ? factory2.getInternalName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    ) : factory2.getDeclarationName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      true
    );
    const decorate = emitHelpers().createDecorateHelper(decoratorExpressions, localName);
    const expression = factory2.createAssignment(localName, classAlias ? factory2.createAssignment(classAlias, decorate) : decorate);
    setEmitFlags(expression, 3072 /* NoComments */);
    setSourceMapRange(expression, moveRangePastModifiers(node));
    return expression;
  }
  function transformDecorator(decorator) {
    return Debug.checkDefined(visitNode(decorator.expression, visitor, isExpression));
  }
  function transformDecoratorsOfParameter(decorators, parameterOffset) {
    let expressions;
    if (decorators) {
      expressions = [];
      for (const decorator of decorators) {
        const helper = emitHelpers().createParamHelper(
          transformDecorator(decorator),
          parameterOffset
        );
        setTextRange(helper, decorator.expression);
        setEmitFlags(helper, 3072 /* NoComments */);
        expressions.push(helper);
      }
    }
    return expressions;
  }
  function getExpressionForPropertyName(member, generateNameForComputedPropertyName) {
    const name = member.name;
    if (isPrivateIdentifier(name)) {
      return factory2.createIdentifier("");
    } else if (isComputedPropertyName(name)) {
      return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression) ? factory2.getGeneratedNameForNode(name) : name.expression;
    } else if (isIdentifier(name)) {
      return factory2.createStringLiteral(idText(name));
    } else {
      return factory2.cloneNode(name);
    }
  }
  function enableSubstitutionForClassAliases() {
    if (!classAliases) {
      context.enableSubstitution(80 /* Identifier */);
      classAliases = [];
    }
  }
  function getClassAliasIfNeeded(node) {
    if (resolver.hasNodeCheckFlag(node, 262144 /* ContainsConstructorReference */)) {
      enableSubstitutionForClassAliases();
      const classAlias = factory2.createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? idText(node.name) : "default");
      classAliases[getOriginalNodeId(node)] = classAlias;
      hoistVariableDeclaration(classAlias);
      return classAlias;
    }
  }
  function getClassPrototype(node) {
    return factory2.createPropertyAccessExpression(factory2.getDeclarationName(node), "prototype");
  }
  function getClassMemberPrefix(node, member) {
    return isStatic(member) ? factory2.getDeclarationName(node) : getClassPrototype(node);
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (hint === 1 /* Expression */) {
      return substituteExpression(node);
    }
    return node;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 80 /* Identifier */:
        return substituteExpressionIdentifier(node);
    }
    return node;
  }
  function substituteExpressionIdentifier(node) {
    return trySubstituteClassAlias(node) ?? node;
  }
  function trySubstituteClassAlias(node) {
    if (classAliases) {
      if (resolver.hasNodeCheckFlag(node, 536870912 /* ConstructorReference */)) {
        const declaration = resolver.getReferencedValueDeclaration(node);
        if (declaration) {
          const classAlias = classAliases[declaration.id];
          if (classAlias) {
            const clone = factory2.cloneNode(classAlias);
            setSourceMapRange(clone, node);
            setCommentRange(clone, node);
            return clone;
          }
        }
      }
    }
    return void 0;
  }
}

// src/compiler/transformers/esDecorators.ts
function transformESDecorators(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    startLexicalEnvironment,
    endLexicalEnvironment,
    hoistVariableDeclaration
  } = context;
  const languageVersion = getEmitScriptTarget(context.getCompilerOptions());
  let top;
  let classInfo;
  let classThis;
  let classSuper;
  let pendingExpressions;
  let shouldTransformPrivateStaticElementsInFile;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    top = void 0;
    shouldTransformPrivateStaticElementsInFile = false;
    const visited = visitEachChild(node, visitor, context);
    addEmitHelpers(visited, context.readEmitHelpers());
    if (shouldTransformPrivateStaticElementsInFile) {
      addInternalEmitFlags(visited, 32 /* TransformPrivateStaticElements */);
      shouldTransformPrivateStaticElementsInFile = false;
    }
    return visited;
  }
  function updateState() {
    classInfo = void 0;
    classThis = void 0;
    classSuper = void 0;
    switch (top == null ? void 0 : top.kind) {
      case "class":
        classInfo = top.classInfo;
        break;
      case "class-element":
        classInfo = top.next.classInfo;
        classThis = top.classThis;
        classSuper = top.classSuper;
        break;
      case "name":
        const grandparent = top.next.next.next;
        if ((grandparent == null ? void 0 : grandparent.kind) === "class-element") {
          classInfo = grandparent.next.classInfo;
          classThis = grandparent.classThis;
          classSuper = grandparent.classSuper;
        }
        break;
    }
  }
  function enterClass(classInfo2) {
    top = { kind: "class", next: top, classInfo: classInfo2, savedPendingExpressions: pendingExpressions };
    pendingExpressions = void 0;
    updateState();
  }
  function exitClass() {
    Debug.assert((top == null ? void 0 : top.kind) === "class", "Incorrect value for top.kind.", () => `Expected top.kind to be 'class' but got '${top == null ? void 0 : top.kind}' instead.`);
    pendingExpressions = top.savedPendingExpressions;
    top = top.next;
    updateState();
  }
  function enterClassElement(node) {
    var _a, _b;
    Debug.assert((top == null ? void 0 : top.kind) === "class", "Incorrect value for top.kind.", () => `Expected top.kind to be 'class' but got '${top == null ? void 0 : top.kind}' instead.`);
    top = { kind: "class-element", next: top };
    if (isClassStaticBlockDeclaration(node) || isPropertyDeclaration(node) && hasStaticModifier(node)) {
      top.classThis = (_a = top.next.classInfo) == null ? void 0 : _a.classThis;
      top.classSuper = (_b = top.next.classInfo) == null ? void 0 : _b.classSuper;
    }
    updateState();
  }
  function exitClassElement() {
    var _a;
    Debug.assert((top == null ? void 0 : top.kind) === "class-element", "Incorrect value for top.kind.", () => `Expected top.kind to be 'class-element' but got '${top == null ? void 0 : top.kind}' instead.`);
    Debug.assert(((_a = top.next) == null ? void 0 : _a.kind) === "class", "Incorrect value for top.next.kind.", () => {
      var _a2;
      return `Expected top.next.kind to be 'class' but got '${(_a2 = top.next) == null ? void 0 : _a2.kind}' instead.`;
    });
    top = top.next;
    updateState();
  }
  function enterName() {
    Debug.assert((top == null ? void 0 : top.kind) === "class-element", "Incorrect value for top.kind.", () => `Expected top.kind to be 'class-element' but got '${top == null ? void 0 : top.kind}' instead.`);
    top = { kind: "name", next: top };
    updateState();
  }
  function exitName() {
    Debug.assert((top == null ? void 0 : top.kind) === "name", "Incorrect value for top.kind.", () => `Expected top.kind to be 'name' but got '${top == null ? void 0 : top.kind}' instead.`);
    top = top.next;
    updateState();
  }
  function enterOther() {
    if ((top == null ? void 0 : top.kind) === "other") {
      Debug.assert(!pendingExpressions);
      top.depth++;
    } else {
      top = { kind: "other", next: top, depth: 0, savedPendingExpressions: pendingExpressions };
      pendingExpressions = void 0;
      updateState();
    }
  }
  function exitOther() {
    Debug.assert((top == null ? void 0 : top.kind) === "other", "Incorrect value for top.kind.", () => `Expected top.kind to be 'other' but got '${top == null ? void 0 : top.kind}' instead.`);
    if (top.depth > 0) {
      Debug.assert(!pendingExpressions);
      top.depth--;
    } else {
      pendingExpressions = top.savedPendingExpressions;
      top = top.next;
      updateState();
    }
  }
  function shouldVisitNode(node) {
    return !!(node.transformFlags & 33554432 /* ContainsDecorators */) || !!classThis && !!(node.transformFlags & 16384 /* ContainsLexicalThis */) || !!classThis && !!classSuper && !!(node.transformFlags & 134217728 /* ContainsLexicalSuper */);
  }
  function visitor(node) {
    if (!shouldVisitNode(node)) {
      return node;
    }
    switch (node.kind) {
      case 170 /* Decorator */:
        return Debug.fail("Use `modifierVisitor` instead.");
      case 263 /* ClassDeclaration */:
        return visitClassDeclaration(node);
      case 231 /* ClassExpression */:
        return visitClassExpression(node);
      case 176 /* Constructor */:
      case 172 /* PropertyDeclaration */:
      case 175 /* ClassStaticBlockDeclaration */:
        return Debug.fail("Not supported outside of a class. Use 'classElementVisitor' instead.");
      case 169 /* Parameter */:
        return visitParameterDeclaration(node);
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(
          node,
          /*discarded*/
          false
        );
      case 303 /* PropertyAssignment */:
        return visitPropertyAssignment(node);
      case 260 /* VariableDeclaration */:
        return visitVariableDeclaration(node);
      case 208 /* BindingElement */:
        return visitBindingElement(node);
      case 277 /* ExportAssignment */:
        return visitExportAssignment(node);
      case 110 /* ThisKeyword */:
        return visitThisExpression(node);
      case 248 /* ForStatement */:
        return visitForStatement(node);
      case 244 /* ExpressionStatement */:
        return visitExpressionStatement(node);
      case 355 /* CommaListExpression */:
        return visitCommaListExpression(
          node,
          /*discarded*/
          false
        );
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(
          node,
          /*discarded*/
          false
        );
      case 354 /* PartiallyEmittedExpression */:
        return visitPartiallyEmittedExpression(
          node,
          /*discarded*/
          false
        );
      case 213 /* CallExpression */:
        return visitCallExpression(node);
      case 215 /* TaggedTemplateExpression */:
        return visitTaggedTemplateExpression(node);
      case 224 /* PrefixUnaryExpression */:
      case 225 /* PostfixUnaryExpression */:
        return visitPreOrPostfixUnaryExpression(
          node,
          /*discarded*/
          false
        );
      case 211 /* PropertyAccessExpression */:
        return visitPropertyAccessExpression(node);
      case 212 /* ElementAccessExpression */:
        return visitElementAccessExpression(node);
      case 167 /* ComputedPropertyName */:
        return visitComputedPropertyName(node);
      case 174 /* MethodDeclaration */:
      case 178 /* SetAccessor */:
      case 177 /* GetAccessor */:
      case 218 /* FunctionExpression */:
      case 262 /* FunctionDeclaration */: {
        enterOther();
        const result = visitEachChild(node, fallbackVisitor, context);
        exitOther();
        return result;
      }
      default:
        return visitEachChild(node, fallbackVisitor, context);
    }
  }
  function fallbackVisitor(node) {
    switch (node.kind) {
      case 170 /* Decorator */:
        return void 0;
      default:
        return visitor(node);
    }
  }
  function modifierVisitor(node) {
    switch (node.kind) {
      case 170 /* Decorator */:
        return void 0;
      default:
        return node;
    }
  }
  function classElementVisitor(node) {
    switch (node.kind) {
      case 176 /* Constructor */:
        return visitConstructorDeclaration(node);
      case 174 /* MethodDeclaration */:
        return visitMethodDeclaration(node);
      case 177 /* GetAccessor */:
        return visitGetAccessorDeclaration(node);
      case 178 /* SetAccessor */:
        return visitSetAccessorDeclaration(node);
      case 172 /* PropertyDeclaration */:
        return visitPropertyDeclaration(node);
      case 175 /* ClassStaticBlockDeclaration */:
        return visitClassStaticBlockDeclaration(node);
      default:
        return visitor(node);
    }
  }
  function discardedValueVisitor(node) {
    switch (node.kind) {
      case 224 /* PrefixUnaryExpression */:
      case 225 /* PostfixUnaryExpression */:
        return visitPreOrPostfixUnaryExpression(
          node,
          /*discarded*/
          true
        );
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(
          node,
          /*discarded*/
          true
        );
      case 355 /* CommaListExpression */:
        return visitCommaListExpression(
          node,
          /*discarded*/
          true
        );
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(
          node,
          /*discarded*/
          true
        );
      default:
        return visitor(node);
    }
  }
  function getHelperVariableName(node) {
    let declarationName = node.name && isIdentifier(node.name) && !isGeneratedIdentifier(node.name) ? idText(node.name) : node.name && isPrivateIdentifier(node.name) && !isGeneratedIdentifier(node.name) ? idText(node.name).slice(1) : node.name && isStringLiteral(node.name) && isIdentifierText(node.name.text, 99 /* ESNext */) ? node.name.text : isClassLike(node) ? "class" : "member";
    if (isGetAccessor(node)) declarationName = `get_${declarationName}`;
    if (isSetAccessor(node)) declarationName = `set_${declarationName}`;
    if (node.name && isPrivateIdentifier(node.name)) declarationName = `private_${declarationName}`;
    if (isStatic(node)) declarationName = `static_${declarationName}`;
    return "_" + declarationName;
  }
  function createHelperVariable(node, suffix) {
    return factory2.createUniqueName(`${getHelperVariableName(node)}_${suffix}`, 16 /* Optimistic */ | 8 /* ReservedInNestedScopes */);
  }
  function createLet(name, initializer) {
    return factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      factory2.createVariableDeclarationList([
        factory2.createVariableDeclaration(
          name,
          /*exclamationToken*/
          void 0,
          /*type*/
          void 0,
          initializer
        )
      ], 1 /* Let */)
    );
  }
  function createClassInfo(node) {
    const metadataReference = factory2.createUniqueName("_metadata", 16 /* Optimistic */ | 32 /* FileLevel */);
    let instanceMethodExtraInitializersName;
    let staticMethodExtraInitializersName;
    let hasStaticInitializers = false;
    let hasNonAmbientInstanceFields = false;
    let hasStaticPrivateClassElements = false;
    let classThis2;
    let pendingStaticInitializers;
    let pendingInstanceInitializers;
    if (nodeIsDecorated(
      /*useLegacyDecorators*/
      false,
      node
    )) {
      const needsUniqueClassThis = some(node.members, (member) => (isPrivateIdentifierClassElementDeclaration(member) || isAutoAccessorPropertyDeclaration(member)) && hasStaticModifier(member));
      classThis2 = factory2.createUniqueName(
        "_classThis",
        needsUniqueClassThis ? 16 /* Optimistic */ | 8 /* ReservedInNestedScopes */ : 16 /* Optimistic */ | 32 /* FileLevel */
      );
    }
    for (const member of node.members) {
      if (isMethodOrAccessor(member) && nodeOrChildIsDecorated(
        /*useLegacyDecorators*/
        false,
        member,
        node
      )) {
        if (hasStaticModifier(member)) {
          if (!staticMethodExtraInitializersName) {
            staticMethodExtraInitializersName = factory2.createUniqueName("_staticExtraInitializers", 16 /* Optimistic */ | 32 /* FileLevel */);
            const initializer = emitHelpers().createRunInitializersHelper(classThis2 ?? factory2.createThis(), staticMethodExtraInitializersName);
            setSourceMapRange(initializer, node.name ?? moveRangePastDecorators(node));
            pendingStaticInitializers ?? (pendingStaticInitializers = []);
            pendingStaticInitializers.push(initializer);
          }
        } else {
          if (!instanceMethodExtraInitializersName) {
            instanceMethodExtraInitializersName = factory2.createUniqueName("_instanceExtraInitializers", 16 /* Optimistic */ | 32 /* FileLevel */);
            const initializer = emitHelpers().createRunInitializersHelper(factory2.createThis(), instanceMethodExtraInitializersName);
            setSourceMapRange(initializer, node.name ?? moveRangePastDecorators(node));
            pendingInstanceInitializers ?? (pendingInstanceInitializers = []);
            pendingInstanceInitializers.push(initializer);
          }
          instanceMethodExtraInitializersName ?? (instanceMethodExtraInitializersName = factory2.createUniqueName("_instanceExtraInitializers", 16 /* Optimistic */ | 32 /* FileLevel */));
        }
      }
      if (isClassStaticBlockDeclaration(member)) {
        if (!isClassNamedEvaluationHelperBlock(member)) {
          hasStaticInitializers = true;
        }
      } else if (isPropertyDeclaration(member)) {
        if (hasStaticModifier(member)) {
          hasStaticInitializers || (hasStaticInitializers = !!member.initializer || hasDecorators(member));
        } else {
          hasNonAmbientInstanceFields || (hasNonAmbientInstanceFields = !isAmbientPropertyDeclaration(member));
        }
      }
      if ((isPrivateIdentifierClassElementDeclaration(member) || isAutoAccessorPropertyDeclaration(member)) && hasStaticModifier(member)) {
        hasStaticPrivateClassElements = true;
      }
      if (staticMethodExtraInitializersName && instanceMethodExtraInitializersName && hasStaticInitializers && hasNonAmbientInstanceFields && hasStaticPrivateClassElements) {
        break;
      }
    }
    return {
      class: node,
      classThis: classThis2,
      metadataReference,
      instanceMethodExtraInitializersName,
      staticMethodExtraInitializersName,
      hasStaticInitializers,
      hasNonAmbientInstanceFields,
      hasStaticPrivateClassElements,
      pendingStaticInitializers,
      pendingInstanceInitializers
    };
  }
  function transformClassLike(node) {
    startLexicalEnvironment();
    if (!classHasDeclaredOrExplicitlyAssignedName(node) && classOrConstructorParameterIsDecorated(
      /*useLegacyDecorators*/
      false,
      node
    )) {
      node = injectClassNamedEvaluationHelperBlockIfMissing(context, node, factory2.createStringLiteral(""));
    }
    const classReference = factory2.getLocalName(
      node,
      /*allowComments*/
      false,
      /*allowSourceMaps*/
      false,
      /*ignoreAssignedName*/
      true
    );
    const classInfo2 = createClassInfo(node);
    const classDefinitionStatements = [];
    let leadingBlockStatements;
    let trailingBlockStatements;
    let syntheticConstructor;
    let heritageClauses;
    let shouldTransformPrivateStaticElementsInClass = false;
    const classDecorators = transformAllDecoratorsOfDeclaration(getAllDecoratorsOfClass(node));
    if (classDecorators) {
      classInfo2.classDecoratorsName = factory2.createUniqueName("_classDecorators", 16 /* Optimistic */ | 32 /* FileLevel */);
      classInfo2.classDescriptorName = factory2.createUniqueName("_classDescriptor", 16 /* Optimistic */ | 32 /* FileLevel */);
      classInfo2.classExtraInitializersName = factory2.createUniqueName("_classExtraInitializers", 16 /* Optimistic */ | 32 /* FileLevel */);
      Debug.assertIsDefined(classInfo2.classThis);
      classDefinitionStatements.push(
        createLet(classInfo2.classDecoratorsName, factory2.createArrayLiteralExpression(classDecorators)),
        createLet(classInfo2.classDescriptorName),
        createLet(classInfo2.classExtraInitializersName, factory2.createArrayLiteralExpression()),
        createLet(classInfo2.classThis)
      );
      if (classInfo2.hasStaticPrivateClassElements) {
        shouldTransformPrivateStaticElementsInClass = true;
        shouldTransformPrivateStaticElementsInFile = true;
      }
    }
    const extendsClause = getHeritageClause(node.heritageClauses, 96 /* ExtendsKeyword */);
    const extendsElement = extendsClause && firstOrUndefined(extendsClause.types);
    const extendsExpression = extendsElement && visitNode(extendsElement.expression, visitor, isExpression);
    if (extendsExpression) {
      classInfo2.classSuper = factory2.createUniqueName("_classSuper", 16 /* Optimistic */ | 32 /* FileLevel */);
      const unwrapped = skipOuterExpressions(extendsExpression);
      const safeExtendsExpression = isClassExpression(unwrapped) && !unwrapped.name || isFunctionExpression(unwrapped) && !unwrapped.name || isArrowFunction(unwrapped) ? factory2.createComma(factory2.createNumericLiteral(0), extendsExpression) : extendsExpression;
      classDefinitionStatements.push(createLet(classInfo2.classSuper, safeExtendsExpression));
      const updatedExtendsElement = factory2.updateExpressionWithTypeArguments(
        extendsElement,
        classInfo2.classSuper,
        /*typeArguments*/
        void 0
      );
      const updatedExtendsClause = factory2.updateHeritageClause(extendsClause, [updatedExtendsElement]);
      heritageClauses = factory2.createNodeArray([updatedExtendsClause]);
    }
    const renamedClassThis = classInfo2.classThis ?? factory2.createThis();
    enterClass(classInfo2);
    leadingBlockStatements = append(leadingBlockStatements, createMetadata(classInfo2.metadataReference, classInfo2.classSuper));
    let members = node.members;
    members = visitNodes2(members, (node2) => isConstructorDeclaration(node2) ? node2 : classElementVisitor(node2), isClassElement);
    members = visitNodes2(members, (node2) => isConstructorDeclaration(node2) ? classElementVisitor(node2) : node2, isClassElement);
    if (pendingExpressions) {
      let outerThis;
      for (let expression of pendingExpressions) {
        expression = visitNode(expression, function thisVisitor(node2) {
          if (!(node2.transformFlags & 16384 /* ContainsLexicalThis */)) {
            return node2;
          }
          switch (node2.kind) {
            case 110 /* ThisKeyword */:
              if (!outerThis) {
                outerThis = factory2.createUniqueName("_outerThis", 16 /* Optimistic */);
                classDefinitionStatements.unshift(createLet(outerThis, factory2.createThis()));
              }
              return outerThis;
            default:
              return visitEachChild(node2, thisVisitor, context);
          }
        }, isExpression);
        const statement = factory2.createExpressionStatement(expression);
        leadingBlockStatements = append(leadingBlockStatements, statement);
      }
      pendingExpressions = void 0;
    }
    exitClass();
    if (some(classInfo2.pendingInstanceInitializers) && !getFirstConstructorWithBody(node)) {
      const initializerStatements = prepareConstructor(node, classInfo2);
      if (initializerStatements) {
        const extendsClauseElement = getEffectiveBaseTypeNode(node);
        const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== 106 /* NullKeyword */);
        const constructorStatements = [];
        if (isDerivedClass) {
          const spreadArguments = factory2.createSpreadElement(factory2.createIdentifier("arguments"));
          const superCall = factory2.createCallExpression(
            factory2.createSuper(),
            /*typeArguments*/
            void 0,
            [spreadArguments]
          );
          constructorStatements.push(factory2.createExpressionStatement(superCall));
        }
        addRange(constructorStatements, initializerStatements);
        const constructorBody = factory2.createBlock(
          constructorStatements,
          /*multiLine*/
          true
        );
        syntheticConstructor = factory2.createConstructorDeclaration(
          /*modifiers*/
          void 0,
          [],
          constructorBody
        );
      }
    }
    if (classInfo2.staticMethodExtraInitializersName) {
      classDefinitionStatements.push(
        createLet(classInfo2.staticMethodExtraInitializersName, factory2.createArrayLiteralExpression())
      );
    }
    if (classInfo2.instanceMethodExtraInitializersName) {
      classDefinitionStatements.push(
        createLet(classInfo2.instanceMethodExtraInitializersName, factory2.createArrayLiteralExpression())
      );
    }
    if (classInfo2.memberInfos) {
      forEachEntry(classInfo2.memberInfos, (memberInfo, member) => {
        if (isStatic(member)) {
          classDefinitionStatements.push(createLet(memberInfo.memberDecoratorsName));
          if (memberInfo.memberInitializersName) {
            classDefinitionStatements.push(createLet(memberInfo.memberInitializersName, factory2.createArrayLiteralExpression()));
          }
          if (memberInfo.memberExtraInitializersName) {
            classDefinitionStatements.push(createLet(memberInfo.memberExtraInitializersName, factory2.createArrayLiteralExpression()));
          }
          if (memberInfo.memberDescriptorName) {
            classDefinitionStatements.push(createLet(memberInfo.memberDescriptorName));
          }
        }
      });
    }
    if (classInfo2.memberInfos) {
      forEachEntry(classInfo2.memberInfos, (memberInfo, member) => {
        if (!isStatic(member)) {
          classDefinitionStatements.push(createLet(memberInfo.memberDecoratorsName));
          if (memberInfo.memberInitializersName) {
            classDefinitionStatements.push(createLet(memberInfo.memberInitializersName, factory2.createArrayLiteralExpression()));
          }
          if (memberInfo.memberExtraInitializersName) {
            classDefinitionStatements.push(createLet(memberInfo.memberExtraInitializersName, factory2.createArrayLiteralExpression()));
          }
          if (memberInfo.memberDescriptorName) {
            classDefinitionStatements.push(createLet(memberInfo.memberDescriptorName));
          }
        }
      });
    }
    leadingBlockStatements = addRange(leadingBlockStatements, classInfo2.staticNonFieldDecorationStatements);
    leadingBlockStatements = addRange(leadingBlockStatements, classInfo2.nonStaticNonFieldDecorationStatements);
    leadingBlockStatements = addRange(leadingBlockStatements, classInfo2.staticFieldDecorationStatements);
    leadingBlockStatements = addRange(leadingBlockStatements, classInfo2.nonStaticFieldDecorationStatements);
    if (classInfo2.classDescriptorName && classInfo2.classDecoratorsName && classInfo2.classExtraInitializersName && classInfo2.classThis) {
      leadingBlockStatements ?? (leadingBlockStatements = []);
      const valueProperty = factory2.createPropertyAssignment("value", renamedClassThis);
      const classDescriptor = factory2.createObjectLiteralExpression([valueProperty]);
      const classDescriptorAssignment = factory2.createAssignment(classInfo2.classDescriptorName, classDescriptor);
      const classNameReference = factory2.createPropertyAccessExpression(renamedClassThis, "name");
      const esDecorateHelper2 = emitHelpers().createESDecorateHelper(
        factory2.createNull(),
        classDescriptorAssignment,
        classInfo2.classDecoratorsName,
        { kind: "class", name: classNameReference, metadata: classInfo2.metadataReference },
        factory2.createNull(),
        classInfo2.classExtraInitializersName
      );
      const esDecorateStatement = factory2.createExpressionStatement(esDecorateHelper2);
      setSourceMapRange(esDecorateStatement, moveRangePastDecorators(node));
      leadingBlockStatements.push(esDecorateStatement);
      const classDescriptorValueReference = factory2.createPropertyAccessExpression(classInfo2.classDescriptorName, "value");
      const classThisAssignment = factory2.createAssignment(classInfo2.classThis, classDescriptorValueReference);
      const classReferenceAssignment = factory2.createAssignment(classReference, classThisAssignment);
      leadingBlockStatements.push(factory2.createExpressionStatement(classReferenceAssignment));
    }
    leadingBlockStatements.push(createSymbolMetadata(renamedClassThis, classInfo2.metadataReference));
    if (some(classInfo2.pendingStaticInitializers)) {
      for (const initializer of classInfo2.pendingStaticInitializers) {
        const initializerStatement = factory2.createExpressionStatement(initializer);
        setSourceMapRange(initializerStatement, getSourceMapRange(initializer));
        trailingBlockStatements = append(trailingBlockStatements, initializerStatement);
      }
      classInfo2.pendingStaticInitializers = void 0;
    }
    if (classInfo2.classExtraInitializersName) {
      const runClassInitializersHelper = emitHelpers().createRunInitializersHelper(renamedClassThis, classInfo2.classExtraInitializersName);
      const runClassInitializersStatement = factory2.createExpressionStatement(runClassInitializersHelper);
      setSourceMapRange(runClassInitializersStatement, node.name ?? moveRangePastDecorators(node));
      trailingBlockStatements = append(trailingBlockStatements, runClassInitializersStatement);
    }
    if (leadingBlockStatements && trailingBlockStatements && !classInfo2.hasStaticInitializers) {
      addRange(leadingBlockStatements, trailingBlockStatements);
      trailingBlockStatements = void 0;
    }
    const leadingStaticBlock = leadingBlockStatements && factory2.createClassStaticBlockDeclaration(factory2.createBlock(
      leadingBlockStatements,
      /*multiLine*/
      true
    ));
    if (leadingStaticBlock && shouldTransformPrivateStaticElementsInClass) {
      setInternalEmitFlags(leadingStaticBlock, 32 /* TransformPrivateStaticElements */);
    }
    const trailingStaticBlock = trailingBlockStatements && factory2.createClassStaticBlockDeclaration(factory2.createBlock(
      trailingBlockStatements,
      /*multiLine*/
      true
    ));
    if (leadingStaticBlock || syntheticConstructor || trailingStaticBlock) {
      const newMembers = [];
      const existingNamedEvaluationHelperBlockIndex = members.findIndex(isClassNamedEvaluationHelperBlock);
      if (leadingStaticBlock) {
        addRange(newMembers, members, 0, existingNamedEvaluationHelperBlockIndex + 1);
        newMembers.push(leadingStaticBlock);
        addRange(newMembers, members, existingNamedEvaluationHelperBlockIndex + 1);
      } else {
        addRange(newMembers, members);
      }
      if (syntheticConstructor) {
        newMembers.push(syntheticConstructor);
      }
      if (trailingStaticBlock) {
        newMembers.push(trailingStaticBlock);
      }
      members = setTextRange(factory2.createNodeArray(newMembers), members);
    }
    const lexicalEnvironment = endLexicalEnvironment();
    let classExpression;
    if (classDecorators) {
      classExpression = factory2.createClassExpression(
        /*modifiers*/
        void 0,
        /*name*/
        void 0,
        /*typeParameters*/
        void 0,
        heritageClauses,
        members
      );
      if (classInfo2.classThis) {
        classExpression = injectClassThisAssignmentIfMissing(factory2, classExpression, classInfo2.classThis);
      }
      const classReferenceDeclaration = factory2.createVariableDeclaration(
        classReference,
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        classExpression
      );
      const classReferenceVarDeclList = factory2.createVariableDeclarationList([classReferenceDeclaration]);
      const returnExpr = classInfo2.classThis ? factory2.createAssignment(classReference, classInfo2.classThis) : classReference;
      classDefinitionStatements.push(
        factory2.createVariableStatement(
          /*modifiers*/
          void 0,
          classReferenceVarDeclList
        ),
        factory2.createReturnStatement(returnExpr)
      );
    } else {
      classExpression = factory2.createClassExpression(
        /*modifiers*/
        void 0,
        node.name,
        /*typeParameters*/
        void 0,
        heritageClauses,
        members
      );
      classDefinitionStatements.push(factory2.createReturnStatement(classExpression));
    }
    if (shouldTransformPrivateStaticElementsInClass) {
      addInternalEmitFlags(classExpression, 32 /* TransformPrivateStaticElements */);
      for (const member of classExpression.members) {
        if ((isPrivateIdentifierClassElementDeclaration(member) || isAutoAccessorPropertyDeclaration(member)) && hasStaticModifier(member)) {
          addInternalEmitFlags(member, 32 /* TransformPrivateStaticElements */);
        }
      }
    }
    setOriginalNode(classExpression, node);
    return factory2.createImmediatelyInvokedArrowFunction(factory2.mergeLexicalEnvironment(classDefinitionStatements, lexicalEnvironment));
  }
  function isDecoratedClassLike(node) {
    return classOrConstructorParameterIsDecorated(
      /*useLegacyDecorators*/
      false,
      node
    ) || childIsDecorated(
      /*useLegacyDecorators*/
      false,
      node
    );
  }
  function visitClassDeclaration(node) {
    if (isDecoratedClassLike(node)) {
      const statements = [];
      const originalClass = getOriginalNode(node, isClassLike) ?? node;
      const className = originalClass.name ? factory2.createStringLiteralFromNode(originalClass.name) : factory2.createStringLiteral("default");
      const isExport = hasSyntacticModifier(node, 32 /* Export */);
      const isDefault = hasSyntacticModifier(node, 2048 /* Default */);
      if (!node.name) {
        node = injectClassNamedEvaluationHelperBlockIfMissing(context, node, className);
      }
      if (isExport && isDefault) {
        const iife = transformClassLike(node);
        if (node.name) {
          const varDecl = factory2.createVariableDeclaration(
            factory2.getLocalName(node),
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            iife
          );
          setOriginalNode(varDecl, node);
          const varDecls = factory2.createVariableDeclarationList([varDecl], 1 /* Let */);
          const varStatement = factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            varDecls
          );
          statements.push(varStatement);
          const exportStatement = factory2.createExportDefault(factory2.getDeclarationName(node));
          setOriginalNode(exportStatement, node);
          setCommentRange(exportStatement, getCommentRange(node));
          setSourceMapRange(exportStatement, moveRangePastDecorators(node));
          statements.push(exportStatement);
        } else {
          const exportStatement = factory2.createExportDefault(iife);
          setOriginalNode(exportStatement, node);
          setCommentRange(exportStatement, getCommentRange(node));
          setSourceMapRange(exportStatement, moveRangePastDecorators(node));
          statements.push(exportStatement);
        }
      } else {
        Debug.assertIsDefined(node.name, "A class declaration that is not a default export must have a name.");
        const iife = transformClassLike(node);
        const modifierVisitorNoExport = isExport ? (node2) => isExportModifier(node2) ? void 0 : modifierVisitor(node2) : modifierVisitor;
        const modifiers = visitNodes2(node.modifiers, modifierVisitorNoExport, isModifier);
        const declName = factory2.getLocalName(
          node,
          /*allowComments*/
          false,
          /*allowSourceMaps*/
          true
        );
        const varDecl = factory2.createVariableDeclaration(
          declName,
          /*exclamationToken*/
          void 0,
          /*type*/
          void 0,
          iife
        );
        setOriginalNode(varDecl, node);
        const varDecls = factory2.createVariableDeclarationList([varDecl], 1 /* Let */);
        const varStatement = factory2.createVariableStatement(modifiers, varDecls);
        setOriginalNode(varStatement, node);
        setCommentRange(varStatement, getCommentRange(node));
        statements.push(varStatement);
        if (isExport) {
          const exportStatement = factory2.createExternalModuleExport(declName);
          setOriginalNode(exportStatement, node);
          statements.push(exportStatement);
        }
      }
      return singleOrMany(statements);
    } else {
      const modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
      const heritageClauses = visitNodes2(node.heritageClauses, visitor, isHeritageClause);
      enterClass(
        /*classInfo*/
        void 0
      );
      const members = visitNodes2(node.members, classElementVisitor, isClassElement);
      exitClass();
      return factory2.updateClassDeclaration(
        node,
        modifiers,
        node.name,
        /*typeParameters*/
        void 0,
        heritageClauses,
        members
      );
    }
  }
  function visitClassExpression(node) {
    if (isDecoratedClassLike(node)) {
      const iife = transformClassLike(node);
      setOriginalNode(iife, node);
      return iife;
    } else {
      const modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
      const heritageClauses = visitNodes2(node.heritageClauses, visitor, isHeritageClause);
      enterClass(
        /*classInfo*/
        void 0
      );
      const members = visitNodes2(node.members, classElementVisitor, isClassElement);
      exitClass();
      return factory2.updateClassExpression(
        node,
        modifiers,
        node.name,
        /*typeParameters*/
        void 0,
        heritageClauses,
        members
      );
    }
  }
  function prepareConstructor(_parent, classInfo2) {
    if (some(classInfo2.pendingInstanceInitializers)) {
      const statements = [];
      statements.push(
        factory2.createExpressionStatement(
          factory2.inlineExpressions(classInfo2.pendingInstanceInitializers)
        )
      );
      classInfo2.pendingInstanceInitializers = void 0;
      return statements;
    }
  }
  function transformConstructorBodyWorker(statementsOut, statementsIn, statementOffset, superPath, superPathDepth, initializerStatements) {
    const superStatementIndex = superPath[superPathDepth];
    const superStatement = statementsIn[superStatementIndex];
    addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, statementOffset, superStatementIndex - statementOffset));
    if (isTryStatement(superStatement)) {
      const tryBlockStatements = [];
      transformConstructorBodyWorker(
        tryBlockStatements,
        superStatement.tryBlock.statements,
        /*statementOffset*/
        0,
        superPath,
        superPathDepth + 1,
        initializerStatements
      );
      const tryBlockStatementsArray = factory2.createNodeArray(tryBlockStatements);
      setTextRange(tryBlockStatementsArray, superStatement.tryBlock.statements);
      statementsOut.push(factory2.updateTryStatement(
        superStatement,
        factory2.updateBlock(superStatement.tryBlock, tryBlockStatements),
        visitNode(superStatement.catchClause, visitor, isCatchClause),
        visitNode(superStatement.finallyBlock, visitor, isBlock)
      ));
    } else {
      addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, superStatementIndex, 1));
      addRange(statementsOut, initializerStatements);
    }
    addRange(statementsOut, visitNodes2(statementsIn, visitor, isStatement, superStatementIndex + 1));
  }
  function visitConstructorDeclaration(node) {
    enterClassElement(node);
    const modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
    const parameters = visitNodes2(node.parameters, visitor, isParameter);
    let body;
    if (node.body && classInfo) {
      const initializerStatements = prepareConstructor(classInfo.class, classInfo);
      if (initializerStatements) {
        const statements = [];
        const nonPrologueStart = factory2.copyPrologue(
          node.body.statements,
          statements,
          /*ensureUseStrict*/
          false,
          visitor
        );
        const superStatementIndices = findSuperStatementIndexPath(node.body.statements, nonPrologueStart);
        if (superStatementIndices.length > 0) {
          transformConstructorBodyWorker(statements, node.body.statements, nonPrologueStart, superStatementIndices, 0, initializerStatements);
        } else {
          addRange(statements, initializerStatements);
          addRange(statements, visitNodes2(node.body.statements, visitor, isStatement));
        }
        body = factory2.createBlock(
          statements,
          /*multiLine*/
          true
        );
        setOriginalNode(body, node.body);
        setTextRange(body, node.body);
      }
    }
    body ?? (body = visitNode(node.body, visitor, isBlock));
    exitClassElement();
    return factory2.updateConstructorDeclaration(node, modifiers, parameters, body);
  }
  function finishClassElement(updated, original) {
    if (updated !== original) {
      setCommentRange(updated, original);
      setSourceMapRange(updated, moveRangePastDecorators(original));
    }
    return updated;
  }
  function partialTransformClassElement(member, classInfo2, createDescriptor) {
    let referencedName;
    let name;
    let initializersName;
    let extraInitializersName;
    let thisArg;
    let descriptorName;
    if (!classInfo2) {
      const modifiers2 = visitNodes2(member.modifiers, modifierVisitor, isModifier);
      enterName();
      name = visitPropertyName(member.name);
      exitName();
      return { modifiers: modifiers2, referencedName, name, initializersName, descriptorName, thisArg };
    }
    const memberDecorators = transformAllDecoratorsOfDeclaration(getAllDecoratorsOfClassElement(
      member,
      classInfo2.class,
      /*useLegacyDecorators*/
      false
    ));
    const modifiers = visitNodes2(member.modifiers, modifierVisitor, isModifier);
    if (memberDecorators) {
      const memberDecoratorsName = createHelperVariable(member, "decorators");
      const memberDecoratorsArray = factory2.createArrayLiteralExpression(memberDecorators);
      const memberDecoratorsAssignment = factory2.createAssignment(memberDecoratorsName, memberDecoratorsArray);
      const memberInfo = { memberDecoratorsName };
      classInfo2.memberInfos ?? (classInfo2.memberInfos = /* @__PURE__ */ new Map());
      classInfo2.memberInfos.set(member, memberInfo);
      pendingExpressions ?? (pendingExpressions = []);
      pendingExpressions.push(memberDecoratorsAssignment);
      const statements = isMethodOrAccessor(member) || isAutoAccessorPropertyDeclaration(member) ? isStatic(member) ? classInfo2.staticNonFieldDecorationStatements ?? (classInfo2.staticNonFieldDecorationStatements = []) : classInfo2.nonStaticNonFieldDecorationStatements ?? (classInfo2.nonStaticNonFieldDecorationStatements = []) : isPropertyDeclaration(member) && !isAutoAccessorPropertyDeclaration(member) ? isStatic(member) ? classInfo2.staticFieldDecorationStatements ?? (classInfo2.staticFieldDecorationStatements = []) : classInfo2.nonStaticFieldDecorationStatements ?? (classInfo2.nonStaticFieldDecorationStatements = []) : Debug.fail();
      const kind = isGetAccessorDeclaration(member) ? "getter" : isSetAccessorDeclaration(member) ? "setter" : isMethodDeclaration(member) ? "method" : isAutoAccessorPropertyDeclaration(member) ? "accessor" : isPropertyDeclaration(member) ? "field" : Debug.fail();
      let propertyName;
      if (isIdentifier(member.name) || isPrivateIdentifier(member.name)) {
        propertyName = { computed: false, name: member.name };
      } else if (isPropertyNameLiteral(member.name)) {
        propertyName = { computed: true, name: factory2.createStringLiteralFromNode(member.name) };
      } else {
        const expression = member.name.expression;
        if (isPropertyNameLiteral(expression) && !isIdentifier(expression)) {
          propertyName = { computed: true, name: factory2.createStringLiteralFromNode(expression) };
        } else {
          enterName();
          ({ referencedName, name } = visitReferencedPropertyName(member.name));
          propertyName = { computed: true, name: referencedName };
          exitName();
        }
      }
      const context2 = {
        kind,
        name: propertyName,
        static: isStatic(member),
        private: isPrivateIdentifier(member.name),
        access: {
          // 15.7.3 CreateDecoratorAccessObject (kind, name)
          // 2. If _kind_ is ~field~, ~method~, ~accessor~, or ~getter~, then ...
          get: isPropertyDeclaration(member) || isGetAccessorDeclaration(member) || isMethodDeclaration(member),
          // 3. If _kind_ is ~field~, ~accessor~, or ~setter~, then ...
          set: isPropertyDeclaration(member) || isSetAccessorDeclaration(member)
        },
        metadata: classInfo2.metadataReference
      };
      if (isMethodOrAccessor(member)) {
        const methodExtraInitializersName = isStatic(member) ? classInfo2.staticMethodExtraInitializersName : classInfo2.instanceMethodExtraInitializersName;
        Debug.assertIsDefined(methodExtraInitializersName);
        let descriptor;
        if (isPrivateIdentifierClassElementDeclaration(member) && createDescriptor) {
          descriptor = createDescriptor(member, visitNodes2(modifiers, (node) => tryCast(node, isAsyncModifier), isModifier));
          memberInfo.memberDescriptorName = descriptorName = createHelperVariable(member, "descriptor");
          descriptor = factory2.createAssignment(descriptorName, descriptor);
        }
        const esDecorateExpression = emitHelpers().createESDecorateHelper(factory2.createThis(), descriptor ?? factory2.createNull(), memberDecoratorsName, context2, factory2.createNull(), methodExtraInitializersName);
        const esDecorateStatement = factory2.createExpressionStatement(esDecorateExpression);
        setSourceMapRange(esDecorateStatement, moveRangePastDecorators(member));
        statements.push(esDecorateStatement);
      } else if (isPropertyDeclaration(member)) {
        initializersName = memberInfo.memberInitializersName ?? (memberInfo.memberInitializersName = createHelperVariable(member, "initializers"));
        extraInitializersName = memberInfo.memberExtraInitializersName ?? (memberInfo.memberExtraInitializersName = createHelperVariable(member, "extraInitializers"));
        if (isStatic(member)) {
          thisArg = classInfo2.classThis;
        }
        let descriptor;
        if (isPrivateIdentifierClassElementDeclaration(member) && hasAccessorModifier(member) && createDescriptor) {
          descriptor = createDescriptor(
            member,
            /*modifiers*/
            void 0
          );
          memberInfo.memberDescriptorName = descriptorName = createHelperVariable(member, "descriptor");
          descriptor = factory2.createAssignment(descriptorName, descriptor);
        }
        const esDecorateExpression = emitHelpers().createESDecorateHelper(
          isAutoAccessorPropertyDeclaration(member) ? factory2.createThis() : factory2.createNull(),
          descriptor ?? factory2.createNull(),
          memberDecoratorsName,
          context2,
          initializersName,
          extraInitializersName
        );
        const esDecorateStatement = factory2.createExpressionStatement(esDecorateExpression);
        setSourceMapRange(esDecorateStatement, moveRangePastDecorators(member));
        statements.push(esDecorateStatement);
      }
    }
    if (name === void 0) {
      enterName();
      name = visitPropertyName(member.name);
      exitName();
    }
    if (!some(modifiers) && (isMethodDeclaration(member) || isPropertyDeclaration(member))) {
      setEmitFlags(name, 1024 /* NoLeadingComments */);
    }
    return { modifiers, referencedName, name, initializersName, extraInitializersName, descriptorName, thisArg };
  }
  function visitMethodDeclaration(node) {
    enterClassElement(node);
    const { modifiers, name, descriptorName } = partialTransformClassElement(node, classInfo, createMethodDescriptorObject);
    if (descriptorName) {
      exitClassElement();
      return finishClassElement(createMethodDescriptorForwarder(modifiers, name, descriptorName), node);
    } else {
      const parameters = visitNodes2(node.parameters, visitor, isParameter);
      const body = visitNode(node.body, visitor, isBlock);
      exitClassElement();
      return finishClassElement(factory2.updateMethodDeclaration(
        node,
        modifiers,
        node.asteriskToken,
        name,
        /*questionToken*/
        void 0,
        /*typeParameters*/
        void 0,
        parameters,
        /*type*/
        void 0,
        body
      ), node);
    }
  }
  function visitGetAccessorDeclaration(node) {
    enterClassElement(node);
    const { modifiers, name, descriptorName } = partialTransformClassElement(node, classInfo, createGetAccessorDescriptorObject);
    if (descriptorName) {
      exitClassElement();
      return finishClassElement(createGetAccessorDescriptorForwarder(modifiers, name, descriptorName), node);
    } else {
      const parameters = visitNodes2(node.parameters, visitor, isParameter);
      const body = visitNode(node.body, visitor, isBlock);
      exitClassElement();
      return finishClassElement(factory2.updateGetAccessorDeclaration(
        node,
        modifiers,
        name,
        parameters,
        /*type*/
        void 0,
        body
      ), node);
    }
  }
  function visitSetAccessorDeclaration(node) {
    enterClassElement(node);
    const { modifiers, name, descriptorName } = partialTransformClassElement(node, classInfo, createSetAccessorDescriptorObject);
    if (descriptorName) {
      exitClassElement();
      return finishClassElement(createSetAccessorDescriptorForwarder(modifiers, name, descriptorName), node);
    } else {
      const parameters = visitNodes2(node.parameters, visitor, isParameter);
      const body = visitNode(node.body, visitor, isBlock);
      exitClassElement();
      return finishClassElement(factory2.updateSetAccessorDeclaration(node, modifiers, name, parameters, body), node);
    }
  }
  function visitClassStaticBlockDeclaration(node) {
    enterClassElement(node);
    let result;
    if (isClassNamedEvaluationHelperBlock(node)) {
      result = visitEachChild(node, visitor, context);
    } else if (isClassThisAssignmentBlock(node)) {
      const savedClassThis = classThis;
      classThis = void 0;
      result = visitEachChild(node, visitor, context);
      classThis = savedClassThis;
    } else {
      node = visitEachChild(node, visitor, context);
      result = node;
      if (classInfo) {
        classInfo.hasStaticInitializers = true;
        if (some(classInfo.pendingStaticInitializers)) {
          const statements = [];
          for (const initializer of classInfo.pendingStaticInitializers) {
            const initializerStatement = factory2.createExpressionStatement(initializer);
            setSourceMapRange(initializerStatement, getSourceMapRange(initializer));
            statements.push(initializerStatement);
          }
          const body = factory2.createBlock(
            statements,
            /*multiLine*/
            true
          );
          const staticBlock = factory2.createClassStaticBlockDeclaration(body);
          result = [staticBlock, result];
          classInfo.pendingStaticInitializers = void 0;
        }
      }
    }
    exitClassElement();
    return result;
  }
  function visitPropertyDeclaration(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.initializer));
    }
    enterClassElement(node);
    Debug.assert(!isAmbientPropertyDeclaration(node), "Not yet implemented.");
    const { modifiers, name, initializersName, extraInitializersName, descriptorName, thisArg } = partialTransformClassElement(node, classInfo, hasAccessorModifier(node) ? createAccessorPropertyDescriptorObject : void 0);
    startLexicalEnvironment();
    let initializer = visitNode(node.initializer, visitor, isExpression);
    if (initializersName) {
      initializer = emitHelpers().createRunInitializersHelper(
        thisArg ?? factory2.createThis(),
        initializersName,
        initializer ?? factory2.createVoidZero()
      );
    }
    if (isStatic(node) && classInfo && initializer) {
      classInfo.hasStaticInitializers = true;
    }
    const declarations = endLexicalEnvironment();
    if (some(declarations)) {
      initializer = factory2.createImmediatelyInvokedArrowFunction([
        ...declarations,
        factory2.createReturnStatement(initializer)
      ]);
    }
    if (classInfo) {
      if (isStatic(node)) {
        initializer = injectPendingInitializers(
          classInfo,
          /*isStatic*/
          true,
          initializer
        );
        if (extraInitializersName) {
          classInfo.pendingStaticInitializers ?? (classInfo.pendingStaticInitializers = []);
          classInfo.pendingStaticInitializers.push(
            emitHelpers().createRunInitializersHelper(
              classInfo.classThis ?? factory2.createThis(),
              extraInitializersName
            )
          );
        }
      } else {
        initializer = injectPendingInitializers(
          classInfo,
          /*isStatic*/
          false,
          initializer
        );
        if (extraInitializersName) {
          classInfo.pendingInstanceInitializers ?? (classInfo.pendingInstanceInitializers = []);
          classInfo.pendingInstanceInitializers.push(
            emitHelpers().createRunInitializersHelper(
              factory2.createThis(),
              extraInitializersName
            )
          );
        }
      }
    }
    exitClassElement();
    if (hasAccessorModifier(node) && descriptorName) {
      const commentRange = getCommentRange(node);
      const sourceMapRange = getSourceMapRange(node);
      const name2 = node.name;
      let getterName = name2;
      let setterName = name2;
      if (isComputedPropertyName(name2) && !isSimpleInlineableExpression(name2.expression)) {
        const cacheAssignment = findComputedPropertyNameCacheAssignment(name2);
        if (cacheAssignment) {
          getterName = factory2.updateComputedPropertyName(name2, visitNode(name2.expression, visitor, isExpression));
          setterName = factory2.updateComputedPropertyName(name2, cacheAssignment.left);
        } else {
          const temp = factory2.createTempVariable(hoistVariableDeclaration);
          setSourceMapRange(temp, name2.expression);
          const expression = visitNode(name2.expression, visitor, isExpression);
          const assignment = factory2.createAssignment(temp, expression);
          setSourceMapRange(assignment, name2.expression);
          getterName = factory2.updateComputedPropertyName(name2, assignment);
          setterName = factory2.updateComputedPropertyName(name2, temp);
        }
      }
      const modifiersWithoutAccessor = visitNodes2(modifiers, (node2) => node2.kind !== 129 /* AccessorKeyword */ ? node2 : void 0, isModifier);
      const backingField = createAccessorPropertyBackingField(factory2, node, modifiersWithoutAccessor, initializer);
      setOriginalNode(backingField, node);
      setEmitFlags(backingField, 3072 /* NoComments */);
      setSourceMapRange(backingField, sourceMapRange);
      setSourceMapRange(backingField.name, node.name);
      const getter = createGetAccessorDescriptorForwarder(modifiersWithoutAccessor, getterName, descriptorName);
      setOriginalNode(getter, node);
      setCommentRange(getter, commentRange);
      setSourceMapRange(getter, sourceMapRange);
      const setter = createSetAccessorDescriptorForwarder(modifiersWithoutAccessor, setterName, descriptorName);
      setOriginalNode(setter, node);
      setEmitFlags(setter, 3072 /* NoComments */);
      setSourceMapRange(setter, sourceMapRange);
      return [backingField, getter, setter];
    }
    return finishClassElement(factory2.updatePropertyDeclaration(
      node,
      modifiers,
      name,
      /*questionOrExclamationToken*/
      void 0,
      /*type*/
      void 0,
      initializer
    ), node);
  }
  function visitThisExpression(node) {
    return classThis ?? node;
  }
  function visitCallExpression(node) {
    if (isSuperProperty(node.expression) && classThis) {
      const expression = visitNode(node.expression, visitor, isExpression);
      const argumentsList = visitNodes2(node.arguments, visitor, isExpression);
      const invocation = factory2.createFunctionCallCall(expression, classThis, argumentsList);
      setOriginalNode(invocation, node);
      setTextRange(invocation, node);
      return invocation;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitTaggedTemplateExpression(node) {
    if (isSuperProperty(node.tag) && classThis) {
      const tag = visitNode(node.tag, visitor, isExpression);
      const boundTag = factory2.createFunctionBindCall(tag, classThis, []);
      setOriginalNode(boundTag, node);
      setTextRange(boundTag, node);
      const template = visitNode(node.template, visitor, isTemplateLiteral);
      return factory2.updateTaggedTemplateExpression(
        node,
        boundTag,
        /*typeArguments*/
        void 0,
        template
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitPropertyAccessExpression(node) {
    if (isSuperProperty(node) && isIdentifier(node.name) && classThis && classSuper) {
      const propertyName = factory2.createStringLiteralFromNode(node.name);
      const superProperty = factory2.createReflectGetCall(classSuper, propertyName, classThis);
      setOriginalNode(superProperty, node.expression);
      setTextRange(superProperty, node.expression);
      return superProperty;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitElementAccessExpression(node) {
    if (isSuperProperty(node) && classThis && classSuper) {
      const propertyName = visitNode(node.argumentExpression, visitor, isExpression);
      const superProperty = factory2.createReflectGetCall(classSuper, propertyName, classThis);
      setOriginalNode(superProperty, node.expression);
      setTextRange(superProperty, node.expression);
      return superProperty;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitParameterDeclaration(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.initializer));
    }
    const updated = factory2.updateParameterDeclaration(
      node,
      /*modifiers*/
      void 0,
      node.dotDotDotToken,
      visitNode(node.name, visitor, isBindingName),
      /*questionToken*/
      void 0,
      /*type*/
      void 0,
      visitNode(node.initializer, visitor, isExpression)
    );
    if (updated !== node) {
      setCommentRange(updated, node);
      setTextRange(updated, moveRangePastModifiers(node));
      setSourceMapRange(updated, moveRangePastModifiers(node));
      setEmitFlags(updated.name, 64 /* NoTrailingSourceMap */);
    }
    return updated;
  }
  function isAnonymousClassNeedingAssignedName(node) {
    return isClassExpression(node) && !node.name && isDecoratedClassLike(node);
  }
  function canIgnoreEmptyStringLiteralInAssignedName(node) {
    const innerExpression = skipOuterExpressions(node);
    return isClassExpression(innerExpression) && !innerExpression.name && !classOrConstructorParameterIsDecorated(
      /*useLegacyDecorators*/
      false,
      innerExpression
    );
  }
  function visitForStatement(node) {
    return factory2.updateForStatement(
      node,
      visitNode(node.initializer, discardedValueVisitor, isForInitializer),
      visitNode(node.condition, visitor, isExpression),
      visitNode(node.incrementor, discardedValueVisitor, isExpression),
      visitIterationBody(node.statement, visitor, context)
    );
  }
  function visitExpressionStatement(node) {
    return visitEachChild(node, discardedValueVisitor, context);
  }
  function visitBinaryExpression(node, discarded) {
    if (isDestructuringAssignment(node)) {
      const left = visitAssignmentPattern(node.left);
      const right = visitNode(node.right, visitor, isExpression);
      return factory2.updateBinaryExpression(node, left, node.operatorToken, right);
    }
    if (isAssignmentExpression(node)) {
      if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
        node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.right));
        return visitEachChild(node, visitor, context);
      }
      if (isSuperProperty(node.left) && classThis && classSuper) {
        let setterName = isElementAccessExpression(node.left) ? visitNode(node.left.argumentExpression, visitor, isExpression) : isIdentifier(node.left.name) ? factory2.createStringLiteralFromNode(node.left.name) : void 0;
        if (setterName) {
          let expression = visitNode(node.right, visitor, isExpression);
          if (isCompoundAssignment(node.operatorToken.kind)) {
            let getterName = setterName;
            if (!isSimpleInlineableExpression(setterName)) {
              getterName = factory2.createTempVariable(hoistVariableDeclaration);
              setterName = factory2.createAssignment(getterName, setterName);
            }
            const superPropertyGet = factory2.createReflectGetCall(
              classSuper,
              getterName,
              classThis
            );
            setOriginalNode(superPropertyGet, node.left);
            setTextRange(superPropertyGet, node.left);
            expression = factory2.createBinaryExpression(
              superPropertyGet,
              getNonAssignmentOperatorForCompoundAssignment(node.operatorToken.kind),
              expression
            );
            setTextRange(expression, node);
          }
          const temp = discarded ? void 0 : factory2.createTempVariable(hoistVariableDeclaration);
          if (temp) {
            expression = factory2.createAssignment(temp, expression);
            setTextRange(temp, node);
          }
          expression = factory2.createReflectSetCall(
            classSuper,
            setterName,
            expression,
            classThis
          );
          setOriginalNode(expression, node);
          setTextRange(expression, node);
          if (temp) {
            expression = factory2.createComma(expression, temp);
            setTextRange(expression, node);
          }
          return expression;
        }
      }
    }
    if (node.operatorToken.kind === 28 /* CommaToken */) {
      const left = visitNode(node.left, discardedValueVisitor, isExpression);
      const right = visitNode(node.right, discarded ? discardedValueVisitor : visitor, isExpression);
      return factory2.updateBinaryExpression(node, left, node.operatorToken, right);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitPreOrPostfixUnaryExpression(node, discarded) {
    if (node.operator === 46 /* PlusPlusToken */ || node.operator === 47 /* MinusMinusToken */) {
      const operand = skipParentheses(node.operand);
      if (isSuperProperty(operand) && classThis && classSuper) {
        let setterName = isElementAccessExpression(operand) ? visitNode(operand.argumentExpression, visitor, isExpression) : isIdentifier(operand.name) ? factory2.createStringLiteralFromNode(operand.name) : void 0;
        if (setterName) {
          let getterName = setterName;
          if (!isSimpleInlineableExpression(setterName)) {
            getterName = factory2.createTempVariable(hoistVariableDeclaration);
            setterName = factory2.createAssignment(getterName, setterName);
          }
          let expression = factory2.createReflectGetCall(classSuper, getterName, classThis);
          setOriginalNode(expression, node);
          setTextRange(expression, node);
          const temp = discarded ? void 0 : factory2.createTempVariable(hoistVariableDeclaration);
          expression = expandPreOrPostfixIncrementOrDecrementExpression(factory2, node, expression, hoistVariableDeclaration, temp);
          expression = factory2.createReflectSetCall(classSuper, setterName, expression, classThis);
          setOriginalNode(expression, node);
          setTextRange(expression, node);
          if (temp) {
            expression = factory2.createComma(expression, temp);
            setTextRange(expression, node);
          }
          return expression;
        }
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCommaListExpression(node, discarded) {
    const elements = discarded ? visitCommaListElements(node.elements, discardedValueVisitor) : visitCommaListElements(node.elements, visitor, discardedValueVisitor);
    return factory2.updateCommaListExpression(node, elements);
  }
  function visitReferencedPropertyName(node) {
    if (isPropertyNameLiteral(node) || isPrivateIdentifier(node)) {
      const referencedName2 = factory2.createStringLiteralFromNode(node);
      const name2 = visitNode(node, visitor, isPropertyName);
      return { referencedName: referencedName2, name: name2 };
    }
    if (isPropertyNameLiteral(node.expression) && !isIdentifier(node.expression)) {
      const referencedName2 = factory2.createStringLiteralFromNode(node.expression);
      const name2 = visitNode(node, visitor, isPropertyName);
      return { referencedName: referencedName2, name: name2 };
    }
    const referencedName = factory2.getGeneratedNameForNode(node);
    hoistVariableDeclaration(referencedName);
    const key = emitHelpers().createPropKeyHelper(visitNode(node.expression, visitor, isExpression));
    const assignment = factory2.createAssignment(referencedName, key);
    const name = factory2.updateComputedPropertyName(node, injectPendingExpressions(assignment));
    return { referencedName, name };
  }
  function visitPropertyName(node) {
    if (isComputedPropertyName(node)) {
      return visitComputedPropertyName(node);
    }
    return visitNode(node, visitor, isPropertyName);
  }
  function visitComputedPropertyName(node) {
    let expression = visitNode(node.expression, visitor, isExpression);
    if (!isSimpleInlineableExpression(expression)) {
      expression = injectPendingExpressions(expression);
    }
    return factory2.updateComputedPropertyName(node, expression);
  }
  function visitPropertyAssignment(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.initializer));
    }
    return visitEachChild(node, visitor, context);
  }
  function visitVariableDeclaration(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.initializer));
    }
    return visitEachChild(node, visitor, context);
  }
  function visitBindingElement(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.initializer));
    }
    return visitEachChild(node, visitor, context);
  }
  function visitDestructuringAssignmentTarget(node) {
    if (isObjectLiteralExpression(node) || isArrayLiteralExpression(node)) {
      return visitAssignmentPattern(node);
    }
    if (isSuperProperty(node) && classThis && classSuper) {
      const propertyName = isElementAccessExpression(node) ? visitNode(node.argumentExpression, visitor, isExpression) : isIdentifier(node.name) ? factory2.createStringLiteralFromNode(node.name) : void 0;
      if (propertyName) {
        const paramName = factory2.createTempVariable(
          /*recordTempVariable*/
          void 0
        );
        const expression = factory2.createAssignmentTargetWrapper(
          paramName,
          factory2.createReflectSetCall(
            classSuper,
            propertyName,
            paramName,
            classThis
          )
        );
        setOriginalNode(expression, node);
        setTextRange(expression, node);
        return expression;
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentElement(node) {
    if (isAssignmentExpression(
      node,
      /*excludeCompoundAssignment*/
      true
    )) {
      if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
        node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.right));
      }
      const assignmentTarget = visitDestructuringAssignmentTarget(node.left);
      const initializer = visitNode(node.right, visitor, isExpression);
      return factory2.updateBinaryExpression(node, assignmentTarget, node.operatorToken, initializer);
    } else {
      return visitDestructuringAssignmentTarget(node);
    }
  }
  function visitAssignmentRestElement(node) {
    if (isLeftHandSideExpression(node.expression)) {
      const expression = visitDestructuringAssignmentTarget(node.expression);
      return factory2.updateSpreadElement(node, expression);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitArrayAssignmentElement(node) {
    Debug.assertNode(node, isArrayBindingOrAssignmentElement);
    if (isSpreadElement(node)) return visitAssignmentRestElement(node);
    if (!isOmittedExpression(node)) return visitAssignmentElement(node);
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentProperty(node) {
    const name = visitNode(node.name, visitor, isPropertyName);
    if (isAssignmentExpression(
      node.initializer,
      /*excludeCompoundAssignment*/
      true
    )) {
      const assignmentElement = visitAssignmentElement(node.initializer);
      return factory2.updatePropertyAssignment(node, name, assignmentElement);
    }
    if (isLeftHandSideExpression(node.initializer)) {
      const assignmentElement = visitDestructuringAssignmentTarget(node.initializer);
      return factory2.updatePropertyAssignment(node, name, assignmentElement);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitShorthandAssignmentProperty(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.objectAssignmentInitializer));
    }
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentRestProperty(node) {
    if (isLeftHandSideExpression(node.expression)) {
      const expression = visitDestructuringAssignmentTarget(node.expression);
      return factory2.updateSpreadAssignment(node, expression);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitObjectAssignmentElement(node) {
    Debug.assertNode(node, isObjectBindingOrAssignmentElement);
    if (isSpreadAssignment(node)) return visitAssignmentRestProperty(node);
    if (isShorthandPropertyAssignment(node)) return visitShorthandAssignmentProperty(node);
    if (isPropertyAssignment(node)) return visitAssignmentProperty(node);
    return visitEachChild(node, visitor, context);
  }
  function visitAssignmentPattern(node) {
    if (isArrayLiteralExpression(node)) {
      const elements = visitNodes2(node.elements, visitArrayAssignmentElement, isExpression);
      return factory2.updateArrayLiteralExpression(node, elements);
    } else {
      const properties = visitNodes2(node.properties, visitObjectAssignmentElement, isObjectLiteralElementLike);
      return factory2.updateObjectLiteralExpression(node, properties);
    }
  }
  function visitExportAssignment(node) {
    if (isNamedEvaluation(node, isAnonymousClassNeedingAssignedName)) {
      node = transformNamedEvaluation(context, node, canIgnoreEmptyStringLiteralInAssignedName(node.expression));
    }
    return visitEachChild(node, visitor, context);
  }
  function visitParenthesizedExpression(node, discarded) {
    const visitorFunc = discarded ? discardedValueVisitor : visitor;
    const expression = visitNode(node.expression, visitorFunc, isExpression);
    return factory2.updateParenthesizedExpression(node, expression);
  }
  function visitPartiallyEmittedExpression(node, discarded) {
    const visitorFunc = discarded ? discardedValueVisitor : visitor;
    const expression = visitNode(node.expression, visitorFunc, isExpression);
    return factory2.updatePartiallyEmittedExpression(node, expression);
  }
  function injectPendingExpressionsCommon(pendingExpressions2, expression) {
    if (some(pendingExpressions2)) {
      if (expression) {
        if (isParenthesizedExpression(expression)) {
          pendingExpressions2.push(expression.expression);
          expression = factory2.updateParenthesizedExpression(expression, factory2.inlineExpressions(pendingExpressions2));
        } else {
          pendingExpressions2.push(expression);
          expression = factory2.inlineExpressions(pendingExpressions2);
        }
      } else {
        expression = factory2.inlineExpressions(pendingExpressions2);
      }
    }
    return expression;
  }
  function injectPendingExpressions(expression) {
    const result = injectPendingExpressionsCommon(pendingExpressions, expression);
    Debug.assertIsDefined(result);
    if (result !== expression) {
      pendingExpressions = void 0;
    }
    return result;
  }
  function injectPendingInitializers(classInfo2, isStatic2, expression) {
    const result = injectPendingExpressionsCommon(isStatic2 ? classInfo2.pendingStaticInitializers : classInfo2.pendingInstanceInitializers, expression);
    if (result !== expression) {
      if (isStatic2) {
        classInfo2.pendingStaticInitializers = void 0;
      } else {
        classInfo2.pendingInstanceInitializers = void 0;
      }
    }
    return result;
  }
  function transformAllDecoratorsOfDeclaration(allDecorators) {
    if (!allDecorators) {
      return void 0;
    }
    const decoratorExpressions = [];
    addRange(decoratorExpressions, map(allDecorators.decorators, transformDecorator));
    return decoratorExpressions;
  }
  function transformDecorator(decorator) {
    const expression = visitNode(decorator.expression, visitor, isExpression);
    setEmitFlags(expression, 3072 /* NoComments */);
    const innerExpression = skipOuterExpressions(expression);
    if (isAccessExpression(innerExpression)) {
      const { target, thisArg } = factory2.createCallBinding(
        expression,
        hoistVariableDeclaration,
        languageVersion,
        /*cacheIdentifiers*/
        true
      );
      return factory2.restoreOuterExpressions(expression, factory2.createFunctionBindCall(target, thisArg, []));
    }
    return expression;
  }
  function createDescriptorMethod(original, name, modifiers, asteriskToken, kind, parameters, body) {
    const func = factory2.createFunctionExpression(
      modifiers,
      asteriskToken,
      /*name*/
      void 0,
      /*typeParameters*/
      void 0,
      parameters,
      /*type*/
      void 0,
      body ?? factory2.createBlock([])
    );
    setOriginalNode(func, original);
    setSourceMapRange(func, moveRangePastDecorators(original));
    setEmitFlags(func, 3072 /* NoComments */);
    const prefix = kind === "get" || kind === "set" ? kind : void 0;
    const functionName = factory2.createStringLiteralFromNode(
      name,
      /*isSingleQuote*/
      void 0
    );
    const namedFunction = emitHelpers().createSetFunctionNameHelper(func, functionName, prefix);
    const method = factory2.createPropertyAssignment(factory2.createIdentifier(kind), namedFunction);
    setOriginalNode(method, original);
    setSourceMapRange(method, moveRangePastDecorators(original));
    setEmitFlags(method, 3072 /* NoComments */);
    return method;
  }
  function createMethodDescriptorObject(node, modifiers) {
    return factory2.createObjectLiteralExpression([
      createDescriptorMethod(
        node,
        node.name,
        modifiers,
        node.asteriskToken,
        "value",
        visitNodes2(node.parameters, visitor, isParameter),
        visitNode(node.body, visitor, isBlock)
      )
    ]);
  }
  function createGetAccessorDescriptorObject(node, modifiers) {
    return factory2.createObjectLiteralExpression([
      createDescriptorMethod(
        node,
        node.name,
        modifiers,
        /*asteriskToken*/
        void 0,
        "get",
        [],
        visitNode(node.body, visitor, isBlock)
      )
    ]);
  }
  function createSetAccessorDescriptorObject(node, modifiers) {
    return factory2.createObjectLiteralExpression([
      createDescriptorMethod(
        node,
        node.name,
        modifiers,
        /*asteriskToken*/
        void 0,
        "set",
        visitNodes2(node.parameters, visitor, isParameter),
        visitNode(node.body, visitor, isBlock)
      )
    ]);
  }
  function createAccessorPropertyDescriptorObject(node, modifiers) {
    return factory2.createObjectLiteralExpression([
      createDescriptorMethod(
        node,
        node.name,
        modifiers,
        /*asteriskToken*/
        void 0,
        "get",
        [],
        factory2.createBlock([
          factory2.createReturnStatement(
            factory2.createPropertyAccessExpression(
              factory2.createThis(),
              factory2.getGeneratedPrivateNameForNode(node.name)
            )
          )
        ])
      ),
      createDescriptorMethod(
        node,
        node.name,
        modifiers,
        /*asteriskToken*/
        void 0,
        "set",
        [factory2.createParameterDeclaration(
          /*modifiers*/
          void 0,
          /*dotDotDotToken*/
          void 0,
          "value"
        )],
        factory2.createBlock([
          factory2.createExpressionStatement(
            factory2.createAssignment(
              factory2.createPropertyAccessExpression(
                factory2.createThis(),
                factory2.getGeneratedPrivateNameForNode(node.name)
              ),
              factory2.createIdentifier("value")
            )
          )
        ])
      )
    ]);
  }
  function createMethodDescriptorForwarder(modifiers, name, descriptorName) {
    modifiers = visitNodes2(modifiers, (node) => isStaticModifier(node) ? node : void 0, isModifier);
    return factory2.createGetAccessorDeclaration(
      modifiers,
      name,
      [],
      /*type*/
      void 0,
      factory2.createBlock([
        factory2.createReturnStatement(
          factory2.createPropertyAccessExpression(
            descriptorName,
            factory2.createIdentifier("value")
          )
        )
      ])
    );
  }
  function createGetAccessorDescriptorForwarder(modifiers, name, descriptorName) {
    modifiers = visitNodes2(modifiers, (node) => isStaticModifier(node) ? node : void 0, isModifier);
    return factory2.createGetAccessorDeclaration(
      modifiers,
      name,
      [],
      /*type*/
      void 0,
      factory2.createBlock([
        factory2.createReturnStatement(
          factory2.createFunctionCallCall(
            factory2.createPropertyAccessExpression(
              descriptorName,
              factory2.createIdentifier("get")
            ),
            factory2.createThis(),
            []
          )
        )
      ])
    );
  }
  function createSetAccessorDescriptorForwarder(modifiers, name, descriptorName) {
    modifiers = visitNodes2(modifiers, (node) => isStaticModifier(node) ? node : void 0, isModifier);
    return factory2.createSetAccessorDeclaration(
      modifiers,
      name,
      [factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        "value"
      )],
      factory2.createBlock([
        factory2.createReturnStatement(
          factory2.createFunctionCallCall(
            factory2.createPropertyAccessExpression(
              descriptorName,
              factory2.createIdentifier("set")
            ),
            factory2.createThis(),
            [factory2.createIdentifier("value")]
          )
        )
      ])
    );
  }
  function createMetadata(name, classSuper2) {
    const varDecl = factory2.createVariableDeclaration(
      name,
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      factory2.createConditionalExpression(
        factory2.createLogicalAnd(
          factory2.createTypeCheck(factory2.createIdentifier("Symbol"), "function"),
          factory2.createPropertyAccessExpression(factory2.createIdentifier("Symbol"), "metadata")
        ),
        factory2.createToken(58 /* QuestionToken */),
        factory2.createCallExpression(
          factory2.createPropertyAccessExpression(factory2.createIdentifier("Object"), "create"),
          /*typeArguments*/
          void 0,
          [classSuper2 ? createSymbolMetadataReference(classSuper2) : factory2.createNull()]
        ),
        factory2.createToken(59 /* ColonToken */),
        factory2.createVoidZero()
      )
    );
    return factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      factory2.createVariableDeclarationList([varDecl], 2 /* Const */)
    );
  }
  function createSymbolMetadata(target, value) {
    const defineProperty = factory2.createObjectDefinePropertyCall(
      target,
      factory2.createPropertyAccessExpression(factory2.createIdentifier("Symbol"), "metadata"),
      factory2.createPropertyDescriptor(
        { configurable: true, writable: true, enumerable: true, value },
        /*singleLine*/
        true
      )
    );
    return setEmitFlags(
      factory2.createIfStatement(value, factory2.createExpressionStatement(defineProperty)),
      1 /* SingleLine */
    );
  }
  function createSymbolMetadataReference(classSuper2) {
    return factory2.createBinaryExpression(
      factory2.createElementAccessExpression(
        classSuper2,
        factory2.createPropertyAccessExpression(factory2.createIdentifier("Symbol"), "metadata")
      ),
      61 /* QuestionQuestionToken */,
      factory2.createNull()
    );
  }
}

// src/compiler/transformers/es2017.ts
function transformES2017(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    resumeLexicalEnvironment,
    endLexicalEnvironment,
    hoistVariableDeclaration
  } = context;
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  let enabledSubstitutions;
  let enclosingSuperContainerFlags = 0;
  let enclosingFunctionParameterNames;
  let capturedSuperProperties;
  let hasSuperElementAccess;
  let lexicalArgumentsBinding;
  const substitutedSuperAccessors = [];
  let contextFlags = 0 /* None */;
  const previousOnEmitNode = context.onEmitNode;
  const previousOnSubstituteNode = context.onSubstituteNode;
  context.onEmitNode = onEmitNode;
  context.onSubstituteNode = onSubstituteNode;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    setContextFlag(1 /* NonTopLevel */, false);
    setContextFlag(2 /* HasLexicalThis */, !isEffectiveStrictModeSourceFile(node, compilerOptions));
    const visited = visitEachChild(node, visitor, context);
    addEmitHelpers(visited, context.readEmitHelpers());
    return visited;
  }
  function setContextFlag(flag, val) {
    contextFlags = val ? contextFlags | flag : contextFlags & ~flag;
  }
  function inContext(flags) {
    return (contextFlags & flags) !== 0;
  }
  function inTopLevelContext() {
    return !inContext(1 /* NonTopLevel */);
  }
  function inHasLexicalThisContext() {
    return inContext(2 /* HasLexicalThis */);
  }
  function doWithContext(flags, cb, value) {
    const contextFlagsToSet = flags & ~contextFlags;
    if (contextFlagsToSet) {
      setContextFlag(
        contextFlagsToSet,
        /*val*/
        true
      );
      const result = cb(value);
      setContextFlag(
        contextFlagsToSet,
        /*val*/
        false
      );
      return result;
    }
    return cb(value);
  }
  function visitDefault(node) {
    return visitEachChild(node, visitor, context);
  }
  function argumentsVisitor(node) {
    switch (node.kind) {
      case 218 /* FunctionExpression */:
      case 262 /* FunctionDeclaration */:
      case 174 /* MethodDeclaration */:
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 176 /* Constructor */:
        return node;
      case 169 /* Parameter */:
      case 208 /* BindingElement */:
      case 260 /* VariableDeclaration */:
        break;
      case 80 /* Identifier */:
        if (lexicalArgumentsBinding && resolver.isArgumentsLocalBinding(node)) {
          return lexicalArgumentsBinding;
        }
        break;
    }
    return visitEachChild(node, argumentsVisitor, context);
  }
  function visitor(node) {
    if ((node.transformFlags & 256 /* ContainsES2017 */) === 0) {
      return lexicalArgumentsBinding ? argumentsVisitor(node) : node;
    }
    switch (node.kind) {
      case 134 /* AsyncKeyword */:
        return void 0;
      case 223 /* AwaitExpression */:
        return visitAwaitExpression(node);
      case 174 /* MethodDeclaration */:
        return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitMethodDeclaration, node);
      case 262 /* FunctionDeclaration */:
        return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitFunctionDeclaration, node);
      case 218 /* FunctionExpression */:
        return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitFunctionExpression, node);
      case 219 /* ArrowFunction */:
        return doWithContext(1 /* NonTopLevel */, visitArrowFunction, node);
      case 211 /* PropertyAccessExpression */:
        if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === 108 /* SuperKeyword */) {
          capturedSuperProperties.add(node.name.escapedText);
        }
        return visitEachChild(node, visitor, context);
      case 212 /* ElementAccessExpression */:
        if (capturedSuperProperties && node.expression.kind === 108 /* SuperKeyword */) {
          hasSuperElementAccess = true;
        }
        return visitEachChild(node, visitor, context);
      case 177 /* GetAccessor */:
        return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitGetAccessorDeclaration, node);
      case 178 /* SetAccessor */:
        return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitSetAccessorDeclaration, node);
      case 176 /* Constructor */:
        return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitConstructorDeclaration, node);
      case 263 /* ClassDeclaration */:
      case 231 /* ClassExpression */:
        return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitDefault, node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function asyncBodyVisitor(node) {
    if (isNodeWithPossibleHoistedDeclaration(node)) {
      switch (node.kind) {
        case 243 /* VariableStatement */:
          return visitVariableStatementInAsyncBody(node);
        case 248 /* ForStatement */:
          return visitForStatementInAsyncBody(node);
        case 249 /* ForInStatement */:
          return visitForInStatementInAsyncBody(node);
        case 250 /* ForOfStatement */:
          return visitForOfStatementInAsyncBody(node);
        case 299 /* CatchClause */:
          return visitCatchClauseInAsyncBody(node);
        case 241 /* Block */:
        case 255 /* SwitchStatement */:
        case 269 /* CaseBlock */:
        case 296 /* CaseClause */:
        case 297 /* DefaultClause */:
        case 258 /* TryStatement */:
        case 246 /* DoStatement */:
        case 247 /* WhileStatement */:
        case 245 /* IfStatement */:
        case 254 /* WithStatement */:
        case 256 /* LabeledStatement */:
          return visitEachChild(node, asyncBodyVisitor, context);
        default:
          return Debug.assertNever(node, "Unhandled node.");
      }
    }
    return visitor(node);
  }
  function visitCatchClauseInAsyncBody(node) {
    const catchClauseNames = /* @__PURE__ */ new Set();
    recordDeclarationName(node.variableDeclaration, catchClauseNames);
    let catchClauseUnshadowedNames;
    catchClauseNames.forEach((_, escapedName) => {
      if (enclosingFunctionParameterNames.has(escapedName)) {
        if (!catchClauseUnshadowedNames) {
          catchClauseUnshadowedNames = new Set(enclosingFunctionParameterNames);
        }
        catchClauseUnshadowedNames.delete(escapedName);
      }
    });
    if (catchClauseUnshadowedNames) {
      const savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
      enclosingFunctionParameterNames = catchClauseUnshadowedNames;
      const result = visitEachChild(node, asyncBodyVisitor, context);
      enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
      return result;
    } else {
      return visitEachChild(node, asyncBodyVisitor, context);
    }
  }
  function visitVariableStatementInAsyncBody(node) {
    if (isVariableDeclarationListWithCollidingName(node.declarationList)) {
      const expression = visitVariableDeclarationListWithCollidingNames(
        node.declarationList,
        /*hasReceiver*/
        false
      );
      return expression ? factory2.createExpressionStatement(expression) : void 0;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitForInStatementInAsyncBody(node) {
    return factory2.updateForInStatement(
      node,
      isVariableDeclarationListWithCollidingName(node.initializer) ? visitVariableDeclarationListWithCollidingNames(
        node.initializer,
        /*hasReceiver*/
        true
      ) : Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
      visitIterationBody(node.statement, asyncBodyVisitor, context)
    );
  }
  function visitForOfStatementInAsyncBody(node) {
    return factory2.updateForOfStatement(
      node,
      visitNode(node.awaitModifier, visitor, isAwaitKeyword),
      isVariableDeclarationListWithCollidingName(node.initializer) ? visitVariableDeclarationListWithCollidingNames(
        node.initializer,
        /*hasReceiver*/
        true
      ) : Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
      visitIterationBody(node.statement, asyncBodyVisitor, context)
    );
  }
  function visitForStatementInAsyncBody(node) {
    const initializer = node.initializer;
    return factory2.updateForStatement(
      node,
      isVariableDeclarationListWithCollidingName(initializer) ? visitVariableDeclarationListWithCollidingNames(
        initializer,
        /*hasReceiver*/
        false
      ) : visitNode(node.initializer, visitor, isForInitializer),
      visitNode(node.condition, visitor, isExpression),
      visitNode(node.incrementor, visitor, isExpression),
      visitIterationBody(node.statement, asyncBodyVisitor, context)
    );
  }
  function visitAwaitExpression(node) {
    if (inTopLevelContext()) {
      return visitEachChild(node, visitor, context);
    }
    return setOriginalNode(
      setTextRange(
        factory2.createYieldExpression(
          /*asteriskToken*/
          void 0,
          visitNode(node.expression, visitor, isExpression)
        ),
        node
      ),
      node
    );
  }
  function visitConstructorDeclaration(node) {
    const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
    lexicalArgumentsBinding = void 0;
    const updated = factory2.updateConstructorDeclaration(
      node,
      visitNodes2(node.modifiers, visitor, isModifier),
      visitParameterList(node.parameters, visitor, context),
      transformMethodBody(node)
    );
    lexicalArgumentsBinding = savedLexicalArgumentsBinding;
    return updated;
  }
  function visitMethodDeclaration(node) {
    let parameters;
    const functionFlags = getFunctionFlags(node);
    const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
    lexicalArgumentsBinding = void 0;
    const updated = factory2.updateMethodDeclaration(
      node,
      visitNodes2(node.modifiers, visitor, isModifierLike),
      node.asteriskToken,
      node.name,
      /*questionToken*/
      void 0,
      /*typeParameters*/
      void 0,
      parameters = functionFlags & 2 /* Async */ ? transformAsyncFunctionParameterList(node) : visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      functionFlags & 2 /* Async */ ? transformAsyncFunctionBody(node, parameters) : transformMethodBody(node)
    );
    lexicalArgumentsBinding = savedLexicalArgumentsBinding;
    return updated;
  }
  function visitGetAccessorDeclaration(node) {
    const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
    lexicalArgumentsBinding = void 0;
    const updated = factory2.updateGetAccessorDeclaration(
      node,
      visitNodes2(node.modifiers, visitor, isModifierLike),
      node.name,
      visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      transformMethodBody(node)
    );
    lexicalArgumentsBinding = savedLexicalArgumentsBinding;
    return updated;
  }
  function visitSetAccessorDeclaration(node) {
    const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
    lexicalArgumentsBinding = void 0;
    const updated = factory2.updateSetAccessorDeclaration(
      node,
      visitNodes2(node.modifiers, visitor, isModifierLike),
      node.name,
      visitParameterList(node.parameters, visitor, context),
      transformMethodBody(node)
    );
    lexicalArgumentsBinding = savedLexicalArgumentsBinding;
    return updated;
  }
  function visitFunctionDeclaration(node) {
    let parameters;
    const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
    lexicalArgumentsBinding = void 0;
    const functionFlags = getFunctionFlags(node);
    const updated = factory2.updateFunctionDeclaration(
      node,
      visitNodes2(node.modifiers, visitor, isModifierLike),
      node.asteriskToken,
      node.name,
      /*typeParameters*/
      void 0,
      parameters = functionFlags & 2 /* Async */ ? transformAsyncFunctionParameterList(node) : visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      functionFlags & 2 /* Async */ ? transformAsyncFunctionBody(node, parameters) : visitFunctionBody(node.body, visitor, context)
    );
    lexicalArgumentsBinding = savedLexicalArgumentsBinding;
    return updated;
  }
  function visitFunctionExpression(node) {
    let parameters;
    const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
    lexicalArgumentsBinding = void 0;
    const functionFlags = getFunctionFlags(node);
    const updated = factory2.updateFunctionExpression(
      node,
      visitNodes2(node.modifiers, visitor, isModifier),
      node.asteriskToken,
      node.name,
      /*typeParameters*/
      void 0,
      parameters = functionFlags & 2 /* Async */ ? transformAsyncFunctionParameterList(node) : visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      functionFlags & 2 /* Async */ ? transformAsyncFunctionBody(node, parameters) : visitFunctionBody(node.body, visitor, context)
    );
    lexicalArgumentsBinding = savedLexicalArgumentsBinding;
    return updated;
  }
  function visitArrowFunction(node) {
    let parameters;
    const functionFlags = getFunctionFlags(node);
    return factory2.updateArrowFunction(
      node,
      visitNodes2(node.modifiers, visitor, isModifier),
      /*typeParameters*/
      void 0,
      parameters = functionFlags & 2 /* Async */ ? transformAsyncFunctionParameterList(node) : visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      node.equalsGreaterThanToken,
      functionFlags & 2 /* Async */ ? transformAsyncFunctionBody(node, parameters) : visitFunctionBody(node.body, visitor, context)
    );
  }
  function recordDeclarationName({ name }, names) {
    if (isIdentifier(name)) {
      names.add(name.escapedText);
    } else {
      for (const element of name.elements) {
        if (!isOmittedExpression(element)) {
          recordDeclarationName(element, names);
        }
      }
    }
  }
  function isVariableDeclarationListWithCollidingName(node) {
    return !!node && isVariableDeclarationList(node) && !(node.flags & 7 /* BlockScoped */) && node.declarations.some(collidesWithParameterName);
  }
  function visitVariableDeclarationListWithCollidingNames(node, hasReceiver) {
    hoistVariableDeclarationList(node);
    const variables = getInitializedVariables(node);
    if (variables.length === 0) {
      if (hasReceiver) {
        return visitNode(factory2.converters.convertToAssignmentElementTarget(node.declarations[0].name), visitor, isExpression);
      }
      return void 0;
    }
    return factory2.inlineExpressions(map(variables, transformInitializedVariable));
  }
  function hoistVariableDeclarationList(node) {
    forEach(node.declarations, hoistVariable);
  }
  function hoistVariable({ name }) {
    if (isIdentifier(name)) {
      hoistVariableDeclaration(name);
    } else {
      for (const element of name.elements) {
        if (!isOmittedExpression(element)) {
          hoistVariable(element);
        }
      }
    }
  }
  function transformInitializedVariable(node) {
    const converted = setSourceMapRange(
      factory2.createAssignment(
        factory2.converters.convertToAssignmentElementTarget(node.name),
        node.initializer
      ),
      node
    );
    return Debug.checkDefined(visitNode(converted, visitor, isExpression));
  }
  function collidesWithParameterName({ name }) {
    if (isIdentifier(name)) {
      return enclosingFunctionParameterNames.has(name.escapedText);
    } else {
      for (const element of name.elements) {
        if (!isOmittedExpression(element) && collidesWithParameterName(element)) {
          return true;
        }
      }
    }
    return false;
  }
  function transformMethodBody(node) {
    Debug.assertIsDefined(node.body);
    const savedCapturedSuperProperties = capturedSuperProperties;
    const savedHasSuperElementAccess = hasSuperElementAccess;
    capturedSuperProperties = /* @__PURE__ */ new Set();
    hasSuperElementAccess = false;
    let updated = visitFunctionBody(node.body, visitor, context);
    const originalMethod = getOriginalNode(node, isFunctionLikeDeclaration);
    const emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */) || resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */)) && (getFunctionFlags(originalMethod) & 3 /* AsyncGenerator */) !== 3 /* AsyncGenerator */;
    if (emitSuperHelpers) {
      enableSubstitutionForAsyncMethodsWithSuper();
      if (capturedSuperProperties.size) {
        const variableStatement = createSuperAccessVariableStatement(factory2, resolver, node, capturedSuperProperties);
        substitutedSuperAccessors[getNodeId(variableStatement)] = true;
        const statements = updated.statements.slice();
        insertStatementsAfterStandardPrologue(statements, [variableStatement]);
        updated = factory2.updateBlock(updated, statements);
      }
      if (hasSuperElementAccess) {
        if (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */)) {
          addEmitHelper(updated, advancedAsyncSuperHelper);
        } else if (resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */)) {
          addEmitHelper(updated, asyncSuperHelper);
        }
      }
    }
    capturedSuperProperties = savedCapturedSuperProperties;
    hasSuperElementAccess = savedHasSuperElementAccess;
    return updated;
  }
  function createCaptureArgumentsStatement() {
    Debug.assert(lexicalArgumentsBinding);
    const variable = factory2.createVariableDeclaration(
      lexicalArgumentsBinding,
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      factory2.createIdentifier("arguments")
    );
    const statement = factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      [variable]
    );
    startOnNewLine(statement);
    addEmitFlags(statement, 2097152 /* CustomPrologue */);
    return statement;
  }
  function transformAsyncFunctionParameterList(node) {
    if (isSimpleParameterList(node.parameters)) {
      return visitParameterList(node.parameters, visitor, context);
    }
    const newParameters = [];
    for (const parameter of node.parameters) {
      if (parameter.initializer || parameter.dotDotDotToken) {
        if (node.kind === 219 /* ArrowFunction */) {
          const restParameter = factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            factory2.createToken(26 /* DotDotDotToken */),
            factory2.createUniqueName("args", 8 /* ReservedInNestedScopes */)
          );
          newParameters.push(restParameter);
        }
        break;
      }
      const newParameter = factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        factory2.getGeneratedNameForNode(parameter.name, 8 /* ReservedInNestedScopes */)
      );
      newParameters.push(newParameter);
    }
    const newParametersArray = factory2.createNodeArray(newParameters);
    setTextRange(newParametersArray, node.parameters);
    return newParametersArray;
  }
  function transformAsyncFunctionBody(node, outerParameters) {
    const innerParameters = !isSimpleParameterList(node.parameters) ? visitParameterList(node.parameters, visitor, context) : void 0;
    resumeLexicalEnvironment();
    const original = getOriginalNode(node, isFunctionLike);
    const nodeType = original.type;
    const promiseConstructor = languageVersion < 2 /* ES2015 */ ? getPromiseConstructor(nodeType) : void 0;
    const isArrowFunction2 = node.kind === 219 /* ArrowFunction */;
    const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
    const hasLexicalArguments = resolver.hasNodeCheckFlag(node, 512 /* CaptureArguments */);
    const captureLexicalArguments = hasLexicalArguments && !lexicalArgumentsBinding;
    if (captureLexicalArguments) {
      lexicalArgumentsBinding = factory2.createUniqueName("arguments");
    }
    let argumentsExpression;
    if (innerParameters) {
      if (isArrowFunction2) {
        const parameterBindings = [];
        Debug.assert(outerParameters.length <= node.parameters.length);
        for (let i = 0; i < node.parameters.length; i++) {
          Debug.assert(i < outerParameters.length);
          const originalParameter = node.parameters[i];
          const outerParameter = outerParameters[i];
          Debug.assertNode(outerParameter.name, isIdentifier);
          if (originalParameter.initializer || originalParameter.dotDotDotToken) {
            Debug.assert(i === outerParameters.length - 1);
            parameterBindings.push(factory2.createSpreadElement(outerParameter.name));
            break;
          }
          parameterBindings.push(outerParameter.name);
        }
        argumentsExpression = factory2.createArrayLiteralExpression(parameterBindings);
      } else {
        argumentsExpression = factory2.createIdentifier("arguments");
      }
    }
    const savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
    enclosingFunctionParameterNames = /* @__PURE__ */ new Set();
    for (const parameter of node.parameters) {
      recordDeclarationName(parameter, enclosingFunctionParameterNames);
    }
    const savedCapturedSuperProperties = capturedSuperProperties;
    const savedHasSuperElementAccess = hasSuperElementAccess;
    if (!isArrowFunction2) {
      capturedSuperProperties = /* @__PURE__ */ new Set();
      hasSuperElementAccess = false;
    }
    const hasLexicalThis = inHasLexicalThisContext();
    let asyncBody = transformAsyncFunctionBodyWorker(node.body);
    asyncBody = factory2.updateBlock(asyncBody, factory2.mergeLexicalEnvironment(asyncBody.statements, endLexicalEnvironment()));
    let result;
    if (!isArrowFunction2) {
      const statements = [];
      statements.push(
        factory2.createReturnStatement(
          emitHelpers().createAwaiterHelper(
            hasLexicalThis,
            argumentsExpression,
            promiseConstructor,
            innerParameters,
            asyncBody
          )
        )
      );
      const emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */) || resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */));
      if (emitSuperHelpers) {
        enableSubstitutionForAsyncMethodsWithSuper();
        if (capturedSuperProperties.size) {
          const variableStatement = createSuperAccessVariableStatement(factory2, resolver, node, capturedSuperProperties);
          substitutedSuperAccessors[getNodeId(variableStatement)] = true;
          insertStatementsAfterStandardPrologue(statements, [variableStatement]);
        }
      }
      if (captureLexicalArguments) {
        insertStatementsAfterStandardPrologue(statements, [createCaptureArgumentsStatement()]);
      }
      const block = factory2.createBlock(
        statements,
        /*multiLine*/
        true
      );
      setTextRange(block, node.body);
      if (emitSuperHelpers && hasSuperElementAccess) {
        if (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */)) {
          addEmitHelper(block, advancedAsyncSuperHelper);
        } else if (resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */)) {
          addEmitHelper(block, asyncSuperHelper);
        }
      }
      result = block;
    } else {
      result = emitHelpers().createAwaiterHelper(
        hasLexicalThis,
        argumentsExpression,
        promiseConstructor,
        innerParameters,
        asyncBody
      );
      if (captureLexicalArguments) {
        const block = factory2.converters.convertToFunctionBlock(result);
        result = factory2.updateBlock(block, factory2.mergeLexicalEnvironment(block.statements, [createCaptureArgumentsStatement()]));
      }
    }
    enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
    if (!isArrowFunction2) {
      capturedSuperProperties = savedCapturedSuperProperties;
      hasSuperElementAccess = savedHasSuperElementAccess;
      lexicalArgumentsBinding = savedLexicalArgumentsBinding;
    }
    return result;
  }
  function transformAsyncFunctionBodyWorker(body, start) {
    if (isBlock(body)) {
      return factory2.updateBlock(body, visitNodes2(body.statements, asyncBodyVisitor, isStatement, start));
    } else {
      return factory2.converters.convertToFunctionBlock(Debug.checkDefined(visitNode(body, asyncBodyVisitor, isConciseBody)));
    }
  }
  function getPromiseConstructor(type) {
    const typeName = type && getEntityNameFromTypeNode(type);
    if (typeName && isEntityName(typeName)) {
      const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
      if (serializationKind === 1 /* TypeWithConstructSignatureAndValue */ || serializationKind === 0 /* Unknown */) {
        return typeName;
      }
    }
    return void 0;
  }
  function enableSubstitutionForAsyncMethodsWithSuper() {
    if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
      enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
      context.enableSubstitution(213 /* CallExpression */);
      context.enableSubstitution(211 /* PropertyAccessExpression */);
      context.enableSubstitution(212 /* ElementAccessExpression */);
      context.enableEmitNotification(263 /* ClassDeclaration */);
      context.enableEmitNotification(174 /* MethodDeclaration */);
      context.enableEmitNotification(177 /* GetAccessor */);
      context.enableEmitNotification(178 /* SetAccessor */);
      context.enableEmitNotification(176 /* Constructor */);
      context.enableEmitNotification(243 /* VariableStatement */);
    }
  }
  function onEmitNode(hint, node, emitCallback) {
    if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
      const superContainerFlags = (resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */) ? 128 /* MethodWithSuperPropertyAccessInAsync */ : 0) | (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */) ? 256 /* MethodWithSuperPropertyAssignmentInAsync */ : 0);
      if (superContainerFlags !== enclosingSuperContainerFlags) {
        const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
        enclosingSuperContainerFlags = superContainerFlags;
        previousOnEmitNode(hint, node, emitCallback);
        enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
        return;
      }
    } else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) {
      const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
      enclosingSuperContainerFlags = 0;
      previousOnEmitNode(hint, node, emitCallback);
      enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
      return;
    }
    previousOnEmitNode(hint, node, emitCallback);
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
      return substituteExpression(node);
    }
    return node;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 211 /* PropertyAccessExpression */:
        return substitutePropertyAccessExpression(node);
      case 212 /* ElementAccessExpression */:
        return substituteElementAccessExpression(node);
      case 213 /* CallExpression */:
        return substituteCallExpression(node);
    }
    return node;
  }
  function substitutePropertyAccessExpression(node) {
    if (node.expression.kind === 108 /* SuperKeyword */) {
      return setTextRange(
        factory2.createPropertyAccessExpression(
          factory2.createUniqueName("_super", 16 /* Optimistic */ | 32 /* FileLevel */),
          node.name
        ),
        node
      );
    }
    return node;
  }
  function substituteElementAccessExpression(node) {
    if (node.expression.kind === 108 /* SuperKeyword */) {
      return createSuperElementAccessInAsyncMethod(
        node.argumentExpression,
        node
      );
    }
    return node;
  }
  function substituteCallExpression(node) {
    const expression = node.expression;
    if (isSuperProperty(expression)) {
      const argumentExpression = isPropertyAccessExpression(expression) ? substitutePropertyAccessExpression(expression) : substituteElementAccessExpression(expression);
      return factory2.createCallExpression(
        factory2.createPropertyAccessExpression(argumentExpression, "call"),
        /*typeArguments*/
        void 0,
        [
          factory2.createThis(),
          ...node.arguments
        ]
      );
    }
    return node;
  }
  function isSuperContainer(node) {
    const kind = node.kind;
    return kind === 263 /* ClassDeclaration */ || kind === 176 /* Constructor */ || kind === 174 /* MethodDeclaration */ || kind === 177 /* GetAccessor */ || kind === 178 /* SetAccessor */;
  }
  function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
    if (enclosingSuperContainerFlags & 256 /* MethodWithSuperPropertyAssignmentInAsync */) {
      return setTextRange(
        factory2.createPropertyAccessExpression(
          factory2.createCallExpression(
            factory2.createUniqueName("_superIndex", 16 /* Optimistic */ | 32 /* FileLevel */),
            /*typeArguments*/
            void 0,
            [argumentExpression]
          ),
          "value"
        ),
        location
      );
    } else {
      return setTextRange(
        factory2.createCallExpression(
          factory2.createUniqueName("_superIndex", 16 /* Optimistic */ | 32 /* FileLevel */),
          /*typeArguments*/
          void 0,
          [argumentExpression]
        ),
        location
      );
    }
  }
}
function createSuperAccessVariableStatement(factory2, resolver, node, names) {
  const hasBinding = resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */);
  const accessors = [];
  names.forEach((_, key) => {
    const name = unescapeLeadingUnderscores(key);
    const getterAndSetter = [];
    getterAndSetter.push(factory2.createPropertyAssignment(
      "get",
      factory2.createArrowFunction(
        /*modifiers*/
        void 0,
        /*typeParameters*/
        void 0,
        /* parameters */
        [],
        /*type*/
        void 0,
        /*equalsGreaterThanToken*/
        void 0,
        setEmitFlags(
          factory2.createPropertyAccessExpression(
            setEmitFlags(
              factory2.createSuper(),
              8 /* NoSubstitution */
            ),
            name
          ),
          8 /* NoSubstitution */
        )
      )
    ));
    if (hasBinding) {
      getterAndSetter.push(
        factory2.createPropertyAssignment(
          "set",
          factory2.createArrowFunction(
            /*modifiers*/
            void 0,
            /*typeParameters*/
            void 0,
            /* parameters */
            [
              factory2.createParameterDeclaration(
                /*modifiers*/
                void 0,
                /*dotDotDotToken*/
                void 0,
                "v",
                /*questionToken*/
                void 0,
                /*type*/
                void 0,
                /*initializer*/
                void 0
              )
            ],
            /*type*/
            void 0,
            /*equalsGreaterThanToken*/
            void 0,
            factory2.createAssignment(
              setEmitFlags(
                factory2.createPropertyAccessExpression(
                  setEmitFlags(
                    factory2.createSuper(),
                    8 /* NoSubstitution */
                  ),
                  name
                ),
                8 /* NoSubstitution */
              ),
              factory2.createIdentifier("v")
            )
          )
        )
      );
    }
    accessors.push(
      factory2.createPropertyAssignment(
        name,
        factory2.createObjectLiteralExpression(getterAndSetter)
      )
    );
  });
  return factory2.createVariableStatement(
    /*modifiers*/
    void 0,
    factory2.createVariableDeclarationList(
      [
        factory2.createVariableDeclaration(
          factory2.createUniqueName("_super", 16 /* Optimistic */ | 32 /* FileLevel */),
          /*exclamationToken*/
          void 0,
          /*type*/
          void 0,
          factory2.createCallExpression(
            factory2.createPropertyAccessExpression(
              factory2.createIdentifier("Object"),
              "create"
            ),
            /*typeArguments*/
            void 0,
            [
              factory2.createNull(),
              factory2.createObjectLiteralExpression(
                accessors,
                /*multiLine*/
                true
              )
            ]
          )
        )
      ],
      2 /* Const */
    )
  );
}

// src/compiler/transformers/es2018.ts
function transformES2018(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    resumeLexicalEnvironment,
    endLexicalEnvironment,
    hoistVariableDeclaration
  } = context;
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const previousOnEmitNode = context.onEmitNode;
  context.onEmitNode = onEmitNode;
  const previousOnSubstituteNode = context.onSubstituteNode;
  context.onSubstituteNode = onSubstituteNode;
  let exportedVariableStatement = false;
  let enabledSubstitutions;
  let enclosingFunctionFlags;
  let parametersWithPrecedingObjectRestOrSpread;
  let enclosingSuperContainerFlags = 0;
  let hierarchyFacts = 0;
  let currentSourceFile;
  let taggedTemplateStringDeclarations;
  let capturedSuperProperties;
  let hasSuperElementAccess;
  const substitutedSuperAccessors = [];
  return chainBundle(context, transformSourceFile);
  function affectsSubtree(excludeFacts, includeFacts) {
    return hierarchyFacts !== (hierarchyFacts & ~excludeFacts | includeFacts);
  }
  function enterSubtree(excludeFacts, includeFacts) {
    const ancestorFacts = hierarchyFacts;
    hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 3 /* AncestorFactsMask */;
    return ancestorFacts;
  }
  function exitSubtree(ancestorFacts) {
    hierarchyFacts = ancestorFacts;
  }
  function recordTaggedTemplateString(temp) {
    taggedTemplateStringDeclarations = append(
      taggedTemplateStringDeclarations,
      factory2.createVariableDeclaration(temp)
    );
  }
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    currentSourceFile = node;
    const visited = visitSourceFile(node);
    addEmitHelpers(visited, context.readEmitHelpers());
    currentSourceFile = void 0;
    taggedTemplateStringDeclarations = void 0;
    return visited;
  }
  function visitor(node) {
    return visitorWorker(
      node,
      /*expressionResultIsUnused*/
      false
    );
  }
  function visitorWithUnusedExpressionResult(node) {
    return visitorWorker(
      node,
      /*expressionResultIsUnused*/
      true
    );
  }
  function visitorNoAsyncModifier(node) {
    if (node.kind === 134 /* AsyncKeyword */) {
      return void 0;
    }
    return node;
  }
  function doWithHierarchyFacts(cb, value, excludeFacts, includeFacts) {
    if (affectsSubtree(excludeFacts, includeFacts)) {
      const ancestorFacts = enterSubtree(excludeFacts, includeFacts);
      const result = cb(value);
      exitSubtree(ancestorFacts);
      return result;
    }
    return cb(value);
  }
  function visitDefault(node) {
    return visitEachChild(node, visitor, context);
  }
  function visitorWorker(node, expressionResultIsUnused2) {
    if ((node.transformFlags & 128 /* ContainsES2018 */) === 0) {
      return node;
    }
    switch (node.kind) {
      case 223 /* AwaitExpression */:
        return visitAwaitExpression(node);
      case 229 /* YieldExpression */:
        return visitYieldExpression(node);
      case 253 /* ReturnStatement */:
        return visitReturnStatement(node);
      case 256 /* LabeledStatement */:
        return visitLabeledStatement(node);
      case 210 /* ObjectLiteralExpression */:
        return visitObjectLiteralExpression(node);
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(node, expressionResultIsUnused2);
      case 355 /* CommaListExpression */:
        return visitCommaListExpression(node, expressionResultIsUnused2);
      case 299 /* CatchClause */:
        return visitCatchClause(node);
      case 243 /* VariableStatement */:
        return visitVariableStatement(node);
      case 260 /* VariableDeclaration */:
        return visitVariableDeclaration(node);
      case 246 /* DoStatement */:
      case 247 /* WhileStatement */:
      case 249 /* ForInStatement */:
        return doWithHierarchyFacts(
          visitDefault,
          node,
          0 /* IterationStatementExcludes */,
          2 /* IterationStatementIncludes */
        );
      case 250 /* ForOfStatement */:
        return visitForOfStatement(
          node,
          /*outermostLabeledStatement*/
          void 0
        );
      case 248 /* ForStatement */:
        return doWithHierarchyFacts(
          visitForStatement,
          node,
          0 /* IterationStatementExcludes */,
          2 /* IterationStatementIncludes */
        );
      case 222 /* VoidExpression */:
        return visitVoidExpression(node);
      case 176 /* Constructor */:
        return doWithHierarchyFacts(
          visitConstructorDeclaration,
          node,
          2 /* ClassOrFunctionExcludes */,
          1 /* ClassOrFunctionIncludes */
        );
      case 174 /* MethodDeclaration */:
        return doWithHierarchyFacts(
          visitMethodDeclaration,
          node,
          2 /* ClassOrFunctionExcludes */,
          1 /* ClassOrFunctionIncludes */
        );
      case 177 /* GetAccessor */:
        return doWithHierarchyFacts(
          visitGetAccessorDeclaration,
          node,
          2 /* ClassOrFunctionExcludes */,
          1 /* ClassOrFunctionIncludes */
        );
      case 178 /* SetAccessor */:
        return doWithHierarchyFacts(
          visitSetAccessorDeclaration,
          node,
          2 /* ClassOrFunctionExcludes */,
          1 /* ClassOrFunctionIncludes */
        );
      case 262 /* FunctionDeclaration */:
        return doWithHierarchyFacts(
          visitFunctionDeclaration,
          node,
          2 /* ClassOrFunctionExcludes */,
          1 /* ClassOrFunctionIncludes */
        );
      case 218 /* FunctionExpression */:
        return doWithHierarchyFacts(
          visitFunctionExpression,
          node,
          2 /* ClassOrFunctionExcludes */,
          1 /* ClassOrFunctionIncludes */
        );
      case 219 /* ArrowFunction */:
        return doWithHierarchyFacts(
          visitArrowFunction,
          node,
          2 /* ArrowFunctionExcludes */,
          0 /* ArrowFunctionIncludes */
        );
      case 169 /* Parameter */:
        return visitParameter(node);
      case 244 /* ExpressionStatement */:
        return visitExpressionStatement(node);
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(node, expressionResultIsUnused2);
      case 215 /* TaggedTemplateExpression */:
        return visitTaggedTemplateExpression(node);
      case 211 /* PropertyAccessExpression */:
        if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === 108 /* SuperKeyword */) {
          capturedSuperProperties.add(node.name.escapedText);
        }
        return visitEachChild(node, visitor, context);
      case 212 /* ElementAccessExpression */:
        if (capturedSuperProperties && node.expression.kind === 108 /* SuperKeyword */) {
          hasSuperElementAccess = true;
        }
        return visitEachChild(node, visitor, context);
      case 263 /* ClassDeclaration */:
      case 231 /* ClassExpression */:
        return doWithHierarchyFacts(
          visitDefault,
          node,
          2 /* ClassOrFunctionExcludes */,
          1 /* ClassOrFunctionIncludes */
        );
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitAwaitExpression(node) {
    if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
      return setOriginalNode(
        setTextRange(
          factory2.createYieldExpression(
            /*asteriskToken*/
            void 0,
            emitHelpers().createAwaitHelper(visitNode(node.expression, visitor, isExpression))
          ),
          /*location*/
          node
        ),
        node
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitYieldExpression(node) {
    if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
      if (node.asteriskToken) {
        const expression = visitNode(Debug.checkDefined(node.expression), visitor, isExpression);
        return setOriginalNode(
          setTextRange(
            factory2.createYieldExpression(
              /*asteriskToken*/
              void 0,
              emitHelpers().createAwaitHelper(
                factory2.updateYieldExpression(
                  node,
                  node.asteriskToken,
                  setTextRange(
                    emitHelpers().createAsyncDelegatorHelper(
                      setTextRange(
                        emitHelpers().createAsyncValuesHelper(expression),
                        expression
                      )
                    ),
                    expression
                  )
                )
              )
            ),
            node
          ),
          node
        );
      }
      return setOriginalNode(
        setTextRange(
          factory2.createYieldExpression(
            /*asteriskToken*/
            void 0,
            createDownlevelAwait(
              node.expression ? visitNode(node.expression, visitor, isExpression) : factory2.createVoidZero()
            )
          ),
          node
        ),
        node
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitReturnStatement(node) {
    if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
      return factory2.updateReturnStatement(
        node,
        createDownlevelAwait(
          node.expression ? visitNode(node.expression, visitor, isExpression) : factory2.createVoidZero()
        )
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitLabeledStatement(node) {
    if (enclosingFunctionFlags & 2 /* Async */) {
      const statement = unwrapInnermostStatementOfLabel(node);
      if (statement.kind === 250 /* ForOfStatement */ && statement.awaitModifier) {
        return visitForOfStatement(statement, node);
      }
      return factory2.restoreEnclosingLabel(visitNode(statement, visitor, isStatement, factory2.liftToBlock), node);
    }
    return visitEachChild(node, visitor, context);
  }
  function chunkObjectLiteralElements(elements) {
    let chunkObject;
    const objects = [];
    for (const e of elements) {
      if (e.kind === 305 /* SpreadAssignment */) {
        if (chunkObject) {
          objects.push(factory2.createObjectLiteralExpression(chunkObject));
          chunkObject = void 0;
        }
        const target = e.expression;
        objects.push(visitNode(target, visitor, isExpression));
      } else {
        chunkObject = append(
          chunkObject,
          e.kind === 303 /* PropertyAssignment */ ? factory2.createPropertyAssignment(e.name, visitNode(e.initializer, visitor, isExpression)) : visitNode(e, visitor, isObjectLiteralElementLike)
        );
      }
    }
    if (chunkObject) {
      objects.push(factory2.createObjectLiteralExpression(chunkObject));
    }
    return objects;
  }
  function visitObjectLiteralExpression(node) {
    if (node.transformFlags & 65536 /* ContainsObjectRestOrSpread */) {
      const objects = chunkObjectLiteralElements(node.properties);
      if (objects.length && objects[0].kind !== 210 /* ObjectLiteralExpression */) {
        objects.unshift(factory2.createObjectLiteralExpression());
      }
      let expression = objects[0];
      if (objects.length > 1) {
        for (let i = 1; i < objects.length; i++) {
          expression = emitHelpers().createAssignHelper([expression, objects[i]]);
        }
        return expression;
      } else {
        return emitHelpers().createAssignHelper(objects);
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitExpressionStatement(node) {
    return visitEachChild(node, visitorWithUnusedExpressionResult, context);
  }
  function visitParenthesizedExpression(node, expressionResultIsUnused2) {
    return visitEachChild(node, expressionResultIsUnused2 ? visitorWithUnusedExpressionResult : visitor, context);
  }
  function visitSourceFile(node) {
    const ancestorFacts = enterSubtree(
      2 /* SourceFileExcludes */,
      isEffectiveStrictModeSourceFile(node, compilerOptions) ? 0 /* StrictModeSourceFileIncludes */ : 1 /* SourceFileIncludes */
    );
    exportedVariableStatement = false;
    const visited = visitEachChild(node, visitor, context);
    const statement = concatenate(
      visited.statements,
      taggedTemplateStringDeclarations && [
        factory2.createVariableStatement(
          /*modifiers*/
          void 0,
          factory2.createVariableDeclarationList(taggedTemplateStringDeclarations)
        )
      ]
    );
    const result = factory2.updateSourceFile(visited, setTextRange(factory2.createNodeArray(statement), node.statements));
    exitSubtree(ancestorFacts);
    return result;
  }
  function visitTaggedTemplateExpression(node) {
    return processTaggedTemplateExpression(
      context,
      node,
      visitor,
      currentSourceFile,
      recordTaggedTemplateString,
      0 /* LiftRestriction */
    );
  }
  function visitBinaryExpression(node, expressionResultIsUnused2) {
    if (isDestructuringAssignment(node) && containsObjectRestOrSpread(node.left)) {
      return flattenDestructuringAssignment(
        node,
        visitor,
        context,
        1 /* ObjectRest */,
        !expressionResultIsUnused2
      );
    }
    if (node.operatorToken.kind === 28 /* CommaToken */) {
      return factory2.updateBinaryExpression(
        node,
        visitNode(node.left, visitorWithUnusedExpressionResult, isExpression),
        node.operatorToken,
        visitNode(node.right, expressionResultIsUnused2 ? visitorWithUnusedExpressionResult : visitor, isExpression)
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCommaListExpression(node, expressionResultIsUnused2) {
    if (expressionResultIsUnused2) {
      return visitEachChild(node, visitorWithUnusedExpressionResult, context);
    }
    let result;
    for (let i = 0; i < node.elements.length; i++) {
      const element = node.elements[i];
      const visited = visitNode(element, i < node.elements.length - 1 ? visitorWithUnusedExpressionResult : visitor, isExpression);
      if (result || visited !== element) {
        result || (result = node.elements.slice(0, i));
        result.push(visited);
      }
    }
    const elements = result ? setTextRange(factory2.createNodeArray(result), node.elements) : node.elements;
    return factory2.updateCommaListExpression(node, elements);
  }
  function visitCatchClause(node) {
    if (node.variableDeclaration && isBindingPattern(node.variableDeclaration.name) && node.variableDeclaration.name.transformFlags & 65536 /* ContainsObjectRestOrSpread */) {
      const name = factory2.getGeneratedNameForNode(node.variableDeclaration.name);
      const updatedDecl = factory2.updateVariableDeclaration(
        node.variableDeclaration,
        node.variableDeclaration.name,
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        name
      );
      const visitedBindings = flattenDestructuringBinding(updatedDecl, visitor, context, 1 /* ObjectRest */);
      let block = visitNode(node.block, visitor, isBlock);
      if (some(visitedBindings)) {
        block = factory2.updateBlock(block, [
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            visitedBindings
          ),
          ...block.statements
        ]);
      }
      return factory2.updateCatchClause(
        node,
        factory2.updateVariableDeclaration(
          node.variableDeclaration,
          name,
          /*exclamationToken*/
          void 0,
          /*type*/
          void 0,
          /*initializer*/
          void 0
        ),
        block
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitVariableStatement(node) {
    if (hasSyntacticModifier(node, 32 /* Export */)) {
      const savedExportedVariableStatement = exportedVariableStatement;
      exportedVariableStatement = true;
      const visited = visitEachChild(node, visitor, context);
      exportedVariableStatement = savedExportedVariableStatement;
      return visited;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitVariableDeclaration(node) {
    if (exportedVariableStatement) {
      const savedExportedVariableStatement = exportedVariableStatement;
      exportedVariableStatement = false;
      const visited = visitVariableDeclarationWorker(
        node,
        /*exportedVariableStatement*/
        true
      );
      exportedVariableStatement = savedExportedVariableStatement;
      return visited;
    }
    return visitVariableDeclarationWorker(
      node,
      /*exportedVariableStatement*/
      false
    );
  }
  function visitVariableDeclarationWorker(node, exportedVariableStatement2) {
    if (isBindingPattern(node.name) && node.name.transformFlags & 65536 /* ContainsObjectRestOrSpread */) {
      return flattenDestructuringBinding(
        node,
        visitor,
        context,
        1 /* ObjectRest */,
        /*rval*/
        void 0,
        exportedVariableStatement2
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitForStatement(node) {
    return factory2.updateForStatement(
      node,
      visitNode(node.initializer, visitorWithUnusedExpressionResult, isForInitializer),
      visitNode(node.condition, visitor, isExpression),
      visitNode(node.incrementor, visitorWithUnusedExpressionResult, isExpression),
      visitIterationBody(node.statement, visitor, context)
    );
  }
  function visitVoidExpression(node) {
    return visitEachChild(node, visitorWithUnusedExpressionResult, context);
  }
  function visitForOfStatement(node, outermostLabeledStatement) {
    const ancestorFacts = enterSubtree(0 /* IterationStatementExcludes */, 2 /* IterationStatementIncludes */);
    if (node.initializer.transformFlags & 65536 /* ContainsObjectRestOrSpread */ || isAssignmentPattern(node.initializer) && containsObjectRestOrSpread(node.initializer)) {
      node = transformForOfStatementWithObjectRest(node);
    }
    const result = node.awaitModifier ? transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) : factory2.restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement);
    exitSubtree(ancestorFacts);
    return result;
  }
  function transformForOfStatementWithObjectRest(node) {
    const initializerWithoutParens = skipParentheses(node.initializer);
    if (isVariableDeclarationList(initializerWithoutParens) || isAssignmentPattern(initializerWithoutParens)) {
      let bodyLocation;
      let statementsLocation;
      const temp = factory2.createTempVariable(
        /*recordTempVariable*/
        void 0
      );
      const statements = [createForOfBindingStatement(factory2, initializerWithoutParens, temp)];
      if (isBlock(node.statement)) {
        addRange(statements, node.statement.statements);
        bodyLocation = node.statement;
        statementsLocation = node.statement.statements;
      } else if (node.statement) {
        append(statements, node.statement);
        bodyLocation = node.statement;
        statementsLocation = node.statement;
      }
      return factory2.updateForOfStatement(
        node,
        node.awaitModifier,
        setTextRange(
          factory2.createVariableDeclarationList(
            [
              setTextRange(factory2.createVariableDeclaration(temp), node.initializer)
            ],
            1 /* Let */
          ),
          node.initializer
        ),
        node.expression,
        setTextRange(
          factory2.createBlock(
            setTextRange(factory2.createNodeArray(statements), statementsLocation),
            /*multiLine*/
            true
          ),
          bodyLocation
        )
      );
    }
    return node;
  }
  function convertForOfStatementHead(node, boundValue, nonUserCode) {
    const value = factory2.createTempVariable(hoistVariableDeclaration);
    const iteratorValueExpression = factory2.createAssignment(value, boundValue);
    const iteratorValueStatement = factory2.createExpressionStatement(iteratorValueExpression);
    setSourceMapRange(iteratorValueStatement, node.expression);
    const exitNonUserCodeExpression = factory2.createAssignment(nonUserCode, factory2.createFalse());
    const exitNonUserCodeStatement = factory2.createExpressionStatement(exitNonUserCodeExpression);
    setSourceMapRange(exitNonUserCodeStatement, node.expression);
    const statements = [iteratorValueStatement, exitNonUserCodeStatement];
    const binding = createForOfBindingStatement(factory2, node.initializer, value);
    statements.push(visitNode(binding, visitor, isStatement));
    let bodyLocation;
    let statementsLocation;
    const statement = visitIterationBody(node.statement, visitor, context);
    if (isBlock(statement)) {
      addRange(statements, statement.statements);
      bodyLocation = statement;
      statementsLocation = statement.statements;
    } else {
      statements.push(statement);
    }
    return setTextRange(
      factory2.createBlock(
        setTextRange(factory2.createNodeArray(statements), statementsLocation),
        /*multiLine*/
        true
      ),
      bodyLocation
    );
  }
  function createDownlevelAwait(expression) {
    return enclosingFunctionFlags & 1 /* Generator */ ? factory2.createYieldExpression(
      /*asteriskToken*/
      void 0,
      emitHelpers().createAwaitHelper(expression)
    ) : factory2.createAwaitExpression(expression);
  }
  function transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) {
    const expression = visitNode(node.expression, visitor, isExpression);
    const iterator = isIdentifier(expression) ? factory2.getGeneratedNameForNode(expression) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    const result = isIdentifier(expression) ? factory2.getGeneratedNameForNode(iterator) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    const nonUserCode = factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    const done = factory2.createTempVariable(hoistVariableDeclaration);
    const errorRecord = factory2.createUniqueName("e");
    const catchVariable = factory2.getGeneratedNameForNode(errorRecord);
    const returnMethod = factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    const callValues = setTextRange(emitHelpers().createAsyncValuesHelper(expression), node.expression);
    const callNext = factory2.createCallExpression(
      factory2.createPropertyAccessExpression(iterator, "next"),
      /*typeArguments*/
      void 0,
      []
    );
    const getDone = factory2.createPropertyAccessExpression(result, "done");
    const getValue = factory2.createPropertyAccessExpression(result, "value");
    const callReturn = factory2.createFunctionCallCall(returnMethod, iterator, []);
    hoistVariableDeclaration(errorRecord);
    hoistVariableDeclaration(returnMethod);
    const initializer = ancestorFacts & 2 /* IterationContainer */ ? factory2.inlineExpressions([factory2.createAssignment(errorRecord, factory2.createVoidZero()), callValues]) : callValues;
    const forStatement = setEmitFlags(
      setTextRange(
        factory2.createForStatement(
          /*initializer*/
          setEmitFlags(
            setTextRange(
              factory2.createVariableDeclarationList([
                factory2.createVariableDeclaration(
                  nonUserCode,
                  /*exclamationToken*/
                  void 0,
                  /*type*/
                  void 0,
                  factory2.createTrue()
                ),
                setTextRange(factory2.createVariableDeclaration(
                  iterator,
                  /*exclamationToken*/
                  void 0,
                  /*type*/
                  void 0,
                  initializer
                ), node.expression),
                factory2.createVariableDeclaration(result)
              ]),
              node.expression
            ),
            4194304 /* NoHoisting */
          ),
          /*condition*/
          factory2.inlineExpressions([
            factory2.createAssignment(result, createDownlevelAwait(callNext)),
            factory2.createAssignment(done, getDone),
            factory2.createLogicalNot(done)
          ]),
          /*incrementor*/
          factory2.createAssignment(nonUserCode, factory2.createTrue()),
          /*statement*/
          convertForOfStatementHead(node, getValue, nonUserCode)
        ),
        /*location*/
        node
      ),
      512 /* NoTokenTrailingSourceMaps */
    );
    setOriginalNode(forStatement, node);
    return factory2.createTryStatement(
      factory2.createBlock([
        factory2.restoreEnclosingLabel(
          forStatement,
          outermostLabeledStatement
        )
      ]),
      factory2.createCatchClause(
        factory2.createVariableDeclaration(catchVariable),
        setEmitFlags(
          factory2.createBlock([
            factory2.createExpressionStatement(
              factory2.createAssignment(
                errorRecord,
                factory2.createObjectLiteralExpression([
                  factory2.createPropertyAssignment("error", catchVariable)
                ])
              )
            )
          ]),
          1 /* SingleLine */
        )
      ),
      factory2.createBlock([
        factory2.createTryStatement(
          /*tryBlock*/
          factory2.createBlock([
            setEmitFlags(
              factory2.createIfStatement(
                factory2.createLogicalAnd(
                  factory2.createLogicalAnd(
                    factory2.createLogicalNot(nonUserCode),
                    factory2.createLogicalNot(done)
                  ),
                  factory2.createAssignment(
                    returnMethod,
                    factory2.createPropertyAccessExpression(iterator, "return")
                  )
                ),
                factory2.createExpressionStatement(createDownlevelAwait(callReturn))
              ),
              1 /* SingleLine */
            )
          ]),
          /*catchClause*/
          void 0,
          /*finallyBlock*/
          setEmitFlags(
            factory2.createBlock([
              setEmitFlags(
                factory2.createIfStatement(
                  errorRecord,
                  factory2.createThrowStatement(
                    factory2.createPropertyAccessExpression(errorRecord, "error")
                  )
                ),
                1 /* SingleLine */
              )
            ]),
            1 /* SingleLine */
          )
        )
      ])
    );
  }
  function parameterVisitor(node) {
    Debug.assertNode(node, isParameter);
    return visitParameter(node);
  }
  function visitParameter(node) {
    if (parametersWithPrecedingObjectRestOrSpread == null ? void 0 : parametersWithPrecedingObjectRestOrSpread.has(node)) {
      return factory2.updateParameterDeclaration(
        node,
        /*modifiers*/
        void 0,
        node.dotDotDotToken,
        isBindingPattern(node.name) ? factory2.getGeneratedNameForNode(node) : node.name,
        /*questionToken*/
        void 0,
        /*type*/
        void 0,
        /*initializer*/
        void 0
      );
    }
    if (node.transformFlags & 65536 /* ContainsObjectRestOrSpread */) {
      return factory2.updateParameterDeclaration(
        node,
        /*modifiers*/
        void 0,
        node.dotDotDotToken,
        factory2.getGeneratedNameForNode(node),
        /*questionToken*/
        void 0,
        /*type*/
        void 0,
        visitNode(node.initializer, visitor, isExpression)
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function collectParametersWithPrecedingObjectRestOrSpread(node) {
    let parameters;
    for (const parameter of node.parameters) {
      if (parameters) {
        parameters.add(parameter);
      } else if (parameter.transformFlags & 65536 /* ContainsObjectRestOrSpread */) {
        parameters = /* @__PURE__ */ new Set();
      }
    }
    return parameters;
  }
  function visitConstructorDeclaration(node) {
    const savedEnclosingFunctionFlags = enclosingFunctionFlags;
    const savedParametersWithPrecedingObjectRestOrSpread = parametersWithPrecedingObjectRestOrSpread;
    enclosingFunctionFlags = getFunctionFlags(node);
    parametersWithPrecedingObjectRestOrSpread = collectParametersWithPrecedingObjectRestOrSpread(node);
    const updated = factory2.updateConstructorDeclaration(
      node,
      node.modifiers,
      visitParameterList(node.parameters, parameterVisitor, context),
      transformFunctionBody(node)
    );
    enclosingFunctionFlags = savedEnclosingFunctionFlags;
    parametersWithPrecedingObjectRestOrSpread = savedParametersWithPrecedingObjectRestOrSpread;
    return updated;
  }
  function visitGetAccessorDeclaration(node) {
    const savedEnclosingFunctionFlags = enclosingFunctionFlags;
    const savedParametersWithPrecedingObjectRestOrSpread = parametersWithPrecedingObjectRestOrSpread;
    enclosingFunctionFlags = getFunctionFlags(node);
    parametersWithPrecedingObjectRestOrSpread = collectParametersWithPrecedingObjectRestOrSpread(node);
    const updated = factory2.updateGetAccessorDeclaration(
      node,
      node.modifiers,
      visitNode(node.name, visitor, isPropertyName),
      visitParameterList(node.parameters, parameterVisitor, context),
      /*type*/
      void 0,
      transformFunctionBody(node)
    );
    enclosingFunctionFlags = savedEnclosingFunctionFlags;
    parametersWithPrecedingObjectRestOrSpread = savedParametersWithPrecedingObjectRestOrSpread;
    return updated;
  }
  function visitSetAccessorDeclaration(node) {
    const savedEnclosingFunctionFlags = enclosingFunctionFlags;
    const savedParametersWithPrecedingObjectRestOrSpread = parametersWithPrecedingObjectRestOrSpread;
    enclosingFunctionFlags = getFunctionFlags(node);
    parametersWithPrecedingObjectRestOrSpread = collectParametersWithPrecedingObjectRestOrSpread(node);
    const updated = factory2.updateSetAccessorDeclaration(
      node,
      node.modifiers,
      visitNode(node.name, visitor, isPropertyName),
      visitParameterList(node.parameters, parameterVisitor, context),
      transformFunctionBody(node)
    );
    enclosingFunctionFlags = savedEnclosingFunctionFlags;
    parametersWithPrecedingObjectRestOrSpread = savedParametersWithPrecedingObjectRestOrSpread;
    return updated;
  }
  function visitMethodDeclaration(node) {
    const savedEnclosingFunctionFlags = enclosingFunctionFlags;
    const savedParametersWithPrecedingObjectRestOrSpread = parametersWithPrecedingObjectRestOrSpread;
    enclosingFunctionFlags = getFunctionFlags(node);
    parametersWithPrecedingObjectRestOrSpread = collectParametersWithPrecedingObjectRestOrSpread(node);
    const updated = factory2.updateMethodDeclaration(
      node,
      enclosingFunctionFlags & 1 /* Generator */ ? visitNodes2(node.modifiers, visitorNoAsyncModifier, isModifierLike) : node.modifiers,
      enclosingFunctionFlags & 2 /* Async */ ? void 0 : node.asteriskToken,
      visitNode(node.name, visitor, isPropertyName),
      visitNode(
        /*node*/
        void 0,
        visitor,
        isQuestionToken
      ),
      /*typeParameters*/
      void 0,
      enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionParameterList(node) : visitParameterList(node.parameters, parameterVisitor, context),
      /*type*/
      void 0,
      enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionBody(node) : transformFunctionBody(node)
    );
    enclosingFunctionFlags = savedEnclosingFunctionFlags;
    parametersWithPrecedingObjectRestOrSpread = savedParametersWithPrecedingObjectRestOrSpread;
    return updated;
  }
  function visitFunctionDeclaration(node) {
    const savedEnclosingFunctionFlags = enclosingFunctionFlags;
    const savedParametersWithPrecedingObjectRestOrSpread = parametersWithPrecedingObjectRestOrSpread;
    enclosingFunctionFlags = getFunctionFlags(node);
    parametersWithPrecedingObjectRestOrSpread = collectParametersWithPrecedingObjectRestOrSpread(node);
    const updated = factory2.updateFunctionDeclaration(
      node,
      enclosingFunctionFlags & 1 /* Generator */ ? visitNodes2(node.modifiers, visitorNoAsyncModifier, isModifier) : node.modifiers,
      enclosingFunctionFlags & 2 /* Async */ ? void 0 : node.asteriskToken,
      node.name,
      /*typeParameters*/
      void 0,
      enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionParameterList(node) : visitParameterList(node.parameters, parameterVisitor, context),
      /*type*/
      void 0,
      enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionBody(node) : transformFunctionBody(node)
    );
    enclosingFunctionFlags = savedEnclosingFunctionFlags;
    parametersWithPrecedingObjectRestOrSpread = savedParametersWithPrecedingObjectRestOrSpread;
    return updated;
  }
  function visitArrowFunction(node) {
    const savedEnclosingFunctionFlags = enclosingFunctionFlags;
    const savedParametersWithPrecedingObjectRestOrSpread = parametersWithPrecedingObjectRestOrSpread;
    enclosingFunctionFlags = getFunctionFlags(node);
    parametersWithPrecedingObjectRestOrSpread = collectParametersWithPrecedingObjectRestOrSpread(node);
    const updated = factory2.updateArrowFunction(
      node,
      node.modifiers,
      /*typeParameters*/
      void 0,
      visitParameterList(node.parameters, parameterVisitor, context),
      /*type*/
      void 0,
      node.equalsGreaterThanToken,
      transformFunctionBody(node)
    );
    enclosingFunctionFlags = savedEnclosingFunctionFlags;
    parametersWithPrecedingObjectRestOrSpread = savedParametersWithPrecedingObjectRestOrSpread;
    return updated;
  }
  function visitFunctionExpression(node) {
    const savedEnclosingFunctionFlags = enclosingFunctionFlags;
    const savedParametersWithPrecedingObjectRestOrSpread = parametersWithPrecedingObjectRestOrSpread;
    enclosingFunctionFlags = getFunctionFlags(node);
    parametersWithPrecedingObjectRestOrSpread = collectParametersWithPrecedingObjectRestOrSpread(node);
    const updated = factory2.updateFunctionExpression(
      node,
      enclosingFunctionFlags & 1 /* Generator */ ? visitNodes2(node.modifiers, visitorNoAsyncModifier, isModifier) : node.modifiers,
      enclosingFunctionFlags & 2 /* Async */ ? void 0 : node.asteriskToken,
      node.name,
      /*typeParameters*/
      void 0,
      enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionParameterList(node) : visitParameterList(node.parameters, parameterVisitor, context),
      /*type*/
      void 0,
      enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionBody(node) : transformFunctionBody(node)
    );
    enclosingFunctionFlags = savedEnclosingFunctionFlags;
    parametersWithPrecedingObjectRestOrSpread = savedParametersWithPrecedingObjectRestOrSpread;
    return updated;
  }
  function transformAsyncGeneratorFunctionParameterList(node) {
    if (isSimpleParameterList(node.parameters)) {
      return visitParameterList(node.parameters, visitor, context);
    }
    const newParameters = [];
    for (const parameter of node.parameters) {
      if (parameter.initializer || parameter.dotDotDotToken) {
        break;
      }
      const newParameter = factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        factory2.getGeneratedNameForNode(parameter.name, 8 /* ReservedInNestedScopes */)
      );
      newParameters.push(newParameter);
    }
    const newParametersArray = factory2.createNodeArray(newParameters);
    setTextRange(newParametersArray, node.parameters);
    return newParametersArray;
  }
  function transformAsyncGeneratorFunctionBody(node) {
    const innerParameters = !isSimpleParameterList(node.parameters) ? visitParameterList(node.parameters, visitor, context) : void 0;
    resumeLexicalEnvironment();
    const savedCapturedSuperProperties = capturedSuperProperties;
    const savedHasSuperElementAccess = hasSuperElementAccess;
    capturedSuperProperties = /* @__PURE__ */ new Set();
    hasSuperElementAccess = false;
    const outerStatements = [];
    let asyncBody = factory2.updateBlock(node.body, visitNodes2(node.body.statements, visitor, isStatement));
    asyncBody = factory2.updateBlock(asyncBody, factory2.mergeLexicalEnvironment(asyncBody.statements, appendObjectRestAssignmentsIfNeeded(endLexicalEnvironment(), node)));
    const returnStatement = factory2.createReturnStatement(
      emitHelpers().createAsyncGeneratorHelper(
        factory2.createFunctionExpression(
          /*modifiers*/
          void 0,
          factory2.createToken(42 /* AsteriskToken */),
          node.name && factory2.getGeneratedNameForNode(node.name),
          /*typeParameters*/
          void 0,
          innerParameters ?? [],
          /*type*/
          void 0,
          asyncBody
        ),
        !!(hierarchyFacts & 1 /* HasLexicalThis */)
      )
    );
    const emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */) || resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */));
    if (emitSuperHelpers) {
      enableSubstitutionForAsyncMethodsWithSuper();
      const variableStatement = createSuperAccessVariableStatement(factory2, resolver, node, capturedSuperProperties);
      substitutedSuperAccessors[getNodeId(variableStatement)] = true;
      insertStatementsAfterStandardPrologue(outerStatements, [variableStatement]);
    }
    outerStatements.push(returnStatement);
    const block = factory2.updateBlock(node.body, outerStatements);
    if (emitSuperHelpers && hasSuperElementAccess) {
      if (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */)) {
        addEmitHelper(block, advancedAsyncSuperHelper);
      } else if (resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */)) {
        addEmitHelper(block, asyncSuperHelper);
      }
    }
    capturedSuperProperties = savedCapturedSuperProperties;
    hasSuperElementAccess = savedHasSuperElementAccess;
    return block;
  }
  function transformFunctionBody(node) {
    resumeLexicalEnvironment();
    let statementOffset = 0;
    const statements = [];
    const body = visitNode(node.body, visitor, isConciseBody) ?? factory2.createBlock([]);
    if (isBlock(body)) {
      statementOffset = factory2.copyPrologue(
        body.statements,
        statements,
        /*ensureUseStrict*/
        false,
        visitor
      );
    }
    addRange(statements, appendObjectRestAssignmentsIfNeeded(
      /*statements*/
      void 0,
      node
    ));
    const leadingStatements = endLexicalEnvironment();
    if (statementOffset > 0 || some(statements) || some(leadingStatements)) {
      const block = factory2.converters.convertToFunctionBlock(
        body,
        /*multiLine*/
        true
      );
      insertStatementsAfterStandardPrologue(statements, leadingStatements);
      addRange(statements, block.statements.slice(statementOffset));
      return factory2.updateBlock(block, setTextRange(factory2.createNodeArray(statements), block.statements));
    }
    return body;
  }
  function appendObjectRestAssignmentsIfNeeded(statements, node) {
    let containsPrecedingObjectRestOrSpread = false;
    for (const parameter of node.parameters) {
      if (containsPrecedingObjectRestOrSpread) {
        if (isBindingPattern(parameter.name)) {
          if (parameter.name.elements.length > 0) {
            const declarations = flattenDestructuringBinding(
              parameter,
              visitor,
              context,
              0 /* All */,
              factory2.getGeneratedNameForNode(parameter)
            );
            if (some(declarations)) {
              const declarationList = factory2.createVariableDeclarationList(declarations);
              const statement = factory2.createVariableStatement(
                /*modifiers*/
                void 0,
                declarationList
              );
              setEmitFlags(statement, 2097152 /* CustomPrologue */);
              statements = append(statements, statement);
            }
          } else if (parameter.initializer) {
            const name = factory2.getGeneratedNameForNode(parameter);
            const initializer = visitNode(parameter.initializer, visitor, isExpression);
            const assignment = factory2.createAssignment(name, initializer);
            const statement = factory2.createExpressionStatement(assignment);
            setEmitFlags(statement, 2097152 /* CustomPrologue */);
            statements = append(statements, statement);
          }
        } else if (parameter.initializer) {
          const name = factory2.cloneNode(parameter.name);
          setTextRange(name, parameter.name);
          setEmitFlags(name, 96 /* NoSourceMap */);
          const initializer = visitNode(parameter.initializer, visitor, isExpression);
          addEmitFlags(initializer, 96 /* NoSourceMap */ | 3072 /* NoComments */);
          const assignment = factory2.createAssignment(name, initializer);
          setTextRange(assignment, parameter);
          setEmitFlags(assignment, 3072 /* NoComments */);
          const block = factory2.createBlock([factory2.createExpressionStatement(assignment)]);
          setTextRange(block, parameter);
          setEmitFlags(block, 1 /* SingleLine */ | 64 /* NoTrailingSourceMap */ | 768 /* NoTokenSourceMaps */ | 3072 /* NoComments */);
          const typeCheck = factory2.createTypeCheck(factory2.cloneNode(parameter.name), "undefined");
          const statement = factory2.createIfStatement(typeCheck, block);
          startOnNewLine(statement);
          setTextRange(statement, parameter);
          setEmitFlags(statement, 768 /* NoTokenSourceMaps */ | 64 /* NoTrailingSourceMap */ | 2097152 /* CustomPrologue */ | 3072 /* NoComments */);
          statements = append(statements, statement);
        }
      } else if (parameter.transformFlags & 65536 /* ContainsObjectRestOrSpread */) {
        containsPrecedingObjectRestOrSpread = true;
        const declarations = flattenDestructuringBinding(
          parameter,
          visitor,
          context,
          1 /* ObjectRest */,
          factory2.getGeneratedNameForNode(parameter),
          /*hoistTempVariables*/
          false,
          /*skipInitializer*/
          true
        );
        if (some(declarations)) {
          const declarationList = factory2.createVariableDeclarationList(declarations);
          const statement = factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            declarationList
          );
          setEmitFlags(statement, 2097152 /* CustomPrologue */);
          statements = append(statements, statement);
        }
      }
    }
    return statements;
  }
  function enableSubstitutionForAsyncMethodsWithSuper() {
    if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
      enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
      context.enableSubstitution(213 /* CallExpression */);
      context.enableSubstitution(211 /* PropertyAccessExpression */);
      context.enableSubstitution(212 /* ElementAccessExpression */);
      context.enableEmitNotification(263 /* ClassDeclaration */);
      context.enableEmitNotification(174 /* MethodDeclaration */);
      context.enableEmitNotification(177 /* GetAccessor */);
      context.enableEmitNotification(178 /* SetAccessor */);
      context.enableEmitNotification(176 /* Constructor */);
      context.enableEmitNotification(243 /* VariableStatement */);
    }
  }
  function onEmitNode(hint, node, emitCallback) {
    if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
      const superContainerFlags = (resolver.hasNodeCheckFlag(node, 128 /* MethodWithSuperPropertyAccessInAsync */) ? 128 /* MethodWithSuperPropertyAccessInAsync */ : 0) | (resolver.hasNodeCheckFlag(node, 256 /* MethodWithSuperPropertyAssignmentInAsync */) ? 256 /* MethodWithSuperPropertyAssignmentInAsync */ : 0);
      if (superContainerFlags !== enclosingSuperContainerFlags) {
        const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
        enclosingSuperContainerFlags = superContainerFlags;
        previousOnEmitNode(hint, node, emitCallback);
        enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
        return;
      }
    } else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) {
      const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
      enclosingSuperContainerFlags = 0;
      previousOnEmitNode(hint, node, emitCallback);
      enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
      return;
    }
    previousOnEmitNode(hint, node, emitCallback);
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
      return substituteExpression(node);
    }
    return node;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 211 /* PropertyAccessExpression */:
        return substitutePropertyAccessExpression(node);
      case 212 /* ElementAccessExpression */:
        return substituteElementAccessExpression(node);
      case 213 /* CallExpression */:
        return substituteCallExpression(node);
    }
    return node;
  }
  function substitutePropertyAccessExpression(node) {
    if (node.expression.kind === 108 /* SuperKeyword */) {
      return setTextRange(
        factory2.createPropertyAccessExpression(
          factory2.createUniqueName("_super", 16 /* Optimistic */ | 32 /* FileLevel */),
          node.name
        ),
        node
      );
    }
    return node;
  }
  function substituteElementAccessExpression(node) {
    if (node.expression.kind === 108 /* SuperKeyword */) {
      return createSuperElementAccessInAsyncMethod(
        node.argumentExpression,
        node
      );
    }
    return node;
  }
  function substituteCallExpression(node) {
    const expression = node.expression;
    if (isSuperProperty(expression)) {
      const argumentExpression = isPropertyAccessExpression(expression) ? substitutePropertyAccessExpression(expression) : substituteElementAccessExpression(expression);
      return factory2.createCallExpression(
        factory2.createPropertyAccessExpression(argumentExpression, "call"),
        /*typeArguments*/
        void 0,
        [
          factory2.createThis(),
          ...node.arguments
        ]
      );
    }
    return node;
  }
  function isSuperContainer(node) {
    const kind = node.kind;
    return kind === 263 /* ClassDeclaration */ || kind === 176 /* Constructor */ || kind === 174 /* MethodDeclaration */ || kind === 177 /* GetAccessor */ || kind === 178 /* SetAccessor */;
  }
  function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
    if (enclosingSuperContainerFlags & 256 /* MethodWithSuperPropertyAssignmentInAsync */) {
      return setTextRange(
        factory2.createPropertyAccessExpression(
          factory2.createCallExpression(
            factory2.createIdentifier("_superIndex"),
            /*typeArguments*/
            void 0,
            [argumentExpression]
          ),
          "value"
        ),
        location
      );
    } else {
      return setTextRange(
        factory2.createCallExpression(
          factory2.createIdentifier("_superIndex"),
          /*typeArguments*/
          void 0,
          [argumentExpression]
        ),
        location
      );
    }
  }
}

// src/compiler/transformers/es2019.ts
function transformES2019(context) {
  const factory2 = context.factory;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitor(node) {
    if ((node.transformFlags & 64 /* ContainsES2019 */) === 0) {
      return node;
    }
    switch (node.kind) {
      case 299 /* CatchClause */:
        return visitCatchClause(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitCatchClause(node) {
    if (!node.variableDeclaration) {
      return factory2.updateCatchClause(
        node,
        factory2.createVariableDeclaration(factory2.createTempVariable(
          /*recordTempVariable*/
          void 0
        )),
        visitNode(node.block, visitor, isBlock)
      );
    }
    return visitEachChild(node, visitor, context);
  }
}

// src/compiler/transformers/es2020.ts
function transformES2020(context) {
  const {
    factory: factory2,
    hoistVariableDeclaration
  } = context;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitor(node) {
    if ((node.transformFlags & 32 /* ContainsES2020 */) === 0) {
      return node;
    }
    switch (node.kind) {
      case 213 /* CallExpression */: {
        const updated = visitNonOptionalCallExpression(
          node,
          /*captureThisArg*/
          false
        );
        Debug.assertNotNode(updated, isSyntheticReference);
        return updated;
      }
      case 211 /* PropertyAccessExpression */:
      case 212 /* ElementAccessExpression */:
        if (isOptionalChain(node)) {
          const updated = visitOptionalExpression(
            node,
            /*captureThisArg*/
            false,
            /*isDelete*/
            false
          );
          Debug.assertNotNode(updated, isSyntheticReference);
          return updated;
        }
        return visitEachChild(node, visitor, context);
      case 226 /* BinaryExpression */:
        if (node.operatorToken.kind === 61 /* QuestionQuestionToken */) {
          return transformNullishCoalescingExpression(node);
        }
        return visitEachChild(node, visitor, context);
      case 220 /* DeleteExpression */:
        return visitDeleteExpression(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function flattenChain(chain) {
    Debug.assertNotNode(chain, isNonNullChain);
    const links = [chain];
    while (!chain.questionDotToken && !isTaggedTemplateExpression(chain)) {
      chain = cast(skipPartiallyEmittedExpressions(chain.expression), isOptionalChain);
      Debug.assertNotNode(chain, isNonNullChain);
      links.unshift(chain);
    }
    return { expression: chain.expression, chain: links };
  }
  function visitNonOptionalParenthesizedExpression(node, captureThisArg, isDelete) {
    const expression = visitNonOptionalExpression(node.expression, captureThisArg, isDelete);
    if (isSyntheticReference(expression)) {
      return factory2.createSyntheticReferenceExpression(factory2.updateParenthesizedExpression(node, expression.expression), expression.thisArg);
    }
    return factory2.updateParenthesizedExpression(node, expression);
  }
  function visitNonOptionalPropertyOrElementAccessExpression(node, captureThisArg, isDelete) {
    if (isOptionalChain(node)) {
      return visitOptionalExpression(node, captureThisArg, isDelete);
    }
    let expression = visitNode(node.expression, visitor, isExpression);
    Debug.assertNotNode(expression, isSyntheticReference);
    let thisArg;
    if (captureThisArg) {
      if (!isSimpleCopiableExpression(expression)) {
        thisArg = factory2.createTempVariable(hoistVariableDeclaration);
        expression = factory2.createAssignment(thisArg, expression);
      } else {
        thisArg = expression;
      }
    }
    expression = node.kind === 211 /* PropertyAccessExpression */ ? factory2.updatePropertyAccessExpression(node, expression, visitNode(node.name, visitor, isIdentifier)) : factory2.updateElementAccessExpression(node, expression, visitNode(node.argumentExpression, visitor, isExpression));
    return thisArg ? factory2.createSyntheticReferenceExpression(expression, thisArg) : expression;
  }
  function visitNonOptionalCallExpression(node, captureThisArg) {
    if (isOptionalChain(node)) {
      return visitOptionalExpression(
        node,
        captureThisArg,
        /*isDelete*/
        false
      );
    }
    if (isParenthesizedExpression(node.expression) && isOptionalChain(skipParentheses(node.expression))) {
      const expression = visitNonOptionalParenthesizedExpression(
        node.expression,
        /*captureThisArg*/
        true,
        /*isDelete*/
        false
      );
      const args = visitNodes2(node.arguments, visitor, isExpression);
      if (isSyntheticReference(expression)) {
        return setTextRange(factory2.createFunctionCallCall(expression.expression, expression.thisArg, args), node);
      }
      return factory2.updateCallExpression(
        node,
        expression,
        /*typeArguments*/
        void 0,
        args
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitNonOptionalExpression(node, captureThisArg, isDelete) {
    switch (node.kind) {
      case 217 /* ParenthesizedExpression */:
        return visitNonOptionalParenthesizedExpression(node, captureThisArg, isDelete);
      case 211 /* PropertyAccessExpression */:
      case 212 /* ElementAccessExpression */:
        return visitNonOptionalPropertyOrElementAccessExpression(node, captureThisArg, isDelete);
      case 213 /* CallExpression */:
        return visitNonOptionalCallExpression(node, captureThisArg);
      default:
        return visitNode(node, visitor, isExpression);
    }
  }
  function visitOptionalExpression(node, captureThisArg, isDelete) {
    const { expression, chain } = flattenChain(node);
    const left = visitNonOptionalExpression(
      skipPartiallyEmittedExpressions(expression),
      isCallChain(chain[0]),
      /*isDelete*/
      false
    );
    let leftThisArg = isSyntheticReference(left) ? left.thisArg : void 0;
    let capturedLeft = isSyntheticReference(left) ? left.expression : left;
    let leftExpression = factory2.restoreOuterExpressions(expression, capturedLeft, 8 /* PartiallyEmittedExpressions */);
    if (!isSimpleCopiableExpression(capturedLeft)) {
      capturedLeft = factory2.createTempVariable(hoistVariableDeclaration);
      leftExpression = factory2.createAssignment(capturedLeft, leftExpression);
    }
    let rightExpression = capturedLeft;
    let thisArg;
    for (let i = 0; i < chain.length; i++) {
      const segment = chain[i];
      switch (segment.kind) {
        case 211 /* PropertyAccessExpression */:
        case 212 /* ElementAccessExpression */:
          if (i === chain.length - 1 && captureThisArg) {
            if (!isSimpleCopiableExpression(rightExpression)) {
              thisArg = factory2.createTempVariable(hoistVariableDeclaration);
              rightExpression = factory2.createAssignment(thisArg, rightExpression);
            } else {
              thisArg = rightExpression;
            }
          }
          rightExpression = segment.kind === 211 /* PropertyAccessExpression */ ? factory2.createPropertyAccessExpression(rightExpression, visitNode(segment.name, visitor, isIdentifier)) : factory2.createElementAccessExpression(rightExpression, visitNode(segment.argumentExpression, visitor, isExpression));
          break;
        case 213 /* CallExpression */:
          if (i === 0 && leftThisArg) {
            if (!isGeneratedIdentifier(leftThisArg)) {
              leftThisArg = factory2.cloneNode(leftThisArg);
              addEmitFlags(leftThisArg, 3072 /* NoComments */);
            }
            rightExpression = factory2.createFunctionCallCall(
              rightExpression,
              leftThisArg.kind === 108 /* SuperKeyword */ ? factory2.createThis() : leftThisArg,
              visitNodes2(segment.arguments, visitor, isExpression)
            );
          } else {
            rightExpression = factory2.createCallExpression(
              rightExpression,
              /*typeArguments*/
              void 0,
              visitNodes2(segment.arguments, visitor, isExpression)
            );
          }
          break;
      }
      setOriginalNode(rightExpression, segment);
    }
    const target = isDelete ? factory2.createConditionalExpression(
      createNotNullCondition(
        leftExpression,
        capturedLeft,
        /*invert*/
        true
      ),
      /*questionToken*/
      void 0,
      factory2.createTrue(),
      /*colonToken*/
      void 0,
      factory2.createDeleteExpression(rightExpression)
    ) : factory2.createConditionalExpression(
      createNotNullCondition(
        leftExpression,
        capturedLeft,
        /*invert*/
        true
      ),
      /*questionToken*/
      void 0,
      factory2.createVoidZero(),
      /*colonToken*/
      void 0,
      rightExpression
    );
    setTextRange(target, node);
    return thisArg ? factory2.createSyntheticReferenceExpression(target, thisArg) : target;
  }
  function createNotNullCondition(left, right, invert) {
    return factory2.createBinaryExpression(
      factory2.createBinaryExpression(
        left,
        factory2.createToken(invert ? 37 /* EqualsEqualsEqualsToken */ : 38 /* ExclamationEqualsEqualsToken */),
        factory2.createNull()
      ),
      factory2.createToken(invert ? 57 /* BarBarToken */ : 56 /* AmpersandAmpersandToken */),
      factory2.createBinaryExpression(
        right,
        factory2.createToken(invert ? 37 /* EqualsEqualsEqualsToken */ : 38 /* ExclamationEqualsEqualsToken */),
        factory2.createVoidZero()
      )
    );
  }
  function transformNullishCoalescingExpression(node) {
    let left = visitNode(node.left, visitor, isExpression);
    let right = left;
    if (!isSimpleCopiableExpression(left)) {
      right = factory2.createTempVariable(hoistVariableDeclaration);
      left = factory2.createAssignment(right, left);
    }
    return setTextRange(
      factory2.createConditionalExpression(
        createNotNullCondition(left, right),
        /*questionToken*/
        void 0,
        right,
        /*colonToken*/
        void 0,
        visitNode(node.right, visitor, isExpression)
      ),
      node
    );
  }
  function visitDeleteExpression(node) {
    return isOptionalChain(skipParentheses(node.expression)) ? setOriginalNode(visitNonOptionalExpression(
      node.expression,
      /*captureThisArg*/
      false,
      /*isDelete*/
      true
    ), node) : factory2.updateDeleteExpression(node, visitNode(node.expression, visitor, isExpression));
  }
}

// src/compiler/transformers/es2021.ts
function transformES2021(context) {
  const {
    hoistVariableDeclaration,
    factory: factory2
  } = context;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitor(node) {
    if ((node.transformFlags & 16 /* ContainsES2021 */) === 0) {
      return node;
    }
    if (isLogicalOrCoalescingAssignmentExpression(node)) {
      return transformLogicalAssignment(node);
    }
    return visitEachChild(node, visitor, context);
  }
  function transformLogicalAssignment(binaryExpression) {
    const operator = binaryExpression.operatorToken;
    const nonAssignmentOperator = getNonAssignmentOperatorForCompoundAssignment(operator.kind);
    let left = skipParentheses(visitNode(binaryExpression.left, visitor, isLeftHandSideExpression));
    let assignmentTarget = left;
    const right = skipParentheses(visitNode(binaryExpression.right, visitor, isExpression));
    if (isAccessExpression(left)) {
      const propertyAccessTargetSimpleCopiable = isSimpleCopiableExpression(left.expression);
      const propertyAccessTarget = propertyAccessTargetSimpleCopiable ? left.expression : factory2.createTempVariable(hoistVariableDeclaration);
      const propertyAccessTargetAssignment = propertyAccessTargetSimpleCopiable ? left.expression : factory2.createAssignment(
        propertyAccessTarget,
        left.expression
      );
      if (isPropertyAccessExpression(left)) {
        assignmentTarget = factory2.createPropertyAccessExpression(
          propertyAccessTarget,
          left.name
        );
        left = factory2.createPropertyAccessExpression(
          propertyAccessTargetAssignment,
          left.name
        );
      } else {
        const elementAccessArgumentSimpleCopiable = isSimpleCopiableExpression(left.argumentExpression);
        const elementAccessArgument = elementAccessArgumentSimpleCopiable ? left.argumentExpression : factory2.createTempVariable(hoistVariableDeclaration);
        assignmentTarget = factory2.createElementAccessExpression(
          propertyAccessTarget,
          elementAccessArgument
        );
        left = factory2.createElementAccessExpression(
          propertyAccessTargetAssignment,
          elementAccessArgumentSimpleCopiable ? left.argumentExpression : factory2.createAssignment(
            elementAccessArgument,
            left.argumentExpression
          )
        );
      }
    }
    return factory2.createBinaryExpression(
      left,
      nonAssignmentOperator,
      factory2.createParenthesizedExpression(
        factory2.createAssignment(
          assignmentTarget,
          right
        )
      )
    );
  }
}

// src/compiler/transformers/esnext.ts
function transformESNext(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    hoistVariableDeclaration,
    startLexicalEnvironment,
    endLexicalEnvironment
  } = context;
  let exportBindings;
  let exportVars;
  let defaultExportBinding;
  let exportEqualsBinding;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    const visited = visitNode(node, visitor, isSourceFile);
    addEmitHelpers(visited, context.readEmitHelpers());
    exportVars = void 0;
    exportBindings = void 0;
    defaultExportBinding = void 0;
    return visited;
  }
  function visitor(node) {
    if ((node.transformFlags & 4 /* ContainsESNext */) === 0) {
      return node;
    }
    switch (node.kind) {
      case 307 /* SourceFile */:
        return visitSourceFile(node);
      case 241 /* Block */:
        return visitBlock(node);
      case 248 /* ForStatement */:
        return visitForStatement(node);
      case 250 /* ForOfStatement */:
        return visitForOfStatement(node);
      case 255 /* SwitchStatement */:
        return visitSwitchStatement(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitSourceFile(node) {
    const usingKind = getUsingKindOfStatements(node.statements);
    if (usingKind) {
      startLexicalEnvironment();
      exportBindings = new IdentifierNameMap();
      exportVars = [];
      const prologueCount = countPrologueStatements(node.statements);
      const topLevelStatements = [];
      addRange(topLevelStatements, visitArray(node.statements, visitor, isStatement, 0, prologueCount));
      let pos = prologueCount;
      while (pos < node.statements.length) {
        const statement = node.statements[pos];
        if (getUsingKind(statement) !== 0 /* None */) {
          if (pos > prologueCount) {
            addRange(topLevelStatements, visitNodes2(node.statements, visitor, isStatement, prologueCount, pos - prologueCount));
          }
          break;
        }
        pos++;
      }
      Debug.assert(pos < node.statements.length, "Should have encountered at least one 'using' statement.");
      const envBinding = createEnvBinding();
      const bodyStatements = transformUsingDeclarations(node.statements, pos, node.statements.length, envBinding, topLevelStatements);
      if (exportBindings.size) {
        append(
          topLevelStatements,
          factory2.createExportDeclaration(
            /*modifiers*/
            void 0,
            /*isTypeOnly*/
            false,
            factory2.createNamedExports(arrayFrom(exportBindings.values()))
          )
        );
      }
      addRange(topLevelStatements, endLexicalEnvironment());
      if (exportVars.length) {
        topLevelStatements.push(factory2.createVariableStatement(
          factory2.createModifiersFromModifierFlags(32 /* Export */),
          factory2.createVariableDeclarationList(
            exportVars,
            1 /* Let */
          )
        ));
      }
      addRange(topLevelStatements, createDownlevelUsingStatements(bodyStatements, envBinding, usingKind === 2 /* Async */));
      if (exportEqualsBinding) {
        topLevelStatements.push(factory2.createExportAssignment(
          /*modifiers*/
          void 0,
          /*isExportEquals*/
          true,
          exportEqualsBinding
        ));
      }
      return factory2.updateSourceFile(node, topLevelStatements);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitBlock(node) {
    const usingKind = getUsingKindOfStatements(node.statements);
    if (usingKind) {
      const prologueCount = countPrologueStatements(node.statements);
      const envBinding = createEnvBinding();
      return factory2.updateBlock(
        node,
        [
          ...visitArray(node.statements, visitor, isStatement, 0, prologueCount),
          ...createDownlevelUsingStatements(
            transformUsingDeclarations(
              node.statements,
              prologueCount,
              node.statements.length,
              envBinding,
              /*topLevelStatements*/
              void 0
            ),
            envBinding,
            usingKind === 2 /* Async */
          )
        ]
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitForStatement(node) {
    if (node.initializer && isUsingVariableDeclarationList(node.initializer)) {
      return visitNode(
        factory2.createBlock([
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            node.initializer
          ),
          factory2.updateForStatement(
            node,
            /*initializer*/
            void 0,
            node.condition,
            node.incrementor,
            node.statement
          )
        ]),
        visitor,
        isStatement
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitForOfStatement(node) {
    if (isUsingVariableDeclarationList(node.initializer)) {
      const forInitializer = node.initializer;
      const forDecl = firstOrUndefined(forInitializer.declarations) || factory2.createVariableDeclaration(factory2.createTempVariable(
        /*recordTempVariable*/
        void 0
      ));
      const isAwaitUsing = getUsingKindOfVariableDeclarationList(forInitializer) === 2 /* Async */;
      const temp = factory2.getGeneratedNameForNode(forDecl.name);
      const usingVar = factory2.updateVariableDeclaration(
        forDecl,
        forDecl.name,
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        temp
      );
      const usingVarList = factory2.createVariableDeclarationList([usingVar], isAwaitUsing ? 6 /* AwaitUsing */ : 4 /* Using */);
      const usingVarStatement = factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        usingVarList
      );
      return visitNode(
        factory2.updateForOfStatement(
          node,
          node.awaitModifier,
          factory2.createVariableDeclarationList([
            factory2.createVariableDeclaration(temp)
          ], 2 /* Const */),
          node.expression,
          isBlock(node.statement) ? factory2.updateBlock(node.statement, [
            usingVarStatement,
            ...node.statement.statements
          ]) : factory2.createBlock(
            [
              usingVarStatement,
              node.statement
            ],
            /*multiLine*/
            true
          )
        ),
        visitor,
        isStatement
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCaseOrDefaultClause(node, envBinding) {
    if (getUsingKindOfStatements(node.statements) !== 0 /* None */) {
      if (isCaseClause(node)) {
        return factory2.updateCaseClause(
          node,
          visitNode(node.expression, visitor, isExpression),
          transformUsingDeclarations(
            node.statements,
            /*start*/
            0,
            node.statements.length,
            envBinding,
            /*topLevelStatements*/
            void 0
          )
        );
      } else {
        return factory2.updateDefaultClause(
          node,
          transformUsingDeclarations(
            node.statements,
            /*start*/
            0,
            node.statements.length,
            envBinding,
            /*topLevelStatements*/
            void 0
          )
        );
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitSwitchStatement(node) {
    const usingKind = getUsingKindOfCaseOrDefaultClauses(node.caseBlock.clauses);
    if (usingKind) {
      const envBinding = createEnvBinding();
      return createDownlevelUsingStatements(
        [
          factory2.updateSwitchStatement(
            node,
            visitNode(node.expression, visitor, isExpression),
            factory2.updateCaseBlock(
              node.caseBlock,
              node.caseBlock.clauses.map((clause) => visitCaseOrDefaultClause(clause, envBinding))
            )
          )
        ],
        envBinding,
        usingKind === 2 /* Async */
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function transformUsingDeclarations(statementsIn, start, end, envBinding, topLevelStatements) {
    const statements = [];
    for (let i = start; i < end; i++) {
      const statement = statementsIn[i];
      const usingKind = getUsingKind(statement);
      if (usingKind) {
        Debug.assertNode(statement, isVariableStatement);
        const declarations = [];
        for (let declaration of statement.declarationList.declarations) {
          if (!isIdentifier(declaration.name)) {
            declarations.length = 0;
            break;
          }
          if (isNamedEvaluation(declaration)) {
            declaration = transformNamedEvaluation(context, declaration);
          }
          const initializer = visitNode(declaration.initializer, visitor, isExpression) ?? factory2.createVoidZero();
          declarations.push(factory2.updateVariableDeclaration(
            declaration,
            declaration.name,
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            emitHelpers().createAddDisposableResourceHelper(
              envBinding,
              initializer,
              usingKind === 2 /* Async */
            )
          ));
        }
        if (declarations.length) {
          const varList = factory2.createVariableDeclarationList(declarations, 2 /* Const */);
          setOriginalNode(varList, statement.declarationList);
          setTextRange(varList, statement.declarationList);
          hoistOrAppendNode(factory2.updateVariableStatement(
            statement,
            /*modifiers*/
            void 0,
            varList
          ));
          continue;
        }
      }
      const result = visitor(statement);
      if (isArray(result)) {
        result.forEach(hoistOrAppendNode);
      } else if (result) {
        hoistOrAppendNode(result);
      }
    }
    return statements;
    function hoistOrAppendNode(node) {
      Debug.assertNode(node, isStatement);
      append(statements, hoist(node));
    }
    function hoist(node) {
      if (!topLevelStatements) return node;
      switch (node.kind) {
        case 272 /* ImportDeclaration */:
        case 271 /* ImportEqualsDeclaration */:
        case 278 /* ExportDeclaration */:
        case 262 /* FunctionDeclaration */:
          return hoistImportOrExportOrHoistedDeclaration(node, topLevelStatements);
        case 277 /* ExportAssignment */:
          return hoistExportAssignment(node);
        case 263 /* ClassDeclaration */:
          return hoistClassDeclaration(node);
        case 243 /* VariableStatement */:
          return hoistVariableStatement(node);
      }
      return node;
    }
  }
  function hoistImportOrExportOrHoistedDeclaration(node, topLevelStatements) {
    topLevelStatements.push(node);
    return void 0;
  }
  function hoistExportAssignment(node) {
    return node.isExportEquals ? hoistExportEquals(node) : hoistExportDefault(node);
  }
  function hoistExportDefault(node) {
    if (defaultExportBinding) {
      return node;
    }
    defaultExportBinding = factory2.createUniqueName("_default", 8 /* ReservedInNestedScopes */ | 32 /* FileLevel */ | 16 /* Optimistic */);
    hoistBindingIdentifier(
      defaultExportBinding,
      /*isExport*/
      true,
      "default",
      node
    );
    let expression = node.expression;
    let innerExpression = skipOuterExpressions(expression);
    if (isNamedEvaluation(innerExpression)) {
      innerExpression = transformNamedEvaluation(
        context,
        innerExpression,
        /*ignoreEmptyStringLiteral*/
        false,
        "default"
      );
      expression = factory2.restoreOuterExpressions(expression, innerExpression);
    }
    const assignment = factory2.createAssignment(defaultExportBinding, expression);
    return factory2.createExpressionStatement(assignment);
  }
  function hoistExportEquals(node) {
    if (exportEqualsBinding) {
      return node;
    }
    exportEqualsBinding = factory2.createUniqueName("_default", 8 /* ReservedInNestedScopes */ | 32 /* FileLevel */ | 16 /* Optimistic */);
    hoistVariableDeclaration(exportEqualsBinding);
    const assignment = factory2.createAssignment(exportEqualsBinding, node.expression);
    return factory2.createExpressionStatement(assignment);
  }
  function hoistClassDeclaration(node) {
    if (!node.name && defaultExportBinding) {
      return node;
    }
    const isExported = hasSyntacticModifier(node, 32 /* Export */);
    const isDefault = hasSyntacticModifier(node, 2048 /* Default */);
    let expression = factory2.converters.convertToClassExpression(node);
    if (node.name) {
      hoistBindingIdentifier(
        factory2.getLocalName(node),
        isExported && !isDefault,
        /*exportAlias*/
        void 0,
        node
      );
      expression = factory2.createAssignment(factory2.getDeclarationName(node), expression);
      if (isNamedEvaluation(expression)) {
        expression = transformNamedEvaluation(
          context,
          expression,
          /*ignoreEmptyStringLiteral*/
          false
        );
      }
      setOriginalNode(expression, node);
      setSourceMapRange(expression, node);
      setCommentRange(expression, node);
    }
    if (isDefault && !defaultExportBinding) {
      defaultExportBinding = factory2.createUniqueName("_default", 8 /* ReservedInNestedScopes */ | 32 /* FileLevel */ | 16 /* Optimistic */);
      hoistBindingIdentifier(
        defaultExportBinding,
        /*isExport*/
        true,
        "default",
        node
      );
      expression = factory2.createAssignment(defaultExportBinding, expression);
      if (isNamedEvaluation(expression)) {
        expression = transformNamedEvaluation(
          context,
          expression,
          /*ignoreEmptyStringLiteral*/
          false,
          "default"
        );
      }
      setOriginalNode(expression, node);
    }
    return factory2.createExpressionStatement(expression);
  }
  function hoistVariableStatement(node) {
    let expressions;
    const isExported = hasSyntacticModifier(node, 32 /* Export */);
    for (const variable of node.declarationList.declarations) {
      hoistBindingElement(variable, isExported, variable);
      if (variable.initializer) {
        expressions = append(expressions, hoistInitializedVariable(variable));
      }
    }
    if (expressions) {
      const statement = factory2.createExpressionStatement(factory2.inlineExpressions(expressions));
      setOriginalNode(statement, node);
      setCommentRange(statement, node);
      setSourceMapRange(statement, node);
      return statement;
    }
    return void 0;
  }
  function hoistInitializedVariable(node) {
    Debug.assertIsDefined(node.initializer);
    let target;
    if (isIdentifier(node.name)) {
      target = factory2.cloneNode(node.name);
      setEmitFlags(target, getEmitFlags(target) & ~(32768 /* LocalName */ | 16384 /* ExportName */ | 65536 /* InternalName */));
    } else {
      target = factory2.converters.convertToAssignmentPattern(node.name);
    }
    const assignment = factory2.createAssignment(target, node.initializer);
    setOriginalNode(assignment, node);
    setCommentRange(assignment, node);
    setSourceMapRange(assignment, node);
    return assignment;
  }
  function hoistBindingElement(node, isExportedDeclaration, original) {
    if (isBindingPattern(node.name)) {
      for (const element of node.name.elements) {
        if (!isOmittedExpression(element)) {
          hoistBindingElement(element, isExportedDeclaration, original);
        }
      }
    } else {
      hoistBindingIdentifier(
        node.name,
        isExportedDeclaration,
        /*exportAlias*/
        void 0,
        original
      );
    }
  }
  function hoistBindingIdentifier(node, isExport, exportAlias, original) {
    const name = isGeneratedIdentifier(node) ? node : factory2.cloneNode(node);
    if (isExport) {
      if (exportAlias === void 0 && !isLocalName(name)) {
        const varDecl = factory2.createVariableDeclaration(name);
        if (original) {
          setOriginalNode(varDecl, original);
        }
        exportVars.push(varDecl);
        return;
      }
      const localName = exportAlias !== void 0 ? name : void 0;
      const exportName = exportAlias !== void 0 ? exportAlias : name;
      const specifier = factory2.createExportSpecifier(
        /*isTypeOnly*/
        false,
        localName,
        exportName
      );
      if (original) {
        setOriginalNode(specifier, original);
      }
      exportBindings.set(name, specifier);
    }
    hoistVariableDeclaration(name);
  }
  function createEnvBinding() {
    return factory2.createUniqueName("env");
  }
  function createDownlevelUsingStatements(bodyStatements, envBinding, async) {
    const statements = [];
    const envObject = factory2.createObjectLiteralExpression([
      factory2.createPropertyAssignment("stack", factory2.createArrayLiteralExpression()),
      factory2.createPropertyAssignment("error", factory2.createVoidZero()),
      factory2.createPropertyAssignment("hasError", factory2.createFalse())
    ]);
    const envVar = factory2.createVariableDeclaration(
      envBinding,
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      envObject
    );
    const envVarList = factory2.createVariableDeclarationList([envVar], 2 /* Const */);
    const envVarStatement = factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      envVarList
    );
    statements.push(envVarStatement);
    const tryBlock = factory2.createBlock(
      bodyStatements,
      /*multiLine*/
      true
    );
    const bodyCatchBinding = factory2.createUniqueName("e");
    const catchClause = factory2.createCatchClause(
      bodyCatchBinding,
      factory2.createBlock(
        [
          factory2.createExpressionStatement(
            factory2.createAssignment(
              factory2.createPropertyAccessExpression(envBinding, "error"),
              bodyCatchBinding
            )
          ),
          factory2.createExpressionStatement(
            factory2.createAssignment(
              factory2.createPropertyAccessExpression(envBinding, "hasError"),
              factory2.createTrue()
            )
          )
        ],
        /*multiLine*/
        true
      )
    );
    let finallyBlock;
    if (async) {
      const result = factory2.createUniqueName("result");
      finallyBlock = factory2.createBlock(
        [
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            factory2.createVariableDeclarationList([
              factory2.createVariableDeclaration(
                result,
                /*exclamationToken*/
                void 0,
                /*type*/
                void 0,
                emitHelpers().createDisposeResourcesHelper(envBinding)
              )
            ], 2 /* Const */)
          ),
          factory2.createIfStatement(result, factory2.createExpressionStatement(factory2.createAwaitExpression(result)))
        ],
        /*multiLine*/
        true
      );
    } else {
      finallyBlock = factory2.createBlock(
        [
          factory2.createExpressionStatement(
            emitHelpers().createDisposeResourcesHelper(envBinding)
          )
        ],
        /*multiLine*/
        true
      );
    }
    const tryStatement = factory2.createTryStatement(tryBlock, catchClause, finallyBlock);
    statements.push(tryStatement);
    return statements;
  }
}
function countPrologueStatements(statements) {
  for (let i = 0; i < statements.length; i++) {
    if (!isPrologueDirective(statements[i]) && !isCustomPrologue(statements[i])) {
      return i;
    }
  }
  return 0;
}
function isUsingVariableDeclarationList(node) {
  return isVariableDeclarationList(node) && getUsingKindOfVariableDeclarationList(node) !== 0 /* None */;
}
function getUsingKindOfVariableDeclarationList(node) {
  return (node.flags & 7 /* BlockScoped */) === 6 /* AwaitUsing */ ? 2 /* Async */ : (node.flags & 7 /* BlockScoped */) === 4 /* Using */ ? 1 /* Sync */ : 0 /* None */;
}
function getUsingKindOfVariableStatement(node) {
  return getUsingKindOfVariableDeclarationList(node.declarationList);
}
function getUsingKind(statement) {
  return isVariableStatement(statement) ? getUsingKindOfVariableStatement(statement) : 0 /* None */;
}
function getUsingKindOfStatements(statements) {
  let result = 0 /* None */;
  for (const statement of statements) {
    const usingKind = getUsingKind(statement);
    if (usingKind === 2 /* Async */) return 2 /* Async */;
    if (usingKind > result) result = usingKind;
  }
  return result;
}
function getUsingKindOfCaseOrDefaultClauses(clauses) {
  let result = 0 /* None */;
  for (const clause of clauses) {
    const usingKind = getUsingKindOfStatements(clause.statements);
    if (usingKind === 2 /* Async */) return 2 /* Async */;
    if (usingKind > result) result = usingKind;
  }
  return result;
}

// src/compiler/transformers/jsx.ts
function transformJsx(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers
  } = context;
  const compilerOptions = context.getCompilerOptions();
  let currentSourceFile;
  let currentFileState;
  return chainBundle(context, transformSourceFile);
  function getCurrentFileNameExpression() {
    if (currentFileState.filenameDeclaration) {
      return currentFileState.filenameDeclaration.name;
    }
    const declaration = factory2.createVariableDeclaration(
      factory2.createUniqueName("_jsxFileName", 16 /* Optimistic */ | 32 /* FileLevel */),
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      factory2.createStringLiteral(currentSourceFile.fileName)
    );
    currentFileState.filenameDeclaration = declaration;
    return currentFileState.filenameDeclaration.name;
  }
  function getJsxFactoryCalleePrimitive(isStaticChildren) {
    return compilerOptions.jsx === 5 /* ReactJSXDev */ ? "jsxDEV" : isStaticChildren ? "jsxs" : "jsx";
  }
  function getJsxFactoryCallee(isStaticChildren) {
    const type = getJsxFactoryCalleePrimitive(isStaticChildren);
    return getImplicitImportForName(type);
  }
  function getImplicitJsxFragmentReference() {
    return getImplicitImportForName("Fragment");
  }
  function getImplicitImportForName(name) {
    var _a, _b;
    const importSource = name === "createElement" ? currentFileState.importSpecifier : getJSXRuntimeImport(currentFileState.importSpecifier, compilerOptions);
    const existing = (_b = (_a = currentFileState.utilizedImplicitRuntimeImports) == null ? void 0 : _a.get(importSource)) == null ? void 0 : _b.get(name);
    if (existing) {
      return existing.name;
    }
    if (!currentFileState.utilizedImplicitRuntimeImports) {
      currentFileState.utilizedImplicitRuntimeImports = /* @__PURE__ */ new Map();
    }
    let specifierSourceImports = currentFileState.utilizedImplicitRuntimeImports.get(importSource);
    if (!specifierSourceImports) {
      specifierSourceImports = /* @__PURE__ */ new Map();
      currentFileState.utilizedImplicitRuntimeImports.set(importSource, specifierSourceImports);
    }
    const generatedName = factory2.createUniqueName(`_${name}`, 16 /* Optimistic */ | 32 /* FileLevel */ | 64 /* AllowNameSubstitution */);
    const specifier = factory2.createImportSpecifier(
      /*isTypeOnly*/
      false,
      factory2.createIdentifier(name),
      generatedName
    );
    setIdentifierGeneratedImportReference(generatedName, specifier);
    specifierSourceImports.set(name, specifier);
    return generatedName;
  }
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    currentSourceFile = node;
    currentFileState = {};
    currentFileState.importSpecifier = getJSXImplicitImportBase(compilerOptions, node);
    let visited = visitEachChild(node, visitor, context);
    addEmitHelpers(visited, context.readEmitHelpers());
    let statements = visited.statements;
    if (currentFileState.filenameDeclaration) {
      statements = insertStatementAfterCustomPrologue(statements.slice(), factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList([currentFileState.filenameDeclaration], 2 /* Const */)
      ));
    }
    if (currentFileState.utilizedImplicitRuntimeImports) {
      for (const [importSource, importSpecifiersMap] of arrayFrom(currentFileState.utilizedImplicitRuntimeImports.entries())) {
        if (isExternalModule(node)) {
          const importStatement = factory2.createImportDeclaration(
            /*modifiers*/
            void 0,
            factory2.createImportClause(
              /*isTypeOnly*/
              false,
              /*name*/
              void 0,
              factory2.createNamedImports(arrayFrom(importSpecifiersMap.values()))
            ),
            factory2.createStringLiteral(importSource),
            /*attributes*/
            void 0
          );
          setParentRecursive(
            importStatement,
            /*incremental*/
            false
          );
          statements = insertStatementAfterCustomPrologue(statements.slice(), importStatement);
        } else if (isExternalOrCommonJsModule(node)) {
          const requireStatement = factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            factory2.createVariableDeclarationList([
              factory2.createVariableDeclaration(
                factory2.createObjectBindingPattern(arrayFrom(importSpecifiersMap.values(), (s) => factory2.createBindingElement(
                  /*dotDotDotToken*/
                  void 0,
                  s.propertyName,
                  s.name
                ))),
                /*exclamationToken*/
                void 0,
                /*type*/
                void 0,
                factory2.createCallExpression(
                  factory2.createIdentifier("require"),
                  /*typeArguments*/
                  void 0,
                  [factory2.createStringLiteral(importSource)]
                )
              )
            ], 2 /* Const */)
          );
          setParentRecursive(
            requireStatement,
            /*incremental*/
            false
          );
          statements = insertStatementAfterCustomPrologue(statements.slice(), requireStatement);
        } else {
        }
      }
    }
    if (statements !== visited.statements) {
      visited = factory2.updateSourceFile(visited, statements);
    }
    currentFileState = void 0;
    return visited;
  }
  function visitor(node) {
    if (node.transformFlags & 2 /* ContainsJsx */) {
      return visitorWorker(node);
    } else {
      return node;
    }
  }
  function visitorWorker(node) {
    switch (node.kind) {
      case 284 /* JsxElement */:
        return visitJsxElement(
          node,
          /*isChild*/
          false
        );
      case 285 /* JsxSelfClosingElement */:
        return visitJsxSelfClosingElement(
          node,
          /*isChild*/
          false
        );
      case 288 /* JsxFragment */:
        return visitJsxFragment(
          node,
          /*isChild*/
          false
        );
      case 294 /* JsxExpression */:
        return visitJsxExpression(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function transformJsxChildToExpression(node) {
    switch (node.kind) {
      case 12 /* JsxText */:
        return visitJsxText(node);
      case 294 /* JsxExpression */:
        return visitJsxExpression(node);
      case 284 /* JsxElement */:
        return visitJsxElement(
          node,
          /*isChild*/
          true
        );
      case 285 /* JsxSelfClosingElement */:
        return visitJsxSelfClosingElement(
          node,
          /*isChild*/
          true
        );
      case 288 /* JsxFragment */:
        return visitJsxFragment(
          node,
          /*isChild*/
          true
        );
      default:
        return Debug.failBadSyntaxKind(node);
    }
  }
  function hasProto(obj) {
    return obj.properties.some(
      (p) => isPropertyAssignment(p) && (isIdentifier(p.name) && idText(p.name) === "__proto__" || isStringLiteral(p.name) && p.name.text === "__proto__")
    );
  }
  function hasKeyAfterPropsSpread(node) {
    let spread = false;
    for (const elem of node.attributes.properties) {
      if (isJsxSpreadAttribute(elem) && (!isObjectLiteralExpression(elem.expression) || elem.expression.properties.some(isSpreadAssignment))) {
        spread = true;
      } else if (spread && isJsxAttribute(elem) && isIdentifier(elem.name) && elem.name.escapedText === "key") {
        return true;
      }
    }
    return false;
  }
  function shouldUseCreateElement(node) {
    return currentFileState.importSpecifier === void 0 || hasKeyAfterPropsSpread(node);
  }
  function visitJsxElement(node, isChild) {
    const tagTransform = shouldUseCreateElement(node.openingElement) ? visitJsxOpeningLikeElementCreateElement : visitJsxOpeningLikeElementJSX;
    return tagTransform(
      node.openingElement,
      node.children,
      isChild,
      /*location*/
      node
    );
  }
  function visitJsxSelfClosingElement(node, isChild) {
    const tagTransform = shouldUseCreateElement(node) ? visitJsxOpeningLikeElementCreateElement : visitJsxOpeningLikeElementJSX;
    return tagTransform(
      node,
      /*children*/
      void 0,
      isChild,
      /*location*/
      node
    );
  }
  function visitJsxFragment(node, isChild) {
    const tagTransform = currentFileState.importSpecifier === void 0 ? visitJsxOpeningFragmentCreateElement : visitJsxOpeningFragmentJSX;
    return tagTransform(
      node.openingFragment,
      node.children,
      isChild,
      /*location*/
      node
    );
  }
  function convertJsxChildrenToChildrenPropObject(children) {
    const prop = convertJsxChildrenToChildrenPropAssignment(children);
    return prop && factory2.createObjectLiteralExpression([prop]);
  }
  function convertJsxChildrenToChildrenPropAssignment(children) {
    const nonWhitespaceChildren = getSemanticJsxChildren(children);
    if (length(nonWhitespaceChildren) === 1 && !nonWhitespaceChildren[0].dotDotDotToken) {
      const result2 = transformJsxChildToExpression(nonWhitespaceChildren[0]);
      return result2 && factory2.createPropertyAssignment("children", result2);
    }
    const result = mapDefined(children, transformJsxChildToExpression);
    return length(result) ? factory2.createPropertyAssignment("children", factory2.createArrayLiteralExpression(result)) : void 0;
  }
  function visitJsxOpeningLikeElementJSX(node, children, isChild, location) {
    const tagName = getTagName(node);
    const childrenProp = children && children.length ? convertJsxChildrenToChildrenPropAssignment(children) : void 0;
    const keyAttr = find(node.attributes.properties, (p) => !!p.name && isIdentifier(p.name) && p.name.escapedText === "key");
    const attrs = keyAttr ? filter(node.attributes.properties, (p) => p !== keyAttr) : node.attributes.properties;
    const objectProperties = length(attrs) ? transformJsxAttributesToObjectProps(attrs, childrenProp) : factory2.createObjectLiteralExpression(childrenProp ? [childrenProp] : emptyArray);
    return visitJsxOpeningLikeElementOrFragmentJSX(
      tagName,
      objectProperties,
      keyAttr,
      children || emptyArray,
      isChild,
      location
    );
  }
  function visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, children, isChild, location) {
    var _a;
    const nonWhitespaceChildren = getSemanticJsxChildren(children);
    const isStaticChildren = length(nonWhitespaceChildren) > 1 || !!((_a = nonWhitespaceChildren[0]) == null ? void 0 : _a.dotDotDotToken);
    const args = [tagName, objectProperties];
    if (keyAttr) {
      args.push(transformJsxAttributeInitializer(keyAttr.initializer));
    }
    if (compilerOptions.jsx === 5 /* ReactJSXDev */) {
      const originalFile = getOriginalNode(currentSourceFile);
      if (originalFile && isSourceFile(originalFile)) {
        if (keyAttr === void 0) {
          args.push(factory2.createVoidZero());
        }
        args.push(isStaticChildren ? factory2.createTrue() : factory2.createFalse());
        const lineCol = getLineAndCharacterOfPosition(originalFile, location.pos);
        args.push(factory2.createObjectLiteralExpression([
          factory2.createPropertyAssignment("fileName", getCurrentFileNameExpression()),
          factory2.createPropertyAssignment("lineNumber", factory2.createNumericLiteral(lineCol.line + 1)),
          factory2.createPropertyAssignment("columnNumber", factory2.createNumericLiteral(lineCol.character + 1))
        ]));
        args.push(factory2.createThis());
      }
    }
    const element = setTextRange(
      factory2.createCallExpression(
        getJsxFactoryCallee(isStaticChildren),
        /*typeArguments*/
        void 0,
        args
      ),
      location
    );
    if (isChild) {
      startOnNewLine(element);
    }
    return element;
  }
  function visitJsxOpeningLikeElementCreateElement(node, children, isChild, location) {
    const tagName = getTagName(node);
    const attrs = node.attributes.properties;
    const objectProperties = length(attrs) ? transformJsxAttributesToObjectProps(attrs) : factory2.createNull();
    const callee = currentFileState.importSpecifier === void 0 ? createJsxFactoryExpression(
      factory2,
      context.getEmitResolver().getJsxFactoryEntity(currentSourceFile),
      compilerOptions.reactNamespace,
      // TODO: GH#18217
      node
    ) : getImplicitImportForName("createElement");
    const element = createExpressionForJsxElement(
      factory2,
      callee,
      tagName,
      objectProperties,
      mapDefined(children, transformJsxChildToExpression),
      location
    );
    if (isChild) {
      startOnNewLine(element);
    }
    return element;
  }
  function visitJsxOpeningFragmentJSX(_node, children, isChild, location) {
    let childrenProps;
    if (children && children.length) {
      const result = convertJsxChildrenToChildrenPropObject(children);
      if (result) {
        childrenProps = result;
      }
    }
    return visitJsxOpeningLikeElementOrFragmentJSX(
      getImplicitJsxFragmentReference(),
      childrenProps || factory2.createObjectLiteralExpression([]),
      /*keyAttr*/
      void 0,
      children,
      isChild,
      location
    );
  }
  function visitJsxOpeningFragmentCreateElement(node, children, isChild, location) {
    const element = createExpressionForJsxFragment(
      factory2,
      context.getEmitResolver().getJsxFactoryEntity(currentSourceFile),
      context.getEmitResolver().getJsxFragmentFactoryEntity(currentSourceFile),
      compilerOptions.reactNamespace,
      // TODO: GH#18217
      mapDefined(children, transformJsxChildToExpression),
      node,
      location
    );
    if (isChild) {
      startOnNewLine(element);
    }
    return element;
  }
  function transformJsxSpreadAttributeToProps(node) {
    if (isObjectLiteralExpression(node.expression) && !hasProto(node.expression)) {
      return sameMap(node.expression.properties, (p) => Debug.checkDefined(visitNode(p, visitor, isObjectLiteralElementLike)));
    }
    return factory2.createSpreadAssignment(Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
  }
  function transformJsxAttributesToObjectProps(attrs, children) {
    const target = getEmitScriptTarget(compilerOptions);
    return target && target >= 5 /* ES2018 */ ? factory2.createObjectLiteralExpression(transformJsxAttributesToProps(attrs, children)) : transformJsxAttributesToExpression(attrs, children);
  }
  function transformJsxAttributesToProps(attrs, children) {
    const props = flatten(spanMap(attrs, isJsxSpreadAttribute, (attrs2, isSpread) => flatten(map(attrs2, (attr) => isSpread ? transformJsxSpreadAttributeToProps(attr) : transformJsxAttributeToObjectLiteralElement(attr)))));
    if (children) {
      props.push(children);
    }
    return props;
  }
  function transformJsxAttributesToExpression(attrs, children) {
    const expressions = [];
    let properties = [];
    for (const attr of attrs) {
      if (isJsxSpreadAttribute(attr)) {
        if (isObjectLiteralExpression(attr.expression) && !hasProto(attr.expression)) {
          for (const prop of attr.expression.properties) {
            if (isSpreadAssignment(prop)) {
              finishObjectLiteralIfNeeded();
              expressions.push(Debug.checkDefined(visitNode(prop.expression, visitor, isExpression)));
              continue;
            }
            properties.push(Debug.checkDefined(visitNode(prop, visitor)));
          }
          continue;
        }
        finishObjectLiteralIfNeeded();
        expressions.push(Debug.checkDefined(visitNode(attr.expression, visitor, isExpression)));
        continue;
      }
      properties.push(transformJsxAttributeToObjectLiteralElement(attr));
    }
    if (children) {
      properties.push(children);
    }
    finishObjectLiteralIfNeeded();
    if (expressions.length && !isObjectLiteralExpression(expressions[0])) {
      expressions.unshift(factory2.createObjectLiteralExpression());
    }
    return singleOrUndefined(expressions) || emitHelpers().createAssignHelper(expressions);
    function finishObjectLiteralIfNeeded() {
      if (properties.length) {
        expressions.push(factory2.createObjectLiteralExpression(properties));
        properties = [];
      }
    }
  }
  function transformJsxAttributeToObjectLiteralElement(node) {
    const name = getAttributeName(node);
    const expression = transformJsxAttributeInitializer(node.initializer);
    return factory2.createPropertyAssignment(name, expression);
  }
  function transformJsxAttributeInitializer(node) {
    if (node === void 0) {
      return factory2.createTrue();
    }
    if (node.kind === 11 /* StringLiteral */) {
      const singleQuote = node.singleQuote !== void 0 ? node.singleQuote : !isStringDoubleQuoted(node, currentSourceFile);
      const literal = factory2.createStringLiteral(tryDecodeEntities(node.text) || node.text, singleQuote);
      return setTextRange(literal, node);
    }
    if (node.kind === 294 /* JsxExpression */) {
      if (node.expression === void 0) {
        return factory2.createTrue();
      }
      return Debug.checkDefined(visitNode(node.expression, visitor, isExpression));
    }
    if (isJsxElement(node)) {
      return visitJsxElement(
        node,
        /*isChild*/
        false
      );
    }
    if (isJsxSelfClosingElement(node)) {
      return visitJsxSelfClosingElement(
        node,
        /*isChild*/
        false
      );
    }
    if (isJsxFragment(node)) {
      return visitJsxFragment(
        node,
        /*isChild*/
        false
      );
    }
    return Debug.failBadSyntaxKind(node);
  }
  function visitJsxText(node) {
    const fixed = fixupWhitespaceAndDecodeEntities(node.text);
    return fixed === void 0 ? void 0 : factory2.createStringLiteral(fixed);
  }
  function fixupWhitespaceAndDecodeEntities(text) {
    let acc;
    let firstNonWhitespace = 0;
    let lastNonWhitespace = -1;
    for (let i = 0; i < text.length; i++) {
      const c = text.charCodeAt(i);
      if (isLineBreak(c)) {
        if (firstNonWhitespace !== -1 && lastNonWhitespace !== -1) {
          acc = addLineOfJsxText(acc, text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
        }
        firstNonWhitespace = -1;
      } else if (!isWhiteSpaceSingleLine(c)) {
        lastNonWhitespace = i;
        if (firstNonWhitespace === -1) {
          firstNonWhitespace = i;
        }
      }
    }
    return firstNonWhitespace !== -1 ? addLineOfJsxText(acc, text.substr(firstNonWhitespace)) : acc;
  }
  function addLineOfJsxText(acc, trimmedLine) {
    const decoded = decodeEntities(trimmedLine);
    return acc === void 0 ? decoded : acc + " " + decoded;
  }
  function decodeEntities(text) {
    return text.replace(/&((#((\d+)|x([\da-fA-F]+)))|(\w+));/g, (match, _all, _number, _digits, decimal, hex, word) => {
      if (decimal) {
        return utf16EncodeAsString(parseInt(decimal, 10));
      } else if (hex) {
        return utf16EncodeAsString(parseInt(hex, 16));
      } else {
        const ch = entities.get(word);
        return ch ? utf16EncodeAsString(ch) : match;
      }
    });
  }
  function tryDecodeEntities(text) {
    const decoded = decodeEntities(text);
    return decoded === text ? void 0 : decoded;
  }
  function getTagName(node) {
    if (node.kind === 284 /* JsxElement */) {
      return getTagName(node.openingElement);
    } else {
      const tagName = node.tagName;
      if (isIdentifier(tagName) && isIntrinsicJsxName(tagName.escapedText)) {
        return factory2.createStringLiteral(idText(tagName));
      } else if (isJsxNamespacedName(tagName)) {
        return factory2.createStringLiteral(idText(tagName.namespace) + ":" + idText(tagName.name));
      } else {
        return createExpressionFromEntityName(factory2, tagName);
      }
    }
  }
  function getAttributeName(node) {
    const name = node.name;
    if (isIdentifier(name)) {
      const text = idText(name);
      return /^[A-Za-z_]\w*$/.test(text) ? name : factory2.createStringLiteral(text);
    }
    return factory2.createStringLiteral(idText(name.namespace) + ":" + idText(name.name));
  }
  function visitJsxExpression(node) {
    const expression = visitNode(node.expression, visitor, isExpression);
    return node.dotDotDotToken ? factory2.createSpreadElement(expression) : expression;
  }
}
var entities = new Map(Object.entries({
  quot: 34,
  amp: 38,
  apos: 39,
  lt: 60,
  gt: 62,
  nbsp: 160,
  iexcl: 161,
  cent: 162,
  pound: 163,
  curren: 164,
  yen: 165,
  brvbar: 166,
  sect: 167,
  uml: 168,
  copy: 169,
  ordf: 170,
  laquo: 171,
  not: 172,
  shy: 173,
  reg: 174,
  macr: 175,
  deg: 176,
  plusmn: 177,
  sup2: 178,
  sup3: 179,
  acute: 180,
  micro: 181,
  para: 182,
  middot: 183,
  cedil: 184,
  sup1: 185,
  ordm: 186,
  raquo: 187,
  frac14: 188,
  frac12: 189,
  frac34: 190,
  iquest: 191,
  Agrave: 192,
  Aacute: 193,
  Acirc: 194,
  Atilde: 195,
  Auml: 196,
  Aring: 197,
  AElig: 198,
  Ccedil: 199,
  Egrave: 200,
  Eacute: 201,
  Ecirc: 202,
  Euml: 203,
  Igrave: 204,
  Iacute: 205,
  Icirc: 206,
  Iuml: 207,
  ETH: 208,
  Ntilde: 209,
  Ograve: 210,
  Oacute: 211,
  Ocirc: 212,
  Otilde: 213,
  Ouml: 214,
  times: 215,
  Oslash: 216,
  Ugrave: 217,
  Uacute: 218,
  Ucirc: 219,
  Uuml: 220,
  Yacute: 221,
  THORN: 222,
  szlig: 223,
  agrave: 224,
  aacute: 225,
  acirc: 226,
  atilde: 227,
  auml: 228,
  aring: 229,
  aelig: 230,
  ccedil: 231,
  egrave: 232,
  eacute: 233,
  ecirc: 234,
  euml: 235,
  igrave: 236,
  iacute: 237,
  icirc: 238,
  iuml: 239,
  eth: 240,
  ntilde: 241,
  ograve: 242,
  oacute: 243,
  ocirc: 244,
  otilde: 245,
  ouml: 246,
  divide: 247,
  oslash: 248,
  ugrave: 249,
  uacute: 250,
  ucirc: 251,
  uuml: 252,
  yacute: 253,
  thorn: 254,
  yuml: 255,
  OElig: 338,
  oelig: 339,
  Scaron: 352,
  scaron: 353,
  Yuml: 376,
  fnof: 402,
  circ: 710,
  tilde: 732,
  Alpha: 913,
  Beta: 914,
  Gamma: 915,
  Delta: 916,
  Epsilon: 917,
  Zeta: 918,
  Eta: 919,
  Theta: 920,
  Iota: 921,
  Kappa: 922,
  Lambda: 923,
  Mu: 924,
  Nu: 925,
  Xi: 926,
  Omicron: 927,
  Pi: 928,
  Rho: 929,
  Sigma: 931,
  Tau: 932,
  Upsilon: 933,
  Phi: 934,
  Chi: 935,
  Psi: 936,
  Omega: 937,
  alpha: 945,
  beta: 946,
  gamma: 947,
  delta: 948,
  epsilon: 949,
  zeta: 950,
  eta: 951,
  theta: 952,
  iota: 953,
  kappa: 954,
  lambda: 955,
  mu: 956,
  nu: 957,
  xi: 958,
  omicron: 959,
  pi: 960,
  rho: 961,
  sigmaf: 962,
  sigma: 963,
  tau: 964,
  upsilon: 965,
  phi: 966,
  chi: 967,
  psi: 968,
  omega: 969,
  thetasym: 977,
  upsih: 978,
  piv: 982,
  ensp: 8194,
  emsp: 8195,
  thinsp: 8201,
  zwnj: 8204,
  zwj: 8205,
  lrm: 8206,
  rlm: 8207,
  ndash: 8211,
  mdash: 8212,
  lsquo: 8216,
  rsquo: 8217,
  sbquo: 8218,
  ldquo: 8220,
  rdquo: 8221,
  bdquo: 8222,
  dagger: 8224,
  Dagger: 8225,
  bull: 8226,
  hellip: 8230,
  permil: 8240,
  prime: 8242,
  Prime: 8243,
  lsaquo: 8249,
  rsaquo: 8250,
  oline: 8254,
  frasl: 8260,
  euro: 8364,
  image: 8465,
  weierp: 8472,
  real: 8476,
  trade: 8482,
  alefsym: 8501,
  larr: 8592,
  uarr: 8593,
  rarr: 8594,
  darr: 8595,
  harr: 8596,
  crarr: 8629,
  lArr: 8656,
  uArr: 8657,
  rArr: 8658,
  dArr: 8659,
  hArr: 8660,
  forall: 8704,
  part: 8706,
  exist: 8707,
  empty: 8709,
  nabla: 8711,
  isin: 8712,
  notin: 8713,
  ni: 8715,
  prod: 8719,
  sum: 8721,
  minus: 8722,
  lowast: 8727,
  radic: 8730,
  prop: 8733,
  infin: 8734,
  ang: 8736,
  and: 8743,
  or: 8744,
  cap: 8745,
  cup: 8746,
  int: 8747,
  there4: 8756,
  sim: 8764,
  cong: 8773,
  asymp: 8776,
  ne: 8800,
  equiv: 8801,
  le: 8804,
  ge: 8805,
  sub: 8834,
  sup: 8835,
  nsub: 8836,
  sube: 8838,
  supe: 8839,
  oplus: 8853,
  otimes: 8855,
  perp: 8869,
  sdot: 8901,
  lceil: 8968,
  rceil: 8969,
  lfloor: 8970,
  rfloor: 8971,
  lang: 9001,
  rang: 9002,
  loz: 9674,
  spades: 9824,
  clubs: 9827,
  hearts: 9829,
  diams: 9830
}));

// src/compiler/transformers/es2016.ts
function transformES2016(context) {
  const {
    factory: factory2,
    hoistVariableDeclaration
  } = context;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitor(node) {
    if ((node.transformFlags & 512 /* ContainsES2016 */) === 0) {
      return node;
    }
    switch (node.kind) {
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitBinaryExpression(node) {
    switch (node.operatorToken.kind) {
      case 68 /* AsteriskAsteriskEqualsToken */:
        return visitExponentiationAssignmentExpression(node);
      case 43 /* AsteriskAsteriskToken */:
        return visitExponentiationExpression(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitExponentiationAssignmentExpression(node) {
    let target;
    let value;
    const left = visitNode(node.left, visitor, isExpression);
    const right = visitNode(node.right, visitor, isExpression);
    if (isElementAccessExpression(left)) {
      const expressionTemp = factory2.createTempVariable(hoistVariableDeclaration);
      const argumentExpressionTemp = factory2.createTempVariable(hoistVariableDeclaration);
      target = setTextRange(
        factory2.createElementAccessExpression(
          setTextRange(factory2.createAssignment(expressionTemp, left.expression), left.expression),
          setTextRange(factory2.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)
        ),
        left
      );
      value = setTextRange(
        factory2.createElementAccessExpression(
          expressionTemp,
          argumentExpressionTemp
        ),
        left
      );
    } else if (isPropertyAccessExpression(left)) {
      const expressionTemp = factory2.createTempVariable(hoistVariableDeclaration);
      target = setTextRange(
        factory2.createPropertyAccessExpression(
          setTextRange(factory2.createAssignment(expressionTemp, left.expression), left.expression),
          left.name
        ),
        left
      );
      value = setTextRange(
        factory2.createPropertyAccessExpression(
          expressionTemp,
          left.name
        ),
        left
      );
    } else {
      target = left;
      value = left;
    }
    return setTextRange(
      factory2.createAssignment(
        target,
        setTextRange(factory2.createGlobalMethodCall("Math", "pow", [value, right]), node)
      ),
      node
    );
  }
  function visitExponentiationExpression(node) {
    const left = visitNode(node.left, visitor, isExpression);
    const right = visitNode(node.right, visitor, isExpression);
    return setTextRange(factory2.createGlobalMethodCall("Math", "pow", [left, right]), node);
  }
}

// src/compiler/transformers/es2015.ts
function createSpreadSegment(kind, expression) {
  return { kind, expression };
}
function transformES2015(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    startLexicalEnvironment,
    resumeLexicalEnvironment,
    endLexicalEnvironment,
    hoistVariableDeclaration
  } = context;
  const compilerOptions = context.getCompilerOptions();
  const resolver = context.getEmitResolver();
  const previousOnSubstituteNode = context.onSubstituteNode;
  const previousOnEmitNode = context.onEmitNode;
  context.onEmitNode = onEmitNode;
  context.onSubstituteNode = onSubstituteNode;
  let currentSourceFile;
  let currentText;
  let hierarchyFacts;
  let taggedTemplateStringDeclarations;
  function recordTaggedTemplateString(temp) {
    taggedTemplateStringDeclarations = append(
      taggedTemplateStringDeclarations,
      factory2.createVariableDeclaration(temp)
    );
  }
  let convertedLoopState;
  let enabledSubstitutions;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    currentSourceFile = node;
    currentText = node.text;
    const visited = visitSourceFile(node);
    addEmitHelpers(visited, context.readEmitHelpers());
    currentSourceFile = void 0;
    currentText = void 0;
    taggedTemplateStringDeclarations = void 0;
    hierarchyFacts = 0 /* None */;
    return visited;
  }
  function enterSubtree(excludeFacts, includeFacts) {
    const ancestorFacts = hierarchyFacts;
    hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 32767 /* AncestorFactsMask */;
    return ancestorFacts;
  }
  function exitSubtree(ancestorFacts, excludeFacts, includeFacts) {
    hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & -32768 /* SubtreeFactsMask */ | ancestorFacts;
  }
  function isReturnVoidStatementInConstructorWithCapturedSuper(node) {
    return (hierarchyFacts & 8192 /* ConstructorWithSuperCall */) !== 0 && node.kind === 253 /* ReturnStatement */ && !node.expression;
  }
  function isOrMayContainReturnCompletion(node) {
    return node.transformFlags & 4194304 /* ContainsHoistedDeclarationOrCompletion */ && (isReturnStatement(node) || isIfStatement(node) || isWithStatement(node) || isSwitchStatement(node) || isCaseBlock(node) || isCaseClause(node) || isDefaultClause(node) || isTryStatement(node) || isCatchClause(node) || isLabeledStatement(node) || isIterationStatement(
      node,
      /*lookInLabeledStatements*/
      false
    ) || isBlock(node));
  }
  function shouldVisitNode(node) {
    return (node.transformFlags & 1024 /* ContainsES2015 */) !== 0 || convertedLoopState !== void 0 || hierarchyFacts & 8192 /* ConstructorWithSuperCall */ && isOrMayContainReturnCompletion(node) || isIterationStatement(
      node,
      /*lookInLabeledStatements*/
      false
    ) && shouldConvertIterationStatement(node) || (getInternalEmitFlags(node) & 1 /* TypeScriptClassWrapper */) !== 0;
  }
  function visitor(node) {
    return shouldVisitNode(node) ? visitorWorker(
      node,
      /*expressionResultIsUnused*/
      false
    ) : node;
  }
  function visitorWithUnusedExpressionResult(node) {
    return shouldVisitNode(node) ? visitorWorker(
      node,
      /*expressionResultIsUnused*/
      true
    ) : node;
  }
  function classWrapperStatementVisitor(node) {
    if (shouldVisitNode(node)) {
      const original = getOriginalNode(node);
      if (isPropertyDeclaration(original) && hasStaticModifier(original)) {
        const ancestorFacts = enterSubtree(
          32670 /* StaticInitializerExcludes */,
          16449 /* StaticInitializerIncludes */
        );
        const result = visitorWorker(
          node,
          /*expressionResultIsUnused*/
          false
        );
        exitSubtree(ancestorFacts, 229376 /* FunctionSubtreeExcludes */, 0 /* None */);
        return result;
      }
      return visitorWorker(
        node,
        /*expressionResultIsUnused*/
        false
      );
    }
    return node;
  }
  function callExpressionVisitor(node) {
    if (node.kind === 108 /* SuperKeyword */) {
      return visitSuperKeyword(
        node,
        /*isExpressionOfCall*/
        true
      );
    }
    return visitor(node);
  }
  function visitorWorker(node, expressionResultIsUnused2) {
    switch (node.kind) {
      case 126 /* StaticKeyword */:
        return void 0;
      case 263 /* ClassDeclaration */:
        return visitClassDeclaration(node);
      case 231 /* ClassExpression */:
        return visitClassExpression(node);
      case 169 /* Parameter */:
        return visitParameter(node);
      case 262 /* FunctionDeclaration */:
        return visitFunctionDeclaration(node);
      case 219 /* ArrowFunction */:
        return visitArrowFunction(node);
      case 218 /* FunctionExpression */:
        return visitFunctionExpression(node);
      case 260 /* VariableDeclaration */:
        return visitVariableDeclaration(node);
      case 80 /* Identifier */:
        return visitIdentifier(node);
      case 261 /* VariableDeclarationList */:
        return visitVariableDeclarationList(node);
      case 255 /* SwitchStatement */:
        return visitSwitchStatement(node);
      case 269 /* CaseBlock */:
        return visitCaseBlock(node);
      case 241 /* Block */:
        return visitBlock(
          node,
          /*isFunctionBody*/
          false
        );
      case 252 /* BreakStatement */:
      case 251 /* ContinueStatement */:
        return visitBreakOrContinueStatement(node);
      case 256 /* LabeledStatement */:
        return visitLabeledStatement(node);
      case 246 /* DoStatement */:
      case 247 /* WhileStatement */:
        return visitDoOrWhileStatement(
          node,
          /*outermostLabeledStatement*/
          void 0
        );
      case 248 /* ForStatement */:
        return visitForStatement(
          node,
          /*outermostLabeledStatement*/
          void 0
        );
      case 249 /* ForInStatement */:
        return visitForInStatement(
          node,
          /*outermostLabeledStatement*/
          void 0
        );
      case 250 /* ForOfStatement */:
        return visitForOfStatement(
          node,
          /*outermostLabeledStatement*/
          void 0
        );
      case 244 /* ExpressionStatement */:
        return visitExpressionStatement(node);
      case 210 /* ObjectLiteralExpression */:
        return visitObjectLiteralExpression(node);
      case 299 /* CatchClause */:
        return visitCatchClause(node);
      case 304 /* ShorthandPropertyAssignment */:
        return visitShorthandPropertyAssignment(node);
      case 167 /* ComputedPropertyName */:
        return visitComputedPropertyName(node);
      case 209 /* ArrayLiteralExpression */:
        return visitArrayLiteralExpression(node);
      case 213 /* CallExpression */:
        return visitCallExpression(node);
      case 214 /* NewExpression */:
        return visitNewExpression(node);
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(node, expressionResultIsUnused2);
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(node, expressionResultIsUnused2);
      case 355 /* CommaListExpression */:
        return visitCommaListExpression(node, expressionResultIsUnused2);
      case 15 /* NoSubstitutionTemplateLiteral */:
      case 16 /* TemplateHead */:
      case 17 /* TemplateMiddle */:
      case 18 /* TemplateTail */:
        return visitTemplateLiteral(node);
      case 11 /* StringLiteral */:
        return visitStringLiteral(node);
      case 9 /* NumericLiteral */:
        return visitNumericLiteral(node);
      case 215 /* TaggedTemplateExpression */:
        return visitTaggedTemplateExpression(node);
      case 228 /* TemplateExpression */:
        return visitTemplateExpression(node);
      case 229 /* YieldExpression */:
        return visitYieldExpression(node);
      case 230 /* SpreadElement */:
        return visitSpreadElement(node);
      case 108 /* SuperKeyword */:
        return visitSuperKeyword(
          node,
          /*isExpressionOfCall*/
          false
        );
      case 110 /* ThisKeyword */:
        return visitThisKeyword(node);
      case 236 /* MetaProperty */:
        return visitMetaProperty(node);
      case 174 /* MethodDeclaration */:
        return visitMethodDeclaration(node);
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
        return visitAccessorDeclaration(node);
      case 243 /* VariableStatement */:
        return visitVariableStatement(node);
      case 253 /* ReturnStatement */:
        return visitReturnStatement(node);
      case 222 /* VoidExpression */:
        return visitVoidExpression(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitSourceFile(node) {
    const ancestorFacts = enterSubtree(8064 /* SourceFileExcludes */, 64 /* SourceFileIncludes */);
    const prologue = [];
    const statements = [];
    startLexicalEnvironment();
    const statementOffset = factory2.copyPrologue(
      node.statements,
      prologue,
      /*ensureUseStrict*/
      false,
      visitor
    );
    addRange(statements, visitNodes2(node.statements, visitor, isStatement, statementOffset));
    if (taggedTemplateStringDeclarations) {
      statements.push(
        factory2.createVariableStatement(
          /*modifiers*/
          void 0,
          factory2.createVariableDeclarationList(taggedTemplateStringDeclarations)
        )
      );
    }
    factory2.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
    insertCaptureThisForNodeIfNeeded(prologue, node);
    exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
    return factory2.updateSourceFile(
      node,
      setTextRange(factory2.createNodeArray(concatenate(prologue, statements)), node.statements)
    );
  }
  function visitSwitchStatement(node) {
    if (convertedLoopState !== void 0) {
      const savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
      convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */;
      const result = visitEachChild(node, visitor, context);
      convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
      return result;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCaseBlock(node) {
    const ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
    const updated = visitEachChild(node, visitor, context);
    exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
    return updated;
  }
  function returnCapturedThis(node) {
    return setOriginalNode(factory2.createReturnStatement(createCapturedThis()), node);
  }
  function createCapturedThis() {
    return factory2.createUniqueName("_this", 16 /* Optimistic */ | 32 /* FileLevel */);
  }
  function visitReturnStatement(node) {
    if (convertedLoopState) {
      convertedLoopState.nonLocalJumps |= 8 /* Return */;
      if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
        node = returnCapturedThis(node);
      }
      return factory2.createReturnStatement(
        factory2.createObjectLiteralExpression(
          [
            factory2.createPropertyAssignment(
              factory2.createIdentifier("value"),
              node.expression ? Debug.checkDefined(visitNode(node.expression, visitor, isExpression)) : factory2.createVoidZero()
            )
          ]
        )
      );
    } else if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
      return returnCapturedThis(node);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitThisKeyword(node) {
    hierarchyFacts |= 65536 /* LexicalThis */;
    if (hierarchyFacts & 2 /* ArrowFunction */ && !(hierarchyFacts & 16384 /* StaticInitializer */)) {
      hierarchyFacts |= 131072 /* CapturedLexicalThis */;
    }
    if (convertedLoopState) {
      if (hierarchyFacts & 2 /* ArrowFunction */) {
        convertedLoopState.containsLexicalThis = true;
        return node;
      }
      return convertedLoopState.thisName || (convertedLoopState.thisName = factory2.createUniqueName("this"));
    }
    return node;
  }
  function visitVoidExpression(node) {
    return visitEachChild(node, visitorWithUnusedExpressionResult, context);
  }
  function visitIdentifier(node) {
    if (convertedLoopState) {
      if (resolver.isArgumentsLocalBinding(node)) {
        return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = factory2.createUniqueName("arguments"));
      }
    }
    if (node.flags & 256 /* IdentifierHasExtendedUnicodeEscape */) {
      return setOriginalNode(
        setTextRange(
          factory2.createIdentifier(unescapeLeadingUnderscores(node.escapedText)),
          node
        ),
        node
      );
    }
    return node;
  }
  function visitBreakOrContinueStatement(node) {
    if (convertedLoopState) {
      const jump = node.kind === 252 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */;
      const canUseBreakOrContinue = node.label && convertedLoopState.labels && convertedLoopState.labels.get(idText(node.label)) || !node.label && convertedLoopState.allowedNonLabeledJumps & jump;
      if (!canUseBreakOrContinue) {
        let labelMarker;
        const label = node.label;
        if (!label) {
          if (node.kind === 252 /* BreakStatement */) {
            convertedLoopState.nonLocalJumps |= 2 /* Break */;
            labelMarker = "break";
          } else {
            convertedLoopState.nonLocalJumps |= 4 /* Continue */;
            labelMarker = "continue";
          }
        } else {
          if (node.kind === 252 /* BreakStatement */) {
            labelMarker = `break-${label.escapedText}`;
            setLabeledJump(
              convertedLoopState,
              /*isBreak*/
              true,
              idText(label),
              labelMarker
            );
          } else {
            labelMarker = `continue-${label.escapedText}`;
            setLabeledJump(
              convertedLoopState,
              /*isBreak*/
              false,
              idText(label),
              labelMarker
            );
          }
        }
        let returnExpression = factory2.createStringLiteral(labelMarker);
        if (convertedLoopState.loopOutParameters.length) {
          const outParams = convertedLoopState.loopOutParameters;
          let expr;
          for (let i = 0; i < outParams.length; i++) {
            const copyExpr = copyOutParameter(outParams[i], 1 /* ToOutParameter */);
            if (i === 0) {
              expr = copyExpr;
            } else {
              expr = factory2.createBinaryExpression(expr, 28 /* CommaToken */, copyExpr);
            }
          }
          returnExpression = factory2.createBinaryExpression(expr, 28 /* CommaToken */, returnExpression);
        }
        return factory2.createReturnStatement(returnExpression);
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitClassDeclaration(node) {
    const variable = factory2.createVariableDeclaration(
      factory2.getLocalName(
        node,
        /*allowComments*/
        true
      ),
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      transformClassLikeDeclarationToExpression(node)
    );
    setOriginalNode(variable, node);
    const statements = [];
    const statement = factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      factory2.createVariableDeclarationList([variable])
    );
    setOriginalNode(statement, node);
    setTextRange(statement, node);
    startOnNewLine(statement);
    statements.push(statement);
    if (hasSyntacticModifier(node, 32 /* Export */)) {
      const exportStatement = hasSyntacticModifier(node, 2048 /* Default */) ? factory2.createExportDefault(factory2.getLocalName(node)) : factory2.createExternalModuleExport(factory2.getLocalName(node));
      setOriginalNode(exportStatement, statement);
      statements.push(exportStatement);
    }
    return singleOrMany(statements);
  }
  function visitClassExpression(node) {
    return transformClassLikeDeclarationToExpression(node);
  }
  function transformClassLikeDeclarationToExpression(node) {
    if (node.name) {
      enableSubstitutionsForBlockScopedBindings();
    }
    const extendsClauseElement = getClassExtendsHeritageElement(node);
    const classFunction = factory2.createFunctionExpression(
      /*modifiers*/
      void 0,
      /*asteriskToken*/
      void 0,
      /*name*/
      void 0,
      /*typeParameters*/
      void 0,
      extendsClauseElement ? [factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        createSyntheticSuper()
      )] : [],
      /*type*/
      void 0,
      transformClassBody(node, extendsClauseElement)
    );
    setEmitFlags(classFunction, getEmitFlags(node) & 131072 /* Indented */ | 1048576 /* ReuseTempVariableScope */);
    const inner = factory2.createPartiallyEmittedExpression(classFunction);
    setTextRangeEnd(inner, node.end);
    setEmitFlags(inner, 3072 /* NoComments */);
    const outer = factory2.createPartiallyEmittedExpression(inner);
    setTextRangeEnd(outer, skipTrivia(currentText, node.pos));
    setEmitFlags(outer, 3072 /* NoComments */);
    const result = factory2.createParenthesizedExpression(
      factory2.createCallExpression(
        outer,
        /*typeArguments*/
        void 0,
        extendsClauseElement ? [Debug.checkDefined(visitNode(extendsClauseElement.expression, visitor, isExpression))] : []
      )
    );
    addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class ");
    return result;
  }
  function transformClassBody(node, extendsClauseElement) {
    const statements = [];
    const name = factory2.getInternalName(node);
    const constructorLikeName = isIdentifierANonContextualKeyword(name) ? factory2.getGeneratedNameForNode(name) : name;
    startLexicalEnvironment();
    addExtendsHelperIfNeeded(statements, node, extendsClauseElement);
    addConstructor(statements, node, constructorLikeName, extendsClauseElement);
    addClassMembers(statements, node);
    const closingBraceLocation = createTokenRange(skipTrivia(currentText, node.members.end), 20 /* CloseBraceToken */);
    const outer = factory2.createPartiallyEmittedExpression(constructorLikeName);
    setTextRangeEnd(outer, closingBraceLocation.end);
    setEmitFlags(outer, 3072 /* NoComments */);
    const statement = factory2.createReturnStatement(outer);
    setTextRangePos(statement, closingBraceLocation.pos);
    setEmitFlags(statement, 3072 /* NoComments */ | 768 /* NoTokenSourceMaps */);
    statements.push(statement);
    insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
    const block = factory2.createBlock(
      setTextRange(
        factory2.createNodeArray(statements),
        /*location*/
        node.members
      ),
      /*multiLine*/
      true
    );
    setEmitFlags(block, 3072 /* NoComments */);
    return block;
  }
  function addExtendsHelperIfNeeded(statements, node, extendsClauseElement) {
    if (extendsClauseElement) {
      statements.push(
        setTextRange(
          factory2.createExpressionStatement(
            emitHelpers().createExtendsHelper(factory2.getInternalName(node))
          ),
          /*location*/
          extendsClauseElement
        )
      );
    }
  }
  function addConstructor(statements, node, name, extendsClauseElement) {
    const savedConvertedLoopState = convertedLoopState;
    convertedLoopState = void 0;
    const ancestorFacts = enterSubtree(32662 /* ConstructorExcludes */, 73 /* ConstructorIncludes */);
    const constructor = getFirstConstructorWithBody(node);
    const hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== void 0);
    const constructorFunction = factory2.createFunctionDeclaration(
      /*modifiers*/
      void 0,
      /*asteriskToken*/
      void 0,
      name,
      /*typeParameters*/
      void 0,
      transformConstructorParameters(constructor, hasSynthesizedSuper),
      /*type*/
      void 0,
      transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper)
    );
    setTextRange(constructorFunction, constructor || node);
    if (extendsClauseElement) {
      setEmitFlags(constructorFunction, 16 /* CapturesThis */);
    }
    statements.push(constructorFunction);
    exitSubtree(ancestorFacts, 229376 /* FunctionSubtreeExcludes */, 0 /* None */);
    convertedLoopState = savedConvertedLoopState;
  }
  function transformConstructorParameters(constructor, hasSynthesizedSuper) {
    return visitParameterList(constructor && !hasSynthesizedSuper ? constructor.parameters : void 0, visitor, context) || [];
  }
  function createDefaultConstructorBody(node, isDerivedClass) {
    const statements = [];
    resumeLexicalEnvironment();
    factory2.mergeLexicalEnvironment(statements, endLexicalEnvironment());
    if (isDerivedClass) {
      statements.push(factory2.createReturnStatement(createDefaultSuperCallOrThis()));
    }
    const statementsArray = factory2.createNodeArray(statements);
    setTextRange(statementsArray, node.members);
    const block = factory2.createBlock(
      statementsArray,
      /*multiLine*/
      true
    );
    setTextRange(block, node);
    setEmitFlags(block, 3072 /* NoComments */);
    return block;
  }
  function isUninitializedVariableStatement(node) {
    return isVariableStatement(node) && every(node.declarationList.declarations, (decl) => isIdentifier(decl.name) && !decl.initializer);
  }
  function containsSuperCall(node) {
    if (isSuperCall(node)) {
      return true;
    }
    if (!(node.transformFlags & 134217728 /* ContainsLexicalSuper */)) {
      return false;
    }
    switch (node.kind) {
      case 219 /* ArrowFunction */:
      case 218 /* FunctionExpression */:
      case 262 /* FunctionDeclaration */:
      case 176 /* Constructor */:
      case 175 /* ClassStaticBlockDeclaration */:
        return false;
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 174 /* MethodDeclaration */:
      case 172 /* PropertyDeclaration */: {
        const named = node;
        if (isComputedPropertyName(named.name)) {
          return !!forEachChild(named.name, containsSuperCall);
        }
        return false;
      }
    }
    return !!forEachChild(node, containsSuperCall);
  }
  function transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) {
    const isDerivedClass = !!extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== 106 /* NullKeyword */;
    if (!constructor) return createDefaultConstructorBody(node, isDerivedClass);
    const prologue = [];
    const statements = [];
    resumeLexicalEnvironment();
    const standardPrologueEnd = factory2.copyStandardPrologue(
      constructor.body.statements,
      prologue,
      /*statementOffset*/
      0
    );
    if (hasSynthesizedSuper || containsSuperCall(constructor.body)) {
      hierarchyFacts |= 8192 /* ConstructorWithSuperCall */;
    }
    addRange(statements, visitNodes2(constructor.body.statements, visitor, isStatement, standardPrologueEnd));
    const mayReplaceThis = isDerivedClass || hierarchyFacts & 8192 /* ConstructorWithSuperCall */;
    addDefaultValueAssignmentsIfNeeded2(prologue, constructor);
    addRestParameterIfNeeded(prologue, constructor, hasSynthesizedSuper);
    insertCaptureNewTargetIfNeeded(prologue, constructor);
    if (mayReplaceThis) {
      insertCaptureThisForNode(prologue, constructor, createActualThis());
    } else {
      insertCaptureThisForNodeIfNeeded(prologue, constructor);
    }
    factory2.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
    if (mayReplaceThis && !isSufficientlyCoveredByReturnStatements(constructor.body)) {
      statements.push(factory2.createReturnStatement(createCapturedThis()));
    }
    const body = factory2.createBlock(
      setTextRange(
        factory2.createNodeArray(
          [
            ...prologue,
            ...statements
          ]
        ),
        /*location*/
        constructor.body.statements
      ),
      /*multiLine*/
      true
    );
    setTextRange(body, constructor.body);
    return simplifyConstructor(body, constructor.body, hasSynthesizedSuper);
  }
  function isCapturedThis(node) {
    return isGeneratedIdentifier(node) && idText(node) === "_this";
  }
  function isSyntheticSuper(node) {
    return isGeneratedIdentifier(node) && idText(node) === "_super";
  }
  function isThisCapturingVariableStatement(node) {
    return isVariableStatement(node) && node.declarationList.declarations.length === 1 && isThisCapturingVariableDeclaration(node.declarationList.declarations[0]);
  }
  function isThisCapturingVariableDeclaration(node) {
    return isVariableDeclaration(node) && isCapturedThis(node.name) && !!node.initializer;
  }
  function isThisCapturingAssignment(node) {
    return isAssignmentExpression(
      node,
      /*excludeCompoundAssignment*/
      true
    ) && isCapturedThis(node.left);
  }
  function isTransformedSuperCall(node) {
    return isCallExpression(node) && isPropertyAccessExpression(node.expression) && isSyntheticSuper(node.expression.expression) && isIdentifier(node.expression.name) && (idText(node.expression.name) === "call" || idText(node.expression.name) === "apply") && node.arguments.length >= 1 && node.arguments[0].kind === 110 /* ThisKeyword */;
  }
  function isTransformedSuperCallWithFallback(node) {
    return isBinaryExpression(node) && node.operatorToken.kind === 57 /* BarBarToken */ && node.right.kind === 110 /* ThisKeyword */ && isTransformedSuperCall(node.left);
  }
  function isImplicitSuperCall(node) {
    return isBinaryExpression(node) && node.operatorToken.kind === 56 /* AmpersandAmpersandToken */ && isBinaryExpression(node.left) && node.left.operatorToken.kind === 38 /* ExclamationEqualsEqualsToken */ && isSyntheticSuper(node.left.left) && node.left.right.kind === 106 /* NullKeyword */ && isTransformedSuperCall(node.right) && idText(node.right.expression.name) === "apply";
  }
  function isImplicitSuperCallWithFallback(node) {
    return isBinaryExpression(node) && node.operatorToken.kind === 57 /* BarBarToken */ && node.right.kind === 110 /* ThisKeyword */ && isImplicitSuperCall(node.left);
  }
  function isThisCapturingTransformedSuperCallWithFallback(node) {
    return isThisCapturingAssignment(node) && isTransformedSuperCallWithFallback(node.right);
  }
  function isThisCapturingImplicitSuperCallWithFallback(node) {
    return isThisCapturingAssignment(node) && isImplicitSuperCallWithFallback(node.right);
  }
  function isTransformedSuperCallLike(node) {
    return isTransformedSuperCall(node) || isTransformedSuperCallWithFallback(node) || isThisCapturingTransformedSuperCallWithFallback(node) || isImplicitSuperCall(node) || isImplicitSuperCallWithFallback(node) || isThisCapturingImplicitSuperCallWithFallback(node);
  }
  function simplifyConstructorInlineSuperInThisCaptureVariable(body) {
    for (let i = 0; i < body.statements.length - 1; i++) {
      const statement = body.statements[i];
      if (!isThisCapturingVariableStatement(statement)) {
        continue;
      }
      const varDecl = statement.declarationList.declarations[0];
      if (varDecl.initializer.kind !== 110 /* ThisKeyword */) {
        continue;
      }
      const thisCaptureStatementIndex = i;
      let superCallIndex = i + 1;
      while (superCallIndex < body.statements.length) {
        const statement2 = body.statements[superCallIndex];
        if (isExpressionStatement(statement2)) {
          if (isTransformedSuperCallLike(skipOuterExpressions(statement2.expression))) {
            break;
          }
        }
        if (isUninitializedVariableStatement(statement2)) {
          superCallIndex++;
          continue;
        }
        return body;
      }
      const following = body.statements[superCallIndex];
      let expression = following.expression;
      if (isThisCapturingAssignment(expression)) {
        expression = expression.right;
      }
      const newVarDecl = factory2.updateVariableDeclaration(
        varDecl,
        varDecl.name,
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        expression
      );
      const newDeclList = factory2.updateVariableDeclarationList(statement.declarationList, [newVarDecl]);
      const newVarStatement = factory2.createVariableStatement(statement.modifiers, newDeclList);
      setOriginalNode(newVarStatement, following);
      setTextRange(newVarStatement, following);
      const newStatements = factory2.createNodeArray([
        ...body.statements.slice(0, thisCaptureStatementIndex),
        // copy statements preceding to `var _this`
        ...body.statements.slice(thisCaptureStatementIndex + 1, superCallIndex),
        // copy intervening temp variables
        newVarStatement,
        ...body.statements.slice(superCallIndex + 1)
        // copy statements following `super.call(this, ...)`
      ]);
      setTextRange(newStatements, body.statements);
      return factory2.updateBlock(body, newStatements);
    }
    return body;
  }
  function simplifyConstructorInlineSuperReturn(body, original) {
    for (const statement of original.statements) {
      if (statement.transformFlags & 134217728 /* ContainsLexicalSuper */ && !getSuperCallFromStatement(statement)) {
        return body;
      }
    }
    const canElideThisCapturingVariable = !(original.transformFlags & 16384 /* ContainsLexicalThis */) && !(hierarchyFacts & 65536 /* LexicalThis */) && !(hierarchyFacts & 131072 /* CapturedLexicalThis */);
    for (let i = body.statements.length - 1; i > 0; i--) {
      const statement = body.statements[i];
      if (isReturnStatement(statement) && statement.expression && isCapturedThis(statement.expression)) {
        const preceding = body.statements[i - 1];
        let expression;
        if (isExpressionStatement(preceding) && isThisCapturingTransformedSuperCallWithFallback(skipOuterExpressions(preceding.expression))) {
          expression = preceding.expression;
        } else if (canElideThisCapturingVariable && isThisCapturingVariableStatement(preceding)) {
          const varDecl = preceding.declarationList.declarations[0];
          if (isTransformedSuperCallLike(skipOuterExpressions(varDecl.initializer))) {
            expression = factory2.createAssignment(
              createCapturedThis(),
              varDecl.initializer
            );
          }
        }
        if (!expression) {
          break;
        }
        const newReturnStatement = factory2.createReturnStatement(expression);
        setOriginalNode(newReturnStatement, preceding);
        setTextRange(newReturnStatement, preceding);
        const newStatements = factory2.createNodeArray([
          ...body.statements.slice(0, i - 1),
          // copy all statements preceding `_super.call(this, ...)`
          newReturnStatement,
          ...body.statements.slice(i + 1)
          // copy all statements following `return _this;`
        ]);
        setTextRange(newStatements, body.statements);
        return factory2.updateBlock(body, newStatements);
      }
    }
    return body;
  }
  function elideUnusedThisCaptureWorker(node) {
    if (isThisCapturingVariableStatement(node)) {
      const varDecl = node.declarationList.declarations[0];
      if (varDecl.initializer.kind === 110 /* ThisKeyword */) {
        return void 0;
      }
    } else if (isThisCapturingAssignment(node)) {
      return factory2.createPartiallyEmittedExpression(node.right, node);
    }
    switch (node.kind) {
      case 219 /* ArrowFunction */:
      case 218 /* FunctionExpression */:
      case 262 /* FunctionDeclaration */:
      case 176 /* Constructor */:
      case 175 /* ClassStaticBlockDeclaration */:
        return node;
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 174 /* MethodDeclaration */:
      case 172 /* PropertyDeclaration */: {
        const named = node;
        if (isComputedPropertyName(named.name)) {
          return factory2.replacePropertyName(named, visitEachChild(
            named.name,
            elideUnusedThisCaptureWorker,
            /*context*/
            void 0
          ));
        }
        return node;
      }
    }
    return visitEachChild(
      node,
      elideUnusedThisCaptureWorker,
      /*context*/
      void 0
    );
  }
  function simplifyConstructorElideUnusedThisCapture(body, original) {
    if (original.transformFlags & 16384 /* ContainsLexicalThis */ || hierarchyFacts & 65536 /* LexicalThis */ || hierarchyFacts & 131072 /* CapturedLexicalThis */) {
      return body;
    }
    for (const statement of original.statements) {
      if (statement.transformFlags & 134217728 /* ContainsLexicalSuper */ && !getSuperCallFromStatement(statement)) {
        return body;
      }
    }
    return factory2.updateBlock(body, visitNodes2(body.statements, elideUnusedThisCaptureWorker, isStatement));
  }
  function injectSuperPresenceCheckWorker(node) {
    if (isTransformedSuperCall(node) && node.arguments.length === 2 && isIdentifier(node.arguments[1]) && idText(node.arguments[1]) === "arguments") {
      return factory2.createLogicalAnd(
        factory2.createStrictInequality(
          createSyntheticSuper(),
          factory2.createNull()
        ),
        node
      );
    }
    switch (node.kind) {
      case 219 /* ArrowFunction */:
      case 218 /* FunctionExpression */:
      case 262 /* FunctionDeclaration */:
      case 176 /* Constructor */:
      case 175 /* ClassStaticBlockDeclaration */:
        return node;
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
      case 174 /* MethodDeclaration */:
      case 172 /* PropertyDeclaration */: {
        const named = node;
        if (isComputedPropertyName(named.name)) {
          return factory2.replacePropertyName(named, visitEachChild(
            named.name,
            injectSuperPresenceCheckWorker,
            /*context*/
            void 0
          ));
        }
        return node;
      }
    }
    return visitEachChild(
      node,
      injectSuperPresenceCheckWorker,
      /*context*/
      void 0
    );
  }
  function complicateConstructorInjectSuperPresenceCheck(body) {
    return factory2.updateBlock(body, visitNodes2(body.statements, injectSuperPresenceCheckWorker, isStatement));
  }
  function simplifyConstructor(body, original, hasSynthesizedSuper) {
    const inputBody = body;
    body = simplifyConstructorInlineSuperInThisCaptureVariable(body);
    body = simplifyConstructorInlineSuperReturn(body, original);
    if (body !== inputBody) {
      body = simplifyConstructorElideUnusedThisCapture(body, original);
    }
    if (hasSynthesizedSuper) {
      body = complicateConstructorInjectSuperPresenceCheck(body);
    }
    return body;
  }
  function isSufficientlyCoveredByReturnStatements(statement) {
    if (statement.kind === 253 /* ReturnStatement */) {
      return true;
    } else if (statement.kind === 245 /* IfStatement */) {
      const ifStatement = statement;
      if (ifStatement.elseStatement) {
        return isSufficientlyCoveredByReturnStatements(ifStatement.thenStatement) && isSufficientlyCoveredByReturnStatements(ifStatement.elseStatement);
      }
    } else if (statement.kind === 241 /* Block */) {
      const lastStatement = lastOrUndefined(statement.statements);
      if (lastStatement && isSufficientlyCoveredByReturnStatements(lastStatement)) {
        return true;
      }
    }
    return false;
  }
  function createActualThis() {
    return setEmitFlags(factory2.createThis(), 8 /* NoSubstitution */);
  }
  function createDefaultSuperCallOrThis() {
    return factory2.createLogicalOr(
      factory2.createLogicalAnd(
        factory2.createStrictInequality(
          createSyntheticSuper(),
          factory2.createNull()
        ),
        factory2.createFunctionApplyCall(
          createSyntheticSuper(),
          createActualThis(),
          factory2.createIdentifier("arguments")
        )
      ),
      createActualThis()
    );
  }
  function visitParameter(node) {
    if (node.dotDotDotToken) {
      return void 0;
    } else if (isBindingPattern(node.name)) {
      return setOriginalNode(
        setTextRange(
          factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            /*dotDotDotToken*/
            void 0,
            factory2.getGeneratedNameForNode(node),
            /*questionToken*/
            void 0,
            /*type*/
            void 0,
            /*initializer*/
            void 0
          ),
          /*location*/
          node
        ),
        /*original*/
        node
      );
    } else if (node.initializer) {
      return setOriginalNode(
        setTextRange(
          factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            /*dotDotDotToken*/
            void 0,
            node.name,
            /*questionToken*/
            void 0,
            /*type*/
            void 0,
            /*initializer*/
            void 0
          ),
          /*location*/
          node
        ),
        /*original*/
        node
      );
    } else {
      return node;
    }
  }
  function hasDefaultValueOrBindingPattern(node) {
    return node.initializer !== void 0 || isBindingPattern(node.name);
  }
  function addDefaultValueAssignmentsIfNeeded2(statements, node) {
    if (!some(node.parameters, hasDefaultValueOrBindingPattern)) {
      return false;
    }
    let added = false;
    for (const parameter of node.parameters) {
      const { name, initializer, dotDotDotToken } = parameter;
      if (dotDotDotToken) {
        continue;
      }
      if (isBindingPattern(name)) {
        added = insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) || added;
      } else if (initializer) {
        insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer);
        added = true;
      }
    }
    return added;
  }
  function insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) {
    if (name.elements.length > 0) {
      insertStatementAfterCustomPrologue(
        statements,
        setEmitFlags(
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            factory2.createVariableDeclarationList(
              flattenDestructuringBinding(
                parameter,
                visitor,
                context,
                0 /* All */,
                factory2.getGeneratedNameForNode(parameter)
              )
            )
          ),
          2097152 /* CustomPrologue */
        )
      );
      return true;
    } else if (initializer) {
      insertStatementAfterCustomPrologue(
        statements,
        setEmitFlags(
          factory2.createExpressionStatement(
            factory2.createAssignment(
              factory2.getGeneratedNameForNode(parameter),
              Debug.checkDefined(visitNode(initializer, visitor, isExpression))
            )
          ),
          2097152 /* CustomPrologue */
        )
      );
      return true;
    }
    return false;
  }
  function insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer) {
    initializer = Debug.checkDefined(visitNode(initializer, visitor, isExpression));
    const statement = factory2.createIfStatement(
      factory2.createTypeCheck(factory2.cloneNode(name), "undefined"),
      setEmitFlags(
        setTextRange(
          factory2.createBlock([
            factory2.createExpressionStatement(
              setEmitFlags(
                setTextRange(
                  factory2.createAssignment(
                    // TODO(rbuckton): Does this need to be parented?
                    setEmitFlags(setParent(setTextRange(factory2.cloneNode(name), name), name.parent), 96 /* NoSourceMap */),
                    setEmitFlags(initializer, 96 /* NoSourceMap */ | getEmitFlags(initializer) | 3072 /* NoComments */)
                  ),
                  parameter
                ),
                3072 /* NoComments */
              )
            )
          ]),
          parameter
        ),
        1 /* SingleLine */ | 64 /* NoTrailingSourceMap */ | 768 /* NoTokenSourceMaps */ | 3072 /* NoComments */
      )
    );
    startOnNewLine(statement);
    setTextRange(statement, parameter);
    setEmitFlags(statement, 768 /* NoTokenSourceMaps */ | 64 /* NoTrailingSourceMap */ | 2097152 /* CustomPrologue */ | 3072 /* NoComments */);
    insertStatementAfterCustomPrologue(statements, statement);
  }
  function shouldAddRestParameter(node, inConstructorWithSynthesizedSuper) {
    return !!(node && node.dotDotDotToken && !inConstructorWithSynthesizedSuper);
  }
  function addRestParameterIfNeeded(statements, node, inConstructorWithSynthesizedSuper) {
    const prologueStatements = [];
    const parameter = lastOrUndefined(node.parameters);
    if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
      return false;
    }
    const declarationName = parameter.name.kind === 80 /* Identifier */ ? setParent(setTextRange(factory2.cloneNode(parameter.name), parameter.name), parameter.name.parent) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    setEmitFlags(declarationName, 96 /* NoSourceMap */);
    const expressionName = parameter.name.kind === 80 /* Identifier */ ? factory2.cloneNode(parameter.name) : declarationName;
    const restIndex = node.parameters.length - 1;
    const temp = factory2.createLoopVariable();
    prologueStatements.push(
      setEmitFlags(
        setTextRange(
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            factory2.createVariableDeclarationList([
              factory2.createVariableDeclaration(
                declarationName,
                /*exclamationToken*/
                void 0,
                /*type*/
                void 0,
                factory2.createArrayLiteralExpression([])
              )
            ])
          ),
          /*location*/
          parameter
        ),
        2097152 /* CustomPrologue */
      )
    );
    const forStatement = factory2.createForStatement(
      setTextRange(
        factory2.createVariableDeclarationList([
          factory2.createVariableDeclaration(
            temp,
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            factory2.createNumericLiteral(restIndex)
          )
        ]),
        parameter
      ),
      setTextRange(
        factory2.createLessThan(
          temp,
          factory2.createPropertyAccessExpression(factory2.createIdentifier("arguments"), "length")
        ),
        parameter
      ),
      setTextRange(factory2.createPostfixIncrement(temp), parameter),
      factory2.createBlock([
        startOnNewLine(
          setTextRange(
            factory2.createExpressionStatement(
              factory2.createAssignment(
                factory2.createElementAccessExpression(
                  expressionName,
                  restIndex === 0 ? temp : factory2.createSubtract(temp, factory2.createNumericLiteral(restIndex))
                ),
                factory2.createElementAccessExpression(factory2.createIdentifier("arguments"), temp)
              )
            ),
            /*location*/
            parameter
          )
        )
      ])
    );
    setEmitFlags(forStatement, 2097152 /* CustomPrologue */);
    startOnNewLine(forStatement);
    prologueStatements.push(forStatement);
    if (parameter.name.kind !== 80 /* Identifier */) {
      prologueStatements.push(
        setEmitFlags(
          setTextRange(
            factory2.createVariableStatement(
              /*modifiers*/
              void 0,
              factory2.createVariableDeclarationList(
                flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, expressionName)
              )
            ),
            parameter
          ),
          2097152 /* CustomPrologue */
        )
      );
    }
    insertStatementsAfterCustomPrologue(statements, prologueStatements);
    return true;
  }
  function insertCaptureThisForNodeIfNeeded(statements, node) {
    if (hierarchyFacts & 131072 /* CapturedLexicalThis */ && node.kind !== 219 /* ArrowFunction */) {
      insertCaptureThisForNode(statements, node, factory2.createThis());
      return true;
    }
    return false;
  }
  function insertCaptureThisForNode(statements, node, initializer) {
    enableSubstitutionsForCapturedThis();
    const captureThisStatement = factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      factory2.createVariableDeclarationList([
        factory2.createVariableDeclaration(
          createCapturedThis(),
          /*exclamationToken*/
          void 0,
          /*type*/
          void 0,
          initializer
        )
      ])
    );
    setEmitFlags(captureThisStatement, 3072 /* NoComments */ | 2097152 /* CustomPrologue */);
    setSourceMapRange(captureThisStatement, node);
    insertStatementAfterCustomPrologue(statements, captureThisStatement);
  }
  function insertCaptureNewTargetIfNeeded(statements, node) {
    if (hierarchyFacts & 32768 /* NewTarget */) {
      let newTarget;
      switch (node.kind) {
        case 219 /* ArrowFunction */:
          return statements;
        case 174 /* MethodDeclaration */:
        case 177 /* GetAccessor */:
        case 178 /* SetAccessor */:
          newTarget = factory2.createVoidZero();
          break;
        case 176 /* Constructor */:
          newTarget = factory2.createPropertyAccessExpression(
            setEmitFlags(factory2.createThis(), 8 /* NoSubstitution */),
            "constructor"
          );
          break;
        case 262 /* FunctionDeclaration */:
        case 218 /* FunctionExpression */:
          newTarget = factory2.createConditionalExpression(
            factory2.createLogicalAnd(
              setEmitFlags(factory2.createThis(), 8 /* NoSubstitution */),
              factory2.createBinaryExpression(
                setEmitFlags(factory2.createThis(), 8 /* NoSubstitution */),
                104 /* InstanceOfKeyword */,
                factory2.getLocalName(node)
              )
            ),
            /*questionToken*/
            void 0,
            factory2.createPropertyAccessExpression(
              setEmitFlags(factory2.createThis(), 8 /* NoSubstitution */),
              "constructor"
            ),
            /*colonToken*/
            void 0,
            factory2.createVoidZero()
          );
          break;
        default:
          return Debug.failBadSyntaxKind(node);
      }
      const captureNewTargetStatement = factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList([
          factory2.createVariableDeclaration(
            factory2.createUniqueName("_newTarget", 16 /* Optimistic */ | 32 /* FileLevel */),
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            newTarget
          )
        ])
      );
      setEmitFlags(captureNewTargetStatement, 3072 /* NoComments */ | 2097152 /* CustomPrologue */);
      insertStatementAfterCustomPrologue(statements, captureNewTargetStatement);
    }
    return statements;
  }
  function addClassMembers(statements, node) {
    for (const member of node.members) {
      switch (member.kind) {
        case 240 /* SemicolonClassElement */:
          statements.push(transformSemicolonClassElementToStatement(member));
          break;
        case 174 /* MethodDeclaration */:
          statements.push(transformClassMethodDeclarationToStatement(getClassMemberPrefix(node, member), member, node));
          break;
        case 177 /* GetAccessor */:
        case 178 /* SetAccessor */:
          const accessors = getAllAccessorDeclarations(node.members, member);
          if (member === accessors.firstAccessor) {
            statements.push(transformAccessorsToStatement(getClassMemberPrefix(node, member), accessors, node));
          }
          break;
        case 176 /* Constructor */:
        case 175 /* ClassStaticBlockDeclaration */:
          break;
        default:
          Debug.failBadSyntaxKind(member, currentSourceFile && currentSourceFile.fileName);
          break;
      }
    }
  }
  function transformSemicolonClassElementToStatement(member) {
    return setTextRange(factory2.createEmptyStatement(), member);
  }
  function transformClassMethodDeclarationToStatement(receiver, member, container) {
    const commentRange = getCommentRange(member);
    const sourceMapRange = getSourceMapRange(member);
    const memberFunction = transformFunctionLikeToExpression(
      member,
      /*location*/
      member,
      /*name*/
      void 0,
      container
    );
    const propertyName = visitNode(member.name, visitor, isPropertyName);
    Debug.assert(propertyName);
    let e;
    if (!isPrivateIdentifier(propertyName) && getUseDefineForClassFields(context.getCompilerOptions())) {
      const name = isComputedPropertyName(propertyName) ? propertyName.expression : isIdentifier(propertyName) ? factory2.createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) : propertyName;
      e = factory2.createObjectDefinePropertyCall(receiver, name, factory2.createPropertyDescriptor({ value: memberFunction, enumerable: false, writable: true, configurable: true }));
    } else {
      const memberName = createMemberAccessForPropertyName(
        factory2,
        receiver,
        propertyName,
        /*location*/
        member.name
      );
      e = factory2.createAssignment(memberName, memberFunction);
    }
    setEmitFlags(memberFunction, 3072 /* NoComments */);
    setSourceMapRange(memberFunction, sourceMapRange);
    const statement = setTextRange(
      factory2.createExpressionStatement(e),
      /*location*/
      member
    );
    setOriginalNode(statement, member);
    setCommentRange(statement, commentRange);
    setEmitFlags(statement, 96 /* NoSourceMap */);
    return statement;
  }
  function transformAccessorsToStatement(receiver, accessors, container) {
    const statement = factory2.createExpressionStatement(transformAccessorsToExpression(
      receiver,
      accessors,
      container,
      /*startsOnNewLine*/
      false
    ));
    setEmitFlags(statement, 3072 /* NoComments */);
    setSourceMapRange(statement, getSourceMapRange(accessors.firstAccessor));
    return statement;
  }
  function transformAccessorsToExpression(receiver, { firstAccessor, getAccessor, setAccessor }, container, startsOnNewLine) {
    const target = setParent(setTextRange(factory2.cloneNode(receiver), receiver), receiver.parent);
    setEmitFlags(target, 3072 /* NoComments */ | 64 /* NoTrailingSourceMap */);
    setSourceMapRange(target, firstAccessor.name);
    const visitedAccessorName = visitNode(firstAccessor.name, visitor, isPropertyName);
    Debug.assert(visitedAccessorName);
    if (isPrivateIdentifier(visitedAccessorName)) {
      return Debug.failBadSyntaxKind(visitedAccessorName, "Encountered unhandled private identifier while transforming ES2015.");
    }
    const propertyName = createExpressionForPropertyName(factory2, visitedAccessorName);
    setEmitFlags(propertyName, 3072 /* NoComments */ | 32 /* NoLeadingSourceMap */);
    setSourceMapRange(propertyName, firstAccessor.name);
    const properties = [];
    if (getAccessor) {
      const getterFunction = transformFunctionLikeToExpression(
        getAccessor,
        /*location*/
        void 0,
        /*name*/
        void 0,
        container
      );
      setSourceMapRange(getterFunction, getSourceMapRange(getAccessor));
      setEmitFlags(getterFunction, 1024 /* NoLeadingComments */);
      const getter = factory2.createPropertyAssignment("get", getterFunction);
      setCommentRange(getter, getCommentRange(getAccessor));
      properties.push(getter);
    }
    if (setAccessor) {
      const setterFunction = transformFunctionLikeToExpression(
        setAccessor,
        /*location*/
        void 0,
        /*name*/
        void 0,
        container
      );
      setSourceMapRange(setterFunction, getSourceMapRange(setAccessor));
      setEmitFlags(setterFunction, 1024 /* NoLeadingComments */);
      const setter = factory2.createPropertyAssignment("set", setterFunction);
      setCommentRange(setter, getCommentRange(setAccessor));
      properties.push(setter);
    }
    properties.push(
      factory2.createPropertyAssignment("enumerable", getAccessor || setAccessor ? factory2.createFalse() : factory2.createTrue()),
      factory2.createPropertyAssignment("configurable", factory2.createTrue())
    );
    const call = factory2.createCallExpression(
      factory2.createPropertyAccessExpression(factory2.createIdentifier("Object"), "defineProperty"),
      /*typeArguments*/
      void 0,
      [
        target,
        propertyName,
        factory2.createObjectLiteralExpression(
          properties,
          /*multiLine*/
          true
        )
      ]
    );
    if (startsOnNewLine) {
      startOnNewLine(call);
    }
    return call;
  }
  function visitArrowFunction(node) {
    if (node.transformFlags & 16384 /* ContainsLexicalThis */ && !(hierarchyFacts & 16384 /* StaticInitializer */)) {
      hierarchyFacts |= 131072 /* CapturedLexicalThis */;
    }
    const savedConvertedLoopState = convertedLoopState;
    convertedLoopState = void 0;
    const ancestorFacts = enterSubtree(15232 /* ArrowFunctionExcludes */, 66 /* ArrowFunctionIncludes */);
    const func = factory2.createFunctionExpression(
      /*modifiers*/
      void 0,
      /*asteriskToken*/
      void 0,
      /*name*/
      void 0,
      /*typeParameters*/
      void 0,
      visitParameterList(node.parameters, visitor, context),
      /*type*/
      void 0,
      transformFunctionBody(node)
    );
    setTextRange(func, node);
    setOriginalNode(func, node);
    setEmitFlags(func, 16 /* CapturesThis */);
    exitSubtree(ancestorFacts, 0 /* ArrowFunctionSubtreeExcludes */, 0 /* None */);
    convertedLoopState = savedConvertedLoopState;
    return func;
  }
  function visitFunctionExpression(node) {
    const ancestorFacts = getEmitFlags(node) & 524288 /* AsyncFunctionBody */ ? enterSubtree(32662 /* AsyncFunctionBodyExcludes */, 69 /* AsyncFunctionBodyIncludes */) : enterSubtree(32670 /* FunctionExcludes */, 65 /* FunctionIncludes */);
    const savedConvertedLoopState = convertedLoopState;
    convertedLoopState = void 0;
    const parameters = visitParameterList(node.parameters, visitor, context);
    const body = transformFunctionBody(node);
    const name = hierarchyFacts & 32768 /* NewTarget */ ? factory2.getLocalName(node) : node.name;
    exitSubtree(ancestorFacts, 229376 /* FunctionSubtreeExcludes */, 0 /* None */);
    convertedLoopState = savedConvertedLoopState;
    return factory2.updateFunctionExpression(
      node,
      /*modifiers*/
      void 0,
      node.asteriskToken,
      name,
      /*typeParameters*/
      void 0,
      parameters,
      /*type*/
      void 0,
      body
    );
  }
  function visitFunctionDeclaration(node) {
    const savedConvertedLoopState = convertedLoopState;
    convertedLoopState = void 0;
    const ancestorFacts = enterSubtree(32670 /* FunctionExcludes */, 65 /* FunctionIncludes */);
    const parameters = visitParameterList(node.parameters, visitor, context);
    const body = transformFunctionBody(node);
    const name = hierarchyFacts & 32768 /* NewTarget */ ? factory2.getLocalName(node) : node.name;
    exitSubtree(ancestorFacts, 229376 /* FunctionSubtreeExcludes */, 0 /* None */);
    convertedLoopState = savedConvertedLoopState;
    return factory2.updateFunctionDeclaration(
      node,
      visitNodes2(node.modifiers, visitor, isModifier),
      node.asteriskToken,
      name,
      /*typeParameters*/
      void 0,
      parameters,
      /*type*/
      void 0,
      body
    );
  }
  function transformFunctionLikeToExpression(node, location, name, container) {
    const savedConvertedLoopState = convertedLoopState;
    convertedLoopState = void 0;
    const ancestorFacts = container && isClassLike(container) && !isStatic(node) ? enterSubtree(32670 /* FunctionExcludes */, 65 /* FunctionIncludes */ | 8 /* NonStaticClassElement */) : enterSubtree(32670 /* FunctionExcludes */, 65 /* FunctionIncludes */);
    const parameters = visitParameterList(node.parameters, visitor, context);
    const body = transformFunctionBody(node);
    if (hierarchyFacts & 32768 /* NewTarget */ && !name && (node.kind === 262 /* FunctionDeclaration */ || node.kind === 218 /* FunctionExpression */)) {
      name = factory2.getGeneratedNameForNode(node);
    }
    exitSubtree(ancestorFacts, 229376 /* FunctionSubtreeExcludes */, 0 /* None */);
    convertedLoopState = savedConvertedLoopState;
    return setOriginalNode(
      setTextRange(
        factory2.createFunctionExpression(
          /*modifiers*/
          void 0,
          node.asteriskToken,
          name,
          /*typeParameters*/
          void 0,
          parameters,
          /*type*/
          void 0,
          body
        ),
        location
      ),
      /*original*/
      node
    );
  }
  function transformFunctionBody(node) {
    let multiLine = false;
    let singleLine = false;
    let statementsLocation;
    let closeBraceLocation;
    const prologue = [];
    const statements = [];
    const body = node.body;
    let statementOffset;
    resumeLexicalEnvironment();
    if (isBlock(body)) {
      statementOffset = factory2.copyStandardPrologue(
        body.statements,
        prologue,
        0,
        /*ensureUseStrict*/
        false
      );
      statementOffset = factory2.copyCustomPrologue(body.statements, statements, statementOffset, visitor, isHoistedFunction);
      statementOffset = factory2.copyCustomPrologue(body.statements, statements, statementOffset, visitor, isHoistedVariableStatement);
    }
    multiLine = addDefaultValueAssignmentsIfNeeded2(statements, node) || multiLine;
    multiLine = addRestParameterIfNeeded(
      statements,
      node,
      /*inConstructorWithSynthesizedSuper*/
      false
    ) || multiLine;
    if (isBlock(body)) {
      statementOffset = factory2.copyCustomPrologue(body.statements, statements, statementOffset, visitor);
      statementsLocation = body.statements;
      addRange(statements, visitNodes2(body.statements, visitor, isStatement, statementOffset));
      if (!multiLine && body.multiLine) {
        multiLine = true;
      }
    } else {
      Debug.assert(node.kind === 219 /* ArrowFunction */);
      statementsLocation = moveRangeEnd(body, -1);
      const equalsGreaterThanToken = node.equalsGreaterThanToken;
      if (!nodeIsSynthesized(equalsGreaterThanToken) && !nodeIsSynthesized(body)) {
        if (rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
          singleLine = true;
        } else {
          multiLine = true;
        }
      }
      const expression = visitNode(body, visitor, isExpression);
      const returnStatement = factory2.createReturnStatement(expression);
      setTextRange(returnStatement, body);
      moveSyntheticComments(returnStatement, body);
      setEmitFlags(returnStatement, 768 /* NoTokenSourceMaps */ | 64 /* NoTrailingSourceMap */ | 2048 /* NoTrailingComments */);
      statements.push(returnStatement);
      closeBraceLocation = body;
    }
    factory2.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
    insertCaptureNewTargetIfNeeded(prologue, node);
    insertCaptureThisForNodeIfNeeded(prologue, node);
    if (some(prologue)) {
      multiLine = true;
    }
    statements.unshift(...prologue);
    if (isBlock(body) && arrayIsEqualTo(statements, body.statements)) {
      return body;
    }
    const block = factory2.createBlock(setTextRange(factory2.createNodeArray(statements), statementsLocation), multiLine);
    setTextRange(block, node.body);
    if (!multiLine && singleLine) {
      setEmitFlags(block, 1 /* SingleLine */);
    }
    if (closeBraceLocation) {
      setTokenSourceMapRange(block, 20 /* CloseBraceToken */, closeBraceLocation);
    }
    setOriginalNode(block, node.body);
    return block;
  }
  function visitBlock(node, isFunctionBody) {
    if (isFunctionBody) {
      return visitEachChild(node, visitor, context);
    }
    const ancestorFacts = hierarchyFacts & 256 /* IterationStatement */ ? enterSubtree(7104 /* IterationStatementBlockExcludes */, 512 /* IterationStatementBlockIncludes */) : enterSubtree(6976 /* BlockExcludes */, 128 /* BlockIncludes */);
    const updated = visitEachChild(node, visitor, context);
    exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
    return updated;
  }
  function visitExpressionStatement(node) {
    return visitEachChild(node, visitorWithUnusedExpressionResult, context);
  }
  function visitParenthesizedExpression(node, expressionResultIsUnused2) {
    return visitEachChild(node, expressionResultIsUnused2 ? visitorWithUnusedExpressionResult : visitor, context);
  }
  function visitBinaryExpression(node, expressionResultIsUnused2) {
    if (isDestructuringAssignment(node)) {
      return flattenDestructuringAssignment(
        node,
        visitor,
        context,
        0 /* All */,
        !expressionResultIsUnused2
      );
    }
    if (node.operatorToken.kind === 28 /* CommaToken */) {
      return factory2.updateBinaryExpression(
        node,
        Debug.checkDefined(visitNode(node.left, visitorWithUnusedExpressionResult, isExpression)),
        node.operatorToken,
        Debug.checkDefined(visitNode(node.right, expressionResultIsUnused2 ? visitorWithUnusedExpressionResult : visitor, isExpression))
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCommaListExpression(node, expressionResultIsUnused2) {
    if (expressionResultIsUnused2) {
      return visitEachChild(node, visitorWithUnusedExpressionResult, context);
    }
    let result;
    for (let i = 0; i < node.elements.length; i++) {
      const element = node.elements[i];
      const visited = visitNode(element, i < node.elements.length - 1 ? visitorWithUnusedExpressionResult : visitor, isExpression);
      if (result || visited !== element) {
        result || (result = node.elements.slice(0, i));
        Debug.assert(visited);
        result.push(visited);
      }
    }
    const elements = result ? setTextRange(factory2.createNodeArray(result), node.elements) : node.elements;
    return factory2.updateCommaListExpression(node, elements);
  }
  function isVariableStatementOfTypeScriptClassWrapper(node) {
    return node.declarationList.declarations.length === 1 && !!node.declarationList.declarations[0].initializer && !!(getInternalEmitFlags(node.declarationList.declarations[0].initializer) & 1 /* TypeScriptClassWrapper */);
  }
  function visitVariableStatement(node) {
    const ancestorFacts = enterSubtree(0 /* None */, hasSyntacticModifier(node, 32 /* Export */) ? 32 /* ExportedVariableStatement */ : 0 /* None */);
    let updated;
    if (convertedLoopState && (node.declarationList.flags & 7 /* BlockScoped */) === 0 && !isVariableStatementOfTypeScriptClassWrapper(node)) {
      let assignments;
      for (const decl of node.declarationList.declarations) {
        hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
        if (decl.initializer) {
          let assignment;
          if (isBindingPattern(decl.name)) {
            assignment = flattenDestructuringAssignment(
              decl,
              visitor,
              context,
              0 /* All */
            );
          } else {
            assignment = factory2.createBinaryExpression(decl.name, 64 /* EqualsToken */, Debug.checkDefined(visitNode(decl.initializer, visitor, isExpression)));
            setTextRange(assignment, decl);
          }
          assignments = append(assignments, assignment);
        }
      }
      if (assignments) {
        updated = setTextRange(factory2.createExpressionStatement(factory2.inlineExpressions(assignments)), node);
      } else {
        updated = void 0;
      }
    } else {
      updated = visitEachChild(node, visitor, context);
    }
    exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
    return updated;
  }
  function visitVariableDeclarationList(node) {
    if (node.flags & 7 /* BlockScoped */ || node.transformFlags & 524288 /* ContainsBindingPattern */) {
      if (node.flags & 7 /* BlockScoped */) {
        enableSubstitutionsForBlockScopedBindings();
      }
      const declarations = visitNodes2(
        node.declarations,
        node.flags & 1 /* Let */ ? visitVariableDeclarationInLetDeclarationList : visitVariableDeclaration,
        isVariableDeclaration
      );
      const declarationList = factory2.createVariableDeclarationList(declarations);
      setOriginalNode(declarationList, node);
      setTextRange(declarationList, node);
      setCommentRange(declarationList, node);
      if (node.transformFlags & 524288 /* ContainsBindingPattern */ && (isBindingPattern(node.declarations[0].name) || isBindingPattern(last(node.declarations).name))) {
        setSourceMapRange(declarationList, getRangeUnion(declarations));
      }
      return declarationList;
    }
    return visitEachChild(node, visitor, context);
  }
  function getRangeUnion(declarations) {
    let pos = -1, end = -1;
    for (const node of declarations) {
      pos = pos === -1 ? node.pos : node.pos === -1 ? pos : Math.min(pos, node.pos);
      end = Math.max(end, node.end);
    }
    return createRange(pos, end);
  }
  function shouldEmitExplicitInitializerForLetDeclaration(node) {
    const isCapturedInFunction = resolver.hasNodeCheckFlag(node, 16384 /* CapturedBlockScopedBinding */);
    const isDeclaredInLoop = resolver.hasNodeCheckFlag(node, 32768 /* BlockScopedBindingInLoop */);
    const emittedAsTopLevel = (hierarchyFacts & 64 /* TopLevel */) !== 0 || isCapturedInFunction && isDeclaredInLoop && (hierarchyFacts & 512 /* IterationStatementBlock */) !== 0;
    const emitExplicitInitializer = !emittedAsTopLevel && (hierarchyFacts & 4096 /* ForInOrForOfStatement */) === 0 && (!resolver.isDeclarationWithCollidingName(node) || isDeclaredInLoop && !isCapturedInFunction && (hierarchyFacts & (2048 /* ForStatement */ | 4096 /* ForInOrForOfStatement */)) === 0);
    return emitExplicitInitializer;
  }
  function visitVariableDeclarationInLetDeclarationList(node) {
    const name = node.name;
    if (isBindingPattern(name)) {
      return visitVariableDeclaration(node);
    }
    if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
      return factory2.updateVariableDeclaration(
        node,
        node.name,
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        factory2.createVoidZero()
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitVariableDeclaration(node) {
    const ancestorFacts = enterSubtree(32 /* ExportedVariableStatement */, 0 /* None */);
    let updated;
    if (isBindingPattern(node.name)) {
      updated = flattenDestructuringBinding(
        node,
        visitor,
        context,
        0 /* All */,
        /*rval*/
        void 0,
        (ancestorFacts & 32 /* ExportedVariableStatement */) !== 0
      );
    } else {
      updated = visitEachChild(node, visitor, context);
    }
    exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
    return updated;
  }
  function recordLabel(node) {
    convertedLoopState.labels.set(idText(node.label), true);
  }
  function resetLabel(node) {
    convertedLoopState.labels.set(idText(node.label), false);
  }
  function visitLabeledStatement(node) {
    if (convertedLoopState && !convertedLoopState.labels) {
      convertedLoopState.labels = /* @__PURE__ */ new Map();
    }
    const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
    return isIterationStatement(
      statement,
      /*lookInLabeledStatements*/
      false
    ) ? visitIterationStatement(
      statement,
      /*outermostLabeledStatement*/
      node
    ) : factory2.restoreEnclosingLabel(Debug.checkDefined(visitNode(statement, visitor, isStatement, factory2.liftToBlock)), node, convertedLoopState && resetLabel);
  }
  function visitIterationStatement(node, outermostLabeledStatement) {
    switch (node.kind) {
      case 246 /* DoStatement */:
      case 247 /* WhileStatement */:
        return visitDoOrWhileStatement(node, outermostLabeledStatement);
      case 248 /* ForStatement */:
        return visitForStatement(node, outermostLabeledStatement);
      case 249 /* ForInStatement */:
        return visitForInStatement(node, outermostLabeledStatement);
      case 250 /* ForOfStatement */:
        return visitForOfStatement(node, outermostLabeledStatement);
    }
  }
  function visitIterationStatementWithFacts(excludeFacts, includeFacts, node, outermostLabeledStatement, convert) {
    const ancestorFacts = enterSubtree(excludeFacts, includeFacts);
    const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert);
    exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
    return updated;
  }
  function visitDoOrWhileStatement(node, outermostLabeledStatement) {
    return visitIterationStatementWithFacts(
      0 /* DoOrWhileStatementExcludes */,
      1280 /* DoOrWhileStatementIncludes */,
      node,
      outermostLabeledStatement
    );
  }
  function visitForStatement(node, outermostLabeledStatement) {
    return visitIterationStatementWithFacts(
      5056 /* ForStatementExcludes */,
      3328 /* ForStatementIncludes */,
      node,
      outermostLabeledStatement
    );
  }
  function visitEachChildOfForStatement2(node) {
    return factory2.updateForStatement(
      node,
      visitNode(node.initializer, visitorWithUnusedExpressionResult, isForInitializer),
      visitNode(node.condition, visitor, isExpression),
      visitNode(node.incrementor, visitorWithUnusedExpressionResult, isExpression),
      Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory2.liftToBlock))
    );
  }
  function visitForInStatement(node, outermostLabeledStatement) {
    return visitIterationStatementWithFacts(
      3008 /* ForInOrForOfStatementExcludes */,
      5376 /* ForInOrForOfStatementIncludes */,
      node,
      outermostLabeledStatement
    );
  }
  function visitForOfStatement(node, outermostLabeledStatement) {
    return visitIterationStatementWithFacts(
      3008 /* ForInOrForOfStatementExcludes */,
      5376 /* ForInOrForOfStatementIncludes */,
      node,
      outermostLabeledStatement,
      compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray
    );
  }
  function convertForOfStatementHead(node, boundValue, convertedLoopBodyStatements) {
    const statements = [];
    const initializer = node.initializer;
    if (isVariableDeclarationList(initializer)) {
      if (node.initializer.flags & 7 /* BlockScoped */) {
        enableSubstitutionsForBlockScopedBindings();
      }
      const firstOriginalDeclaration = firstOrUndefined(initializer.declarations);
      if (firstOriginalDeclaration && isBindingPattern(firstOriginalDeclaration.name)) {
        const declarations = flattenDestructuringBinding(
          firstOriginalDeclaration,
          visitor,
          context,
          0 /* All */,
          boundValue
        );
        const declarationList = setTextRange(factory2.createVariableDeclarationList(declarations), node.initializer);
        setOriginalNode(declarationList, node.initializer);
        setSourceMapRange(declarationList, createRange(declarations[0].pos, last(declarations).end));
        statements.push(
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            declarationList
          )
        );
      } else {
        statements.push(
          setTextRange(
            factory2.createVariableStatement(
              /*modifiers*/
              void 0,
              setOriginalNode(
                setTextRange(
                  factory2.createVariableDeclarationList([
                    factory2.createVariableDeclaration(
                      firstOriginalDeclaration ? firstOriginalDeclaration.name : factory2.createTempVariable(
                        /*recordTempVariable*/
                        void 0
                      ),
                      /*exclamationToken*/
                      void 0,
                      /*type*/
                      void 0,
                      boundValue
                    )
                  ]),
                  moveRangePos(initializer, -1)
                ),
                initializer
              )
            ),
            moveRangeEnd(initializer, -1)
          )
        );
      }
    } else {
      const assignment = factory2.createAssignment(initializer, boundValue);
      if (isDestructuringAssignment(assignment)) {
        statements.push(factory2.createExpressionStatement(visitBinaryExpression(
          assignment,
          /*expressionResultIsUnused*/
          true
        )));
      } else {
        setTextRangeEnd(assignment, initializer.end);
        statements.push(setTextRange(factory2.createExpressionStatement(Debug.checkDefined(visitNode(assignment, visitor, isExpression))), moveRangeEnd(initializer, -1)));
      }
    }
    if (convertedLoopBodyStatements) {
      return createSyntheticBlockForConvertedStatements(addRange(statements, convertedLoopBodyStatements));
    } else {
      const statement = visitNode(node.statement, visitor, isStatement, factory2.liftToBlock);
      Debug.assert(statement);
      if (isBlock(statement)) {
        return factory2.updateBlock(statement, setTextRange(factory2.createNodeArray(concatenate(statements, statement.statements)), statement.statements));
      } else {
        statements.push(statement);
        return createSyntheticBlockForConvertedStatements(statements);
      }
    }
  }
  function createSyntheticBlockForConvertedStatements(statements) {
    return setEmitFlags(
      factory2.createBlock(
        factory2.createNodeArray(statements),
        /*multiLine*/
        true
      ),
      96 /* NoSourceMap */ | 768 /* NoTokenSourceMaps */
    );
  }
  function convertForOfStatementForArray(node, outermostLabeledStatement, convertedLoopBodyStatements) {
    const expression = visitNode(node.expression, visitor, isExpression);
    Debug.assert(expression);
    const counter = factory2.createLoopVariable();
    const rhsReference = isIdentifier(expression) ? factory2.getGeneratedNameForNode(expression) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    setEmitFlags(expression, 96 /* NoSourceMap */ | getEmitFlags(expression));
    const forStatement = setTextRange(
      factory2.createForStatement(
        /*initializer*/
        setEmitFlags(
          setTextRange(
            factory2.createVariableDeclarationList([
              setTextRange(factory2.createVariableDeclaration(
                counter,
                /*exclamationToken*/
                void 0,
                /*type*/
                void 0,
                factory2.createNumericLiteral(0)
              ), moveRangePos(node.expression, -1)),
              setTextRange(factory2.createVariableDeclaration(
                rhsReference,
                /*exclamationToken*/
                void 0,
                /*type*/
                void 0,
                expression
              ), node.expression)
            ]),
            node.expression
          ),
          4194304 /* NoHoisting */
        ),
        /*condition*/
        setTextRange(
          factory2.createLessThan(
            counter,
            factory2.createPropertyAccessExpression(rhsReference, "length")
          ),
          node.expression
        ),
        /*incrementor*/
        setTextRange(factory2.createPostfixIncrement(counter), node.expression),
        /*statement*/
        convertForOfStatementHead(
          node,
          factory2.createElementAccessExpression(rhsReference, counter),
          convertedLoopBodyStatements
        )
      ),
      /*location*/
      node
    );
    setEmitFlags(forStatement, 512 /* NoTokenTrailingSourceMaps */);
    setTextRange(forStatement, node);
    return factory2.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
  }
  function convertForOfStatementForIterable(node, outermostLabeledStatement, convertedLoopBodyStatements, ancestorFacts) {
    const expression = visitNode(node.expression, visitor, isExpression);
    Debug.assert(expression);
    const iterator = isIdentifier(expression) ? factory2.getGeneratedNameForNode(expression) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    const result = isIdentifier(expression) ? factory2.getGeneratedNameForNode(iterator) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    const errorRecord = factory2.createUniqueName("e");
    const catchVariable = factory2.getGeneratedNameForNode(errorRecord);
    const returnMethod = factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    const values = setTextRange(emitHelpers().createValuesHelper(expression), node.expression);
    const next = factory2.createCallExpression(
      factory2.createPropertyAccessExpression(iterator, "next"),
      /*typeArguments*/
      void 0,
      []
    );
    hoistVariableDeclaration(errorRecord);
    hoistVariableDeclaration(returnMethod);
    const initializer = ancestorFacts & 1024 /* IterationContainer */ ? factory2.inlineExpressions([factory2.createAssignment(errorRecord, factory2.createVoidZero()), values]) : values;
    const forStatement = setEmitFlags(
      setTextRange(
        factory2.createForStatement(
          /*initializer*/
          setEmitFlags(
            setTextRange(
              factory2.createVariableDeclarationList([
                setTextRange(factory2.createVariableDeclaration(
                  iterator,
                  /*exclamationToken*/
                  void 0,
                  /*type*/
                  void 0,
                  initializer
                ), node.expression),
                factory2.createVariableDeclaration(
                  result,
                  /*exclamationToken*/
                  void 0,
                  /*type*/
                  void 0,
                  next
                )
              ]),
              node.expression
            ),
            4194304 /* NoHoisting */
          ),
          /*condition*/
          factory2.createLogicalNot(factory2.createPropertyAccessExpression(result, "done")),
          /*incrementor*/
          factory2.createAssignment(result, next),
          /*statement*/
          convertForOfStatementHead(
            node,
            factory2.createPropertyAccessExpression(result, "value"),
            convertedLoopBodyStatements
          )
        ),
        /*location*/
        node
      ),
      512 /* NoTokenTrailingSourceMaps */
    );
    return factory2.createTryStatement(
      factory2.createBlock([
        factory2.restoreEnclosingLabel(
          forStatement,
          outermostLabeledStatement,
          convertedLoopState && resetLabel
        )
      ]),
      factory2.createCatchClause(
        factory2.createVariableDeclaration(catchVariable),
        setEmitFlags(
          factory2.createBlock([
            factory2.createExpressionStatement(
              factory2.createAssignment(
                errorRecord,
                factory2.createObjectLiteralExpression([
                  factory2.createPropertyAssignment("error", catchVariable)
                ])
              )
            )
          ]),
          1 /* SingleLine */
        )
      ),
      factory2.createBlock([
        factory2.createTryStatement(
          /*tryBlock*/
          factory2.createBlock([
            setEmitFlags(
              factory2.createIfStatement(
                factory2.createLogicalAnd(
                  factory2.createLogicalAnd(
                    result,
                    factory2.createLogicalNot(
                      factory2.createPropertyAccessExpression(result, "done")
                    )
                  ),
                  factory2.createAssignment(
                    returnMethod,
                    factory2.createPropertyAccessExpression(iterator, "return")
                  )
                ),
                factory2.createExpressionStatement(
                  factory2.createFunctionCallCall(returnMethod, iterator, [])
                )
              ),
              1 /* SingleLine */
            )
          ]),
          /*catchClause*/
          void 0,
          /*finallyBlock*/
          setEmitFlags(
            factory2.createBlock([
              setEmitFlags(
                factory2.createIfStatement(
                  errorRecord,
                  factory2.createThrowStatement(
                    factory2.createPropertyAccessExpression(errorRecord, "error")
                  )
                ),
                1 /* SingleLine */
              )
            ]),
            1 /* SingleLine */
          )
        )
      ])
    );
  }
  function visitObjectLiteralExpression(node) {
    const properties = node.properties;
    let numInitialProperties = -1, hasComputed = false;
    for (let i = 0; i < properties.length; i++) {
      const property = properties[i];
      if (property.transformFlags & 1048576 /* ContainsYield */ && hierarchyFacts & 4 /* AsyncFunctionBody */ || (hasComputed = Debug.checkDefined(property.name).kind === 167 /* ComputedPropertyName */)) {
        numInitialProperties = i;
        break;
      }
    }
    if (numInitialProperties < 0) {
      return visitEachChild(node, visitor, context);
    }
    const temp = factory2.createTempVariable(hoistVariableDeclaration);
    const expressions = [];
    const assignment = factory2.createAssignment(
      temp,
      setEmitFlags(
        factory2.createObjectLiteralExpression(
          visitNodes2(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
          node.multiLine
        ),
        hasComputed ? 131072 /* Indented */ : 0
      )
    );
    if (node.multiLine) {
      startOnNewLine(assignment);
    }
    expressions.push(assignment);
    addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
    expressions.push(node.multiLine ? startOnNewLine(setParent(setTextRange(factory2.cloneNode(temp), temp), temp.parent)) : temp);
    return factory2.inlineExpressions(expressions);
  }
  function shouldConvertPartOfIterationStatement(node) {
    return resolver.hasNodeCheckFlag(node, 8192 /* ContainsCapturedBlockScopeBinding */);
  }
  function shouldConvertInitializerOfForStatement(node) {
    return isForStatement(node) && !!node.initializer && shouldConvertPartOfIterationStatement(node.initializer);
  }
  function shouldConvertConditionOfForStatement(node) {
    return isForStatement(node) && !!node.condition && shouldConvertPartOfIterationStatement(node.condition);
  }
  function shouldConvertIncrementorOfForStatement(node) {
    return isForStatement(node) && !!node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
  }
  function shouldConvertIterationStatement(node) {
    return shouldConvertBodyOfIterationStatement(node) || shouldConvertInitializerOfForStatement(node);
  }
  function shouldConvertBodyOfIterationStatement(node) {
    return resolver.hasNodeCheckFlag(node, 4096 /* LoopWithCapturedBlockScopedBinding */);
  }
  function hoistVariableDeclarationDeclaredInConvertedLoop(state, node) {
    if (!state.hoistedLocalVariables) {
      state.hoistedLocalVariables = [];
    }
    visit(node.name);
    function visit(node2) {
      if (node2.kind === 80 /* Identifier */) {
        state.hoistedLocalVariables.push(node2);
      } else {
        for (const element of node2.elements) {
          if (!isOmittedExpression(element)) {
            visit(element.name);
          }
        }
      }
    }
  }
  function convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert) {
    if (!shouldConvertIterationStatement(node)) {
      let saveAllowedNonLabeledJumps;
      if (convertedLoopState) {
        saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
        convertedLoopState.allowedNonLabeledJumps = 2 /* Break */ | 4 /* Continue */;
      }
      const result = convert ? convert(
        node,
        outermostLabeledStatement,
        /*convertedLoopBodyStatements*/
        void 0,
        ancestorFacts
      ) : factory2.restoreEnclosingLabel(
        isForStatement(node) ? visitEachChildOfForStatement2(node) : visitEachChild(node, visitor, context),
        outermostLabeledStatement,
        convertedLoopState && resetLabel
      );
      if (convertedLoopState) {
        convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
      }
      return result;
    }
    const currentState = createConvertedLoopState(node);
    const statements = [];
    const outerConvertedLoopState = convertedLoopState;
    convertedLoopState = currentState;
    const initializerFunction = shouldConvertInitializerOfForStatement(node) ? createFunctionForInitializerOfForStatement(node, currentState) : void 0;
    const bodyFunction = shouldConvertBodyOfIterationStatement(node) ? createFunctionForBodyOfIterationStatement(node, currentState, outerConvertedLoopState) : void 0;
    convertedLoopState = outerConvertedLoopState;
    if (initializerFunction) statements.push(initializerFunction.functionDeclaration);
    if (bodyFunction) statements.push(bodyFunction.functionDeclaration);
    addExtraDeclarationsForConvertedLoop(statements, currentState, outerConvertedLoopState);
    if (initializerFunction) {
      statements.push(generateCallToConvertedLoopInitializer(initializerFunction.functionName, initializerFunction.containsYield));
    }
    let loop;
    if (bodyFunction) {
      if (convert) {
        loop = convert(node, outermostLabeledStatement, bodyFunction.part, ancestorFacts);
      } else {
        const clone = convertIterationStatementCore(node, initializerFunction, factory2.createBlock(
          bodyFunction.part,
          /*multiLine*/
          true
        ));
        loop = factory2.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
      }
    } else {
      const clone = convertIterationStatementCore(node, initializerFunction, Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory2.liftToBlock)));
      loop = factory2.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
    }
    statements.push(loop);
    return statements;
  }
  function convertIterationStatementCore(node, initializerFunction, convertedLoopBody) {
    switch (node.kind) {
      case 248 /* ForStatement */:
        return convertForStatement(node, initializerFunction, convertedLoopBody);
      case 249 /* ForInStatement */:
        return convertForInStatement(node, convertedLoopBody);
      case 250 /* ForOfStatement */:
        return convertForOfStatement(node, convertedLoopBody);
      case 246 /* DoStatement */:
        return convertDoStatement(node, convertedLoopBody);
      case 247 /* WhileStatement */:
        return convertWhileStatement(node, convertedLoopBody);
      default:
        return Debug.failBadSyntaxKind(node, "IterationStatement expected");
    }
  }
  function convertForStatement(node, initializerFunction, convertedLoopBody) {
    const shouldConvertCondition = node.condition && shouldConvertPartOfIterationStatement(node.condition);
    const shouldConvertIncrementor = shouldConvertCondition || node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
    return factory2.updateForStatement(
      node,
      visitNode(initializerFunction ? initializerFunction.part : node.initializer, visitorWithUnusedExpressionResult, isForInitializer),
      visitNode(shouldConvertCondition ? void 0 : node.condition, visitor, isExpression),
      visitNode(shouldConvertIncrementor ? void 0 : node.incrementor, visitorWithUnusedExpressionResult, isExpression),
      convertedLoopBody
    );
  }
  function convertForOfStatement(node, convertedLoopBody) {
    return factory2.updateForOfStatement(
      node,
      /*awaitModifier*/
      void 0,
      Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
      convertedLoopBody
    );
  }
  function convertForInStatement(node, convertedLoopBody) {
    return factory2.updateForInStatement(
      node,
      Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)),
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
      convertedLoopBody
    );
  }
  function convertDoStatement(node, convertedLoopBody) {
    return factory2.updateDoStatement(
      node,
      convertedLoopBody,
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression))
    );
  }
  function convertWhileStatement(node, convertedLoopBody) {
    return factory2.updateWhileStatement(
      node,
      Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
      convertedLoopBody
    );
  }
  function createConvertedLoopState(node) {
    let loopInitializer;
    switch (node.kind) {
      case 248 /* ForStatement */:
      case 249 /* ForInStatement */:
      case 250 /* ForOfStatement */:
        const initializer = node.initializer;
        if (initializer && initializer.kind === 261 /* VariableDeclarationList */) {
          loopInitializer = initializer;
        }
        break;
    }
    const loopParameters = [];
    const loopOutParameters = [];
    if (loopInitializer && getCombinedNodeFlags(loopInitializer) & 7 /* BlockScoped */) {
      const hasCapturedBindingsInForHead = shouldConvertInitializerOfForStatement(node) || shouldConvertConditionOfForStatement(node) || shouldConvertIncrementorOfForStatement(node);
      for (const decl of loopInitializer.declarations) {
        processLoopVariableDeclaration(node, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForHead);
      }
    }
    const currentState = { loopParameters, loopOutParameters };
    if (convertedLoopState) {
      if (convertedLoopState.argumentsName) {
        currentState.argumentsName = convertedLoopState.argumentsName;
      }
      if (convertedLoopState.thisName) {
        currentState.thisName = convertedLoopState.thisName;
      }
      if (convertedLoopState.hoistedLocalVariables) {
        currentState.hoistedLocalVariables = convertedLoopState.hoistedLocalVariables;
      }
    }
    return currentState;
  }
  function addExtraDeclarationsForConvertedLoop(statements, state, outerState) {
    let extraVariableDeclarations;
    if (state.argumentsName) {
      if (outerState) {
        outerState.argumentsName = state.argumentsName;
      } else {
        (extraVariableDeclarations || (extraVariableDeclarations = [])).push(
          factory2.createVariableDeclaration(
            state.argumentsName,
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            factory2.createIdentifier("arguments")
          )
        );
      }
    }
    if (state.thisName) {
      if (outerState) {
        outerState.thisName = state.thisName;
      } else {
        (extraVariableDeclarations || (extraVariableDeclarations = [])).push(
          factory2.createVariableDeclaration(
            state.thisName,
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            factory2.createIdentifier("this")
          )
        );
      }
    }
    if (state.hoistedLocalVariables) {
      if (outerState) {
        outerState.hoistedLocalVariables = state.hoistedLocalVariables;
      } else {
        if (!extraVariableDeclarations) {
          extraVariableDeclarations = [];
        }
        for (const identifier of state.hoistedLocalVariables) {
          extraVariableDeclarations.push(factory2.createVariableDeclaration(identifier));
        }
      }
    }
    if (state.loopOutParameters.length) {
      if (!extraVariableDeclarations) {
        extraVariableDeclarations = [];
      }
      for (const outParam of state.loopOutParameters) {
        extraVariableDeclarations.push(factory2.createVariableDeclaration(outParam.outParamName));
      }
    }
    if (state.conditionVariable) {
      if (!extraVariableDeclarations) {
        extraVariableDeclarations = [];
      }
      extraVariableDeclarations.push(factory2.createVariableDeclaration(
        state.conditionVariable,
        /*exclamationToken*/
        void 0,
        /*type*/
        void 0,
        factory2.createFalse()
      ));
    }
    if (extraVariableDeclarations) {
      statements.push(factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList(extraVariableDeclarations)
      ));
    }
  }
  function createOutVariable(p) {
    return factory2.createVariableDeclaration(
      p.originalName,
      /*exclamationToken*/
      void 0,
      /*type*/
      void 0,
      p.outParamName
    );
  }
  function createFunctionForInitializerOfForStatement(node, currentState) {
    const functionName = factory2.createUniqueName("_loop_init");
    const containsYield = (node.initializer.transformFlags & 1048576 /* ContainsYield */) !== 0;
    let emitFlags = 0 /* None */;
    if (currentState.containsLexicalThis) emitFlags |= 16 /* CapturesThis */;
    if (containsYield && hierarchyFacts & 4 /* AsyncFunctionBody */) emitFlags |= 524288 /* AsyncFunctionBody */;
    const statements = [];
    statements.push(factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      node.initializer
    ));
    copyOutParameters(currentState.loopOutParameters, 2 /* Initializer */, 1 /* ToOutParameter */, statements);
    const functionDeclaration = factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      setEmitFlags(
        factory2.createVariableDeclarationList([
          factory2.createVariableDeclaration(
            functionName,
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            setEmitFlags(
              factory2.createFunctionExpression(
                /*modifiers*/
                void 0,
                containsYield ? factory2.createToken(42 /* AsteriskToken */) : void 0,
                /*name*/
                void 0,
                /*typeParameters*/
                void 0,
                /*parameters*/
                void 0,
                /*type*/
                void 0,
                Debug.checkDefined(visitNode(
                  factory2.createBlock(
                    statements,
                    /*multiLine*/
                    true
                  ),
                  visitor,
                  isBlock
                ))
              ),
              emitFlags
            )
          )
        ]),
        4194304 /* NoHoisting */
      )
    );
    const part = factory2.createVariableDeclarationList(map(currentState.loopOutParameters, createOutVariable));
    return { functionName, containsYield, functionDeclaration, part };
  }
  function createFunctionForBodyOfIterationStatement(node, currentState, outerState) {
    const functionName = factory2.createUniqueName("_loop");
    startLexicalEnvironment();
    const statement = visitNode(node.statement, visitor, isStatement, factory2.liftToBlock);
    const lexicalEnvironment = endLexicalEnvironment();
    const statements = [];
    if (shouldConvertConditionOfForStatement(node) || shouldConvertIncrementorOfForStatement(node)) {
      currentState.conditionVariable = factory2.createUniqueName("inc");
      if (node.incrementor) {
        statements.push(factory2.createIfStatement(
          currentState.conditionVariable,
          factory2.createExpressionStatement(Debug.checkDefined(visitNode(node.incrementor, visitor, isExpression))),
          factory2.createExpressionStatement(factory2.createAssignment(currentState.conditionVariable, factory2.createTrue()))
        ));
      } else {
        statements.push(factory2.createIfStatement(
          factory2.createLogicalNot(currentState.conditionVariable),
          factory2.createExpressionStatement(factory2.createAssignment(currentState.conditionVariable, factory2.createTrue()))
        ));
      }
      if (shouldConvertConditionOfForStatement(node)) {
        statements.push(factory2.createIfStatement(
          factory2.createPrefixUnaryExpression(54 /* ExclamationToken */, Debug.checkDefined(visitNode(node.condition, visitor, isExpression))),
          Debug.checkDefined(visitNode(factory2.createBreakStatement(), visitor, isStatement))
        ));
      }
    }
    Debug.assert(statement);
    if (isBlock(statement)) {
      addRange(statements, statement.statements);
    } else {
      statements.push(statement);
    }
    copyOutParameters(currentState.loopOutParameters, 1 /* Body */, 1 /* ToOutParameter */, statements);
    insertStatementsAfterStandardPrologue(statements, lexicalEnvironment);
    const loopBody = factory2.createBlock(
      statements,
      /*multiLine*/
      true
    );
    if (isBlock(statement)) setOriginalNode(loopBody, statement);
    const containsYield = (node.statement.transformFlags & 1048576 /* ContainsYield */) !== 0;
    let emitFlags = 1048576 /* ReuseTempVariableScope */;
    if (currentState.containsLexicalThis) emitFlags |= 16 /* CapturesThis */;
    if (containsYield && (hierarchyFacts & 4 /* AsyncFunctionBody */) !== 0) emitFlags |= 524288 /* AsyncFunctionBody */;
    const functionDeclaration = factory2.createVariableStatement(
      /*modifiers*/
      void 0,
      setEmitFlags(
        factory2.createVariableDeclarationList(
          [
            factory2.createVariableDeclaration(
              functionName,
              /*exclamationToken*/
              void 0,
              /*type*/
              void 0,
              setEmitFlags(
                factory2.createFunctionExpression(
                  /*modifiers*/
                  void 0,
                  containsYield ? factory2.createToken(42 /* AsteriskToken */) : void 0,
                  /*name*/
                  void 0,
                  /*typeParameters*/
                  void 0,
                  currentState.loopParameters,
                  /*type*/
                  void 0,
                  loopBody
                ),
                emitFlags
              )
            )
          ]
        ),
        4194304 /* NoHoisting */
      )
    );
    const part = generateCallToConvertedLoop(functionName, currentState, outerState, containsYield);
    return { functionName, containsYield, functionDeclaration, part };
  }
  function copyOutParameter(outParam, copyDirection) {
    const source = copyDirection === 0 /* ToOriginal */ ? outParam.outParamName : outParam.originalName;
    const target = copyDirection === 0 /* ToOriginal */ ? outParam.originalName : outParam.outParamName;
    return factory2.createBinaryExpression(target, 64 /* EqualsToken */, source);
  }
  function copyOutParameters(outParams, partFlags, copyDirection, statements) {
    for (const outParam of outParams) {
      if (outParam.flags & partFlags) {
        statements.push(factory2.createExpressionStatement(copyOutParameter(outParam, copyDirection)));
      }
    }
  }
  function generateCallToConvertedLoopInitializer(initFunctionExpressionName, containsYield) {
    const call = factory2.createCallExpression(
      initFunctionExpressionName,
      /*typeArguments*/
      void 0,
      []
    );
    const callResult = containsYield ? factory2.createYieldExpression(
      factory2.createToken(42 /* AsteriskToken */),
      setEmitFlags(call, 8388608 /* Iterator */)
    ) : call;
    return factory2.createExpressionStatement(callResult);
  }
  function generateCallToConvertedLoop(loopFunctionExpressionName, state, outerState, containsYield) {
    const statements = [];
    const isSimpleLoop = !(state.nonLocalJumps & ~4 /* Continue */) && !state.labeledNonLocalBreaks && !state.labeledNonLocalContinues;
    const call = factory2.createCallExpression(
      loopFunctionExpressionName,
      /*typeArguments*/
      void 0,
      map(state.loopParameters, (p) => p.name)
    );
    const callResult = containsYield ? factory2.createYieldExpression(
      factory2.createToken(42 /* AsteriskToken */),
      setEmitFlags(call, 8388608 /* Iterator */)
    ) : call;
    if (isSimpleLoop) {
      statements.push(factory2.createExpressionStatement(callResult));
      copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
    } else {
      const loopResultName = factory2.createUniqueName("state");
      const stateVariable = factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList(
          [factory2.createVariableDeclaration(
            loopResultName,
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            callResult
          )]
        )
      );
      statements.push(stateVariable);
      copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
      if (state.nonLocalJumps & 8 /* Return */) {
        let returnStatement;
        if (outerState) {
          outerState.nonLocalJumps |= 8 /* Return */;
          returnStatement = factory2.createReturnStatement(loopResultName);
        } else {
          returnStatement = factory2.createReturnStatement(factory2.createPropertyAccessExpression(loopResultName, "value"));
        }
        statements.push(
          factory2.createIfStatement(
            factory2.createTypeCheck(loopResultName, "object"),
            returnStatement
          )
        );
      }
      if (state.nonLocalJumps & 2 /* Break */) {
        statements.push(
          factory2.createIfStatement(
            factory2.createStrictEquality(
              loopResultName,
              factory2.createStringLiteral("break")
            ),
            factory2.createBreakStatement()
          )
        );
      }
      if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
        const caseClauses = [];
        processLabeledJumps(
          state.labeledNonLocalBreaks,
          /*isBreak*/
          true,
          loopResultName,
          outerState,
          caseClauses
        );
        processLabeledJumps(
          state.labeledNonLocalContinues,
          /*isBreak*/
          false,
          loopResultName,
          outerState,
          caseClauses
        );
        statements.push(
          factory2.createSwitchStatement(
            loopResultName,
            factory2.createCaseBlock(caseClauses)
          )
        );
      }
    }
    return statements;
  }
  function setLabeledJump(state, isBreak, labelText, labelMarker) {
    if (isBreak) {
      if (!state.labeledNonLocalBreaks) {
        state.labeledNonLocalBreaks = /* @__PURE__ */ new Map();
      }
      state.labeledNonLocalBreaks.set(labelText, labelMarker);
    } else {
      if (!state.labeledNonLocalContinues) {
        state.labeledNonLocalContinues = /* @__PURE__ */ new Map();
      }
      state.labeledNonLocalContinues.set(labelText, labelMarker);
    }
  }
  function processLabeledJumps(table, isBreak, loopResultName, outerLoop, caseClauses) {
    if (!table) {
      return;
    }
    table.forEach((labelMarker, labelText) => {
      const statements = [];
      if (!outerLoop || outerLoop.labels && outerLoop.labels.get(labelText)) {
        const label = factory2.createIdentifier(labelText);
        statements.push(isBreak ? factory2.createBreakStatement(label) : factory2.createContinueStatement(label));
      } else {
        setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
        statements.push(factory2.createReturnStatement(loopResultName));
      }
      caseClauses.push(factory2.createCaseClause(factory2.createStringLiteral(labelMarker), statements));
    });
  }
  function processLoopVariableDeclaration(container, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForHead) {
    const name = decl.name;
    if (isBindingPattern(name)) {
      for (const element of name.elements) {
        if (!isOmittedExpression(element)) {
          processLoopVariableDeclaration(container, element, loopParameters, loopOutParameters, hasCapturedBindingsInForHead);
        }
      }
    } else {
      loopParameters.push(factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        name
      ));
      const needsOutParam = resolver.hasNodeCheckFlag(decl, 65536 /* NeedsLoopOutParameter */);
      if (needsOutParam || hasCapturedBindingsInForHead) {
        const outParamName = factory2.createUniqueName("out_" + idText(name));
        let flags = 0 /* None */;
        if (needsOutParam) {
          flags |= 1 /* Body */;
        }
        if (isForStatement(container)) {
          if (container.initializer && resolver.isBindingCapturedByNode(container.initializer, decl)) {
            flags |= 2 /* Initializer */;
          }
          if (container.condition && resolver.isBindingCapturedByNode(container.condition, decl) || container.incrementor && resolver.isBindingCapturedByNode(container.incrementor, decl)) {
            flags |= 1 /* Body */;
          }
        }
        loopOutParameters.push({ flags, originalName: name, outParamName });
      }
    }
  }
  function addObjectLiteralMembers(expressions, node, receiver, start) {
    const properties = node.properties;
    const numProperties = properties.length;
    for (let i = start; i < numProperties; i++) {
      const property = properties[i];
      switch (property.kind) {
        case 177 /* GetAccessor */:
        case 178 /* SetAccessor */:
          const accessors = getAllAccessorDeclarations(node.properties, property);
          if (property === accessors.firstAccessor) {
            expressions.push(transformAccessorsToExpression(receiver, accessors, node, !!node.multiLine));
          }
          break;
        case 174 /* MethodDeclaration */:
          expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
          break;
        case 303 /* PropertyAssignment */:
          expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
          break;
        case 304 /* ShorthandPropertyAssignment */:
          expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
          break;
        default:
          Debug.failBadSyntaxKind(node);
          break;
      }
    }
  }
  function transformPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
    const expression = factory2.createAssignment(
      createMemberAccessForPropertyName(
        factory2,
        receiver,
        Debug.checkDefined(visitNode(property.name, visitor, isPropertyName))
      ),
      Debug.checkDefined(visitNode(property.initializer, visitor, isExpression))
    );
    setTextRange(expression, property);
    if (startsOnNewLine) {
      startOnNewLine(expression);
    }
    return expression;
  }
  function transformShorthandPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
    const expression = factory2.createAssignment(
      createMemberAccessForPropertyName(
        factory2,
        receiver,
        Debug.checkDefined(visitNode(property.name, visitor, isPropertyName))
      ),
      factory2.cloneNode(property.name)
    );
    setTextRange(expression, property);
    if (startsOnNewLine) {
      startOnNewLine(expression);
    }
    return expression;
  }
  function transformObjectLiteralMethodDeclarationToExpression(method, receiver, container, startsOnNewLine) {
    const expression = factory2.createAssignment(
      createMemberAccessForPropertyName(
        factory2,
        receiver,
        Debug.checkDefined(visitNode(method.name, visitor, isPropertyName))
      ),
      transformFunctionLikeToExpression(
        method,
        /*location*/
        method,
        /*name*/
        void 0,
        container
      )
    );
    setTextRange(expression, method);
    if (startsOnNewLine) {
      startOnNewLine(expression);
    }
    return expression;
  }
  function visitCatchClause(node) {
    const ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
    let updated;
    Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
    if (isBindingPattern(node.variableDeclaration.name)) {
      const temp = factory2.createTempVariable(
        /*recordTempVariable*/
        void 0
      );
      const newVariableDeclaration = factory2.createVariableDeclaration(temp);
      setTextRange(newVariableDeclaration, node.variableDeclaration);
      const vars = flattenDestructuringBinding(
        node.variableDeclaration,
        visitor,
        context,
        0 /* All */,
        temp
      );
      const list = factory2.createVariableDeclarationList(vars);
      setTextRange(list, node.variableDeclaration);
      const destructure = factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        list
      );
      updated = factory2.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
    } else {
      updated = visitEachChild(node, visitor, context);
    }
    exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
    return updated;
  }
  function addStatementToStartOfBlock(block, statement) {
    const transformedStatements = visitNodes2(block.statements, visitor, isStatement);
    return factory2.updateBlock(block, [statement, ...transformedStatements]);
  }
  function visitMethodDeclaration(node) {
    Debug.assert(!isComputedPropertyName(node.name));
    const functionExpression = transformFunctionLikeToExpression(
      node,
      /*location*/
      moveRangePos(node, -1),
      /*name*/
      void 0,
      /*container*/
      void 0
    );
    setEmitFlags(functionExpression, 1024 /* NoLeadingComments */ | getEmitFlags(functionExpression));
    return setTextRange(
      factory2.createPropertyAssignment(
        node.name,
        functionExpression
      ),
      /*location*/
      node
    );
  }
  function visitAccessorDeclaration(node) {
    Debug.assert(!isComputedPropertyName(node.name));
    const savedConvertedLoopState = convertedLoopState;
    convertedLoopState = void 0;
    const ancestorFacts = enterSubtree(32670 /* FunctionExcludes */, 65 /* FunctionIncludes */);
    let updated;
    const parameters = visitParameterList(node.parameters, visitor, context);
    const body = transformFunctionBody(node);
    if (node.kind === 177 /* GetAccessor */) {
      updated = factory2.updateGetAccessorDeclaration(node, node.modifiers, node.name, parameters, node.type, body);
    } else {
      updated = factory2.updateSetAccessorDeclaration(node, node.modifiers, node.name, parameters, body);
    }
    exitSubtree(ancestorFacts, 229376 /* FunctionSubtreeExcludes */, 0 /* None */);
    convertedLoopState = savedConvertedLoopState;
    return updated;
  }
  function visitShorthandPropertyAssignment(node) {
    return setTextRange(
      factory2.createPropertyAssignment(
        node.name,
        visitIdentifier(factory2.cloneNode(node.name))
      ),
      /*location*/
      node
    );
  }
  function visitComputedPropertyName(node) {
    return visitEachChild(node, visitor, context);
  }
  function visitYieldExpression(node) {
    return visitEachChild(node, visitor, context);
  }
  function visitArrayLiteralExpression(node) {
    if (some(node.elements, isSpreadElement)) {
      return transformAndSpreadElements(
        node.elements,
        /*isArgumentList*/
        false,
        !!node.multiLine,
        /*hasTrailingComma*/
        !!node.elements.hasTrailingComma
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCallExpression(node) {
    if (getInternalEmitFlags(node) & 1 /* TypeScriptClassWrapper */) {
      return visitTypeScriptClassWrapper(node);
    }
    const expression = skipOuterExpressions(node.expression);
    if (expression.kind === 108 /* SuperKeyword */ || isSuperProperty(expression) || some(node.arguments, isSpreadElement)) {
      return visitCallExpressionWithPotentialCapturedThisAssignment(
        node,
        /*assignToCapturedThis*/
        true
      );
    }
    return factory2.updateCallExpression(
      node,
      Debug.checkDefined(visitNode(node.expression, callExpressionVisitor, isExpression)),
      /*typeArguments*/
      void 0,
      visitNodes2(node.arguments, visitor, isExpression)
    );
  }
  function visitTypeScriptClassWrapper(node) {
    const body = cast(cast(skipOuterExpressions(node.expression), isArrowFunction).body, isBlock);
    const isVariableStatementWithInitializer = (stmt) => isVariableStatement(stmt) && !!first(stmt.declarationList.declarations).initializer;
    const savedConvertedLoopState = convertedLoopState;
    convertedLoopState = void 0;
    const bodyStatements = visitNodes2(body.statements, classWrapperStatementVisitor, isStatement);
    convertedLoopState = savedConvertedLoopState;
    const classStatements = filter(bodyStatements, isVariableStatementWithInitializer);
    const remainingStatements = filter(bodyStatements, (stmt) => !isVariableStatementWithInitializer(stmt));
    const varStatement = cast(first(classStatements), isVariableStatement);
    const variable = varStatement.declarationList.declarations[0];
    const initializer = skipOuterExpressions(variable.initializer);
    let aliasAssignment = tryCast(initializer, isAssignmentExpression);
    if (!aliasAssignment && isBinaryExpression(initializer) && initializer.operatorToken.kind === 28 /* CommaToken */) {
      aliasAssignment = tryCast(initializer.left, isAssignmentExpression);
    }
    const call = cast(aliasAssignment ? skipOuterExpressions(aliasAssignment.right) : initializer, isCallExpression);
    const func = cast(skipOuterExpressions(call.expression), isFunctionExpression);
    const funcStatements = func.body.statements;
    let classBodyStart = 0;
    let classBodyEnd = -1;
    const statements = [];
    if (aliasAssignment) {
      const extendsCall = tryCast(funcStatements[classBodyStart], isExpressionStatement);
      if (extendsCall) {
        statements.push(extendsCall);
        classBodyStart++;
      }
      statements.push(funcStatements[classBodyStart]);
      classBodyStart++;
      statements.push(
        factory2.createExpressionStatement(
          factory2.createAssignment(
            aliasAssignment.left,
            cast(variable.name, isIdentifier)
          )
        )
      );
    }
    while (!isReturnStatement(elementAt(funcStatements, classBodyEnd))) {
      classBodyEnd--;
    }
    addRange(statements, funcStatements, classBodyStart, classBodyEnd);
    if (classBodyEnd < -1) {
      addRange(statements, funcStatements, classBodyEnd + 1);
    }
    const returnStatement = tryCast(elementAt(funcStatements, classBodyEnd), isReturnStatement);
    for (const statement of remainingStatements) {
      if (isReturnStatement(statement) && (returnStatement == null ? void 0 : returnStatement.expression) && !isIdentifier(returnStatement.expression)) {
        statements.push(returnStatement);
      } else {
        statements.push(statement);
      }
    }
    addRange(
      statements,
      classStatements,
      /*start*/
      1
    );
    return factory2.restoreOuterExpressions(
      node.expression,
      factory2.restoreOuterExpressions(
        variable.initializer,
        factory2.restoreOuterExpressions(
          aliasAssignment && aliasAssignment.right,
          factory2.updateCallExpression(
            call,
            factory2.restoreOuterExpressions(
              call.expression,
              factory2.updateFunctionExpression(
                func,
                /*modifiers*/
                void 0,
                /*asteriskToken*/
                void 0,
                /*name*/
                void 0,
                /*typeParameters*/
                void 0,
                func.parameters,
                /*type*/
                void 0,
                factory2.updateBlock(
                  func.body,
                  statements
                )
              )
            ),
            /*typeArguments*/
            void 0,
            call.arguments
          )
        )
      )
    );
  }
  function visitCallExpressionWithPotentialCapturedThisAssignment(node, assignToCapturedThis) {
    if (node.transformFlags & 32768 /* ContainsRestOrSpread */ || node.expression.kind === 108 /* SuperKeyword */ || isSuperProperty(skipOuterExpressions(node.expression))) {
      const { target, thisArg } = factory2.createCallBinding(node.expression, hoistVariableDeclaration);
      if (node.expression.kind === 108 /* SuperKeyword */) {
        setEmitFlags(thisArg, 8 /* NoSubstitution */);
      }
      let resultingCall;
      if (node.transformFlags & 32768 /* ContainsRestOrSpread */) {
        resultingCall = factory2.createFunctionApplyCall(
          Debug.checkDefined(visitNode(target, callExpressionVisitor, isExpression)),
          node.expression.kind === 108 /* SuperKeyword */ ? thisArg : Debug.checkDefined(visitNode(thisArg, visitor, isExpression)),
          transformAndSpreadElements(
            node.arguments,
            /*isArgumentList*/
            true,
            /*multiLine*/
            false,
            /*hasTrailingComma*/
            false
          )
        );
      } else {
        resultingCall = setTextRange(
          factory2.createFunctionCallCall(
            Debug.checkDefined(visitNode(target, callExpressionVisitor, isExpression)),
            node.expression.kind === 108 /* SuperKeyword */ ? thisArg : Debug.checkDefined(visitNode(thisArg, visitor, isExpression)),
            visitNodes2(node.arguments, visitor, isExpression)
          ),
          node
        );
      }
      if (node.expression.kind === 108 /* SuperKeyword */) {
        const initializer = factory2.createLogicalOr(
          resultingCall,
          createActualThis()
        );
        resultingCall = assignToCapturedThis ? factory2.createAssignment(createCapturedThis(), initializer) : initializer;
      }
      return setOriginalNode(resultingCall, node);
    }
    if (isSuperCall(node)) {
      hierarchyFacts |= 131072 /* CapturedLexicalThis */;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitNewExpression(node) {
    if (some(node.arguments, isSpreadElement)) {
      const { target, thisArg } = factory2.createCallBinding(factory2.createPropertyAccessExpression(node.expression, "bind"), hoistVariableDeclaration);
      return factory2.createNewExpression(
        factory2.createFunctionApplyCall(
          Debug.checkDefined(visitNode(target, visitor, isExpression)),
          thisArg,
          transformAndSpreadElements(
            factory2.createNodeArray([factory2.createVoidZero(), ...node.arguments]),
            /*isArgumentList*/
            true,
            /*multiLine*/
            false,
            /*hasTrailingComma*/
            false
          )
        ),
        /*typeArguments*/
        void 0,
        []
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function transformAndSpreadElements(elements, isArgumentList, multiLine, hasTrailingComma) {
    const numElements = elements.length;
    const segments = flatten(
      // As we visit each element, we return one of two functions to use as the "key":
      // - `visitSpanOfSpreads` for one or more contiguous `...` spread expressions, i.e. `...a, ...b` in `[1, 2, ...a, ...b]`
      // - `visitSpanOfNonSpreads` for one or more contiguous non-spread elements, i.e. `1, 2`, in `[1, 2, ...a, ...b]`
      spanMap(elements, partitionSpread, (partition, visitPartition, _start, end) => visitPartition(partition, multiLine, hasTrailingComma && end === numElements))
    );
    if (segments.length === 1) {
      const firstSegment = segments[0];
      if (isArgumentList && !compilerOptions.downlevelIteration || isPackedArrayLiteral(firstSegment.expression) || isCallToHelper(firstSegment.expression, "___spreadArray")) {
        return firstSegment.expression;
      }
    }
    const helpers = emitHelpers();
    const startsWithSpread = segments[0].kind !== 0 /* None */;
    let expression = startsWithSpread ? factory2.createArrayLiteralExpression() : segments[0].expression;
    for (let i = startsWithSpread ? 0 : 1; i < segments.length; i++) {
      const segment = segments[i];
      expression = helpers.createSpreadArrayHelper(
        expression,
        segment.expression,
        segment.kind === 1 /* UnpackedSpread */ && !isArgumentList
      );
    }
    return expression;
  }
  function partitionSpread(node) {
    return isSpreadElement(node) ? visitSpanOfSpreads : visitSpanOfNonSpreads;
  }
  function visitSpanOfSpreads(chunk) {
    return map(chunk, visitExpressionOfSpread);
  }
  function visitExpressionOfSpread(node) {
    Debug.assertNode(node, isSpreadElement);
    let expression = visitNode(node.expression, visitor, isExpression);
    Debug.assert(expression);
    const isCallToReadHelper = isCallToHelper(expression, "___read");
    let kind = isCallToReadHelper || isPackedArrayLiteral(expression) ? 2 /* PackedSpread */ : 1 /* UnpackedSpread */;
    if (compilerOptions.downlevelIteration && kind === 1 /* UnpackedSpread */ && !isArrayLiteralExpression(expression) && !isCallToReadHelper) {
      expression = emitHelpers().createReadHelper(
        expression,
        /*count*/
        void 0
      );
      kind = 2 /* PackedSpread */;
    }
    return createSpreadSegment(kind, expression);
  }
  function visitSpanOfNonSpreads(chunk, multiLine, hasTrailingComma) {
    const expression = factory2.createArrayLiteralExpression(
      visitNodes2(factory2.createNodeArray(chunk, hasTrailingComma), visitor, isExpression),
      multiLine
    );
    return createSpreadSegment(0 /* None */, expression);
  }
  function visitSpreadElement(node) {
    return visitNode(node.expression, visitor, isExpression);
  }
  function visitTemplateLiteral(node) {
    return setTextRange(factory2.createStringLiteral(node.text), node);
  }
  function visitStringLiteral(node) {
    if (node.hasExtendedUnicodeEscape) {
      return setTextRange(factory2.createStringLiteral(node.text), node);
    }
    return node;
  }
  function visitNumericLiteral(node) {
    if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) {
      return setTextRange(factory2.createNumericLiteral(node.text), node);
    }
    return node;
  }
  function visitTaggedTemplateExpression(node) {
    return processTaggedTemplateExpression(
      context,
      node,
      visitor,
      currentSourceFile,
      recordTaggedTemplateString,
      1 /* All */
    );
  }
  function visitTemplateExpression(node) {
    let expression = factory2.createStringLiteral(node.head.text);
    for (const span of node.templateSpans) {
      const args = [Debug.checkDefined(visitNode(span.expression, visitor, isExpression))];
      if (span.literal.text.length > 0) {
        args.push(factory2.createStringLiteral(span.literal.text));
      }
      expression = factory2.createCallExpression(
        factory2.createPropertyAccessExpression(expression, "concat"),
        /*typeArguments*/
        void 0,
        args
      );
    }
    return setTextRange(expression, node);
  }
  function createSyntheticSuper() {
    return factory2.createUniqueName("_super", 16 /* Optimistic */ | 32 /* FileLevel */);
  }
  function visitSuperKeyword(node, isExpressionOfCall) {
    const expression = hierarchyFacts & 8 /* NonStaticClassElement */ && !isExpressionOfCall ? factory2.createPropertyAccessExpression(setOriginalNode(createSyntheticSuper(), node), "prototype") : createSyntheticSuper();
    setOriginalNode(expression, node);
    setCommentRange(expression, node);
    setSourceMapRange(expression, node);
    return expression;
  }
  function visitMetaProperty(node) {
    if (node.keywordToken === 105 /* NewKeyword */ && node.name.escapedText === "target") {
      hierarchyFacts |= 32768 /* NewTarget */;
      return factory2.createUniqueName("_newTarget", 16 /* Optimistic */ | 32 /* FileLevel */);
    }
    return node;
  }
  function onEmitNode(hint, node, emitCallback) {
    if (enabledSubstitutions & 1 /* CapturedThis */ && isFunctionLike(node)) {
      const ancestorFacts = enterSubtree(
        32670 /* FunctionExcludes */,
        getEmitFlags(node) & 16 /* CapturesThis */ ? 65 /* FunctionIncludes */ | 16 /* CapturesThis */ : 65 /* FunctionIncludes */
      );
      previousOnEmitNode(hint, node, emitCallback);
      exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
      return;
    }
    previousOnEmitNode(hint, node, emitCallback);
  }
  function enableSubstitutionsForBlockScopedBindings() {
    if ((enabledSubstitutions & 2 /* BlockScopedBindings */) === 0) {
      enabledSubstitutions |= 2 /* BlockScopedBindings */;
      context.enableSubstitution(80 /* Identifier */);
    }
  }
  function enableSubstitutionsForCapturedThis() {
    if ((enabledSubstitutions & 1 /* CapturedThis */) === 0) {
      enabledSubstitutions |= 1 /* CapturedThis */;
      context.enableSubstitution(110 /* ThisKeyword */);
      context.enableEmitNotification(176 /* Constructor */);
      context.enableEmitNotification(174 /* MethodDeclaration */);
      context.enableEmitNotification(177 /* GetAccessor */);
      context.enableEmitNotification(178 /* SetAccessor */);
      context.enableEmitNotification(219 /* ArrowFunction */);
      context.enableEmitNotification(218 /* FunctionExpression */);
      context.enableEmitNotification(262 /* FunctionDeclaration */);
    }
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (hint === 1 /* Expression */) {
      return substituteExpression(node);
    }
    if (isIdentifier(node)) {
      return substituteIdentifier(node);
    }
    return node;
  }
  function substituteIdentifier(node) {
    if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !isInternalName(node)) {
      const original = getParseTreeNode(node, isIdentifier);
      if (original && isNameOfDeclarationWithCollidingName(original)) {
        return setTextRange(factory2.getGeneratedNameForNode(original), node);
      }
    }
    return node;
  }
  function isNameOfDeclarationWithCollidingName(node) {
    switch (node.parent.kind) {
      case 208 /* BindingElement */:
      case 263 /* ClassDeclaration */:
      case 266 /* EnumDeclaration */:
      case 260 /* VariableDeclaration */:
        return node.parent.name === node && resolver.isDeclarationWithCollidingName(node.parent);
    }
    return false;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 80 /* Identifier */:
        return substituteExpressionIdentifier(node);
      case 110 /* ThisKeyword */:
        return substituteThisKeyword(node);
    }
    return node;
  }
  function substituteExpressionIdentifier(node) {
    if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !isInternalName(node)) {
      const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
      if (declaration && !(isClassLike(declaration) && isPartOfClassBody(declaration, node))) {
        return setTextRange(factory2.getGeneratedNameForNode(getNameOfDeclaration(declaration)), node);
      }
    }
    return node;
  }
  function isPartOfClassBody(declaration, node) {
    let currentNode = getParseTreeNode(node);
    if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) {
      return false;
    }
    const blockScope = getEnclosingBlockScopeContainer(declaration);
    while (currentNode) {
      if (currentNode === blockScope || currentNode === declaration) {
        return false;
      }
      if (isClassElement(currentNode) && currentNode.parent === declaration) {
        return true;
      }
      currentNode = currentNode.parent;
    }
    return false;
  }
  function substituteThisKeyword(node) {
    if (enabledSubstitutions & 1 /* CapturedThis */ && hierarchyFacts & 16 /* CapturesThis */) {
      return setTextRange(createCapturedThis(), node);
    }
    return node;
  }
  function getClassMemberPrefix(node, member) {
    return isStatic(member) ? factory2.getInternalName(node) : factory2.createPropertyAccessExpression(factory2.getInternalName(node), "prototype");
  }
  function hasSynthesizedDefaultSuperCall(constructor, hasExtendsClause) {
    if (!constructor || !hasExtendsClause) {
      return false;
    }
    if (some(constructor.parameters)) {
      return false;
    }
    const statement = firstOrUndefined(constructor.body.statements);
    if (!statement || !nodeIsSynthesized(statement) || statement.kind !== 244 /* ExpressionStatement */) {
      return false;
    }
    const statementExpression = statement.expression;
    if (!nodeIsSynthesized(statementExpression) || statementExpression.kind !== 213 /* CallExpression */) {
      return false;
    }
    const callTarget = statementExpression.expression;
    if (!nodeIsSynthesized(callTarget) || callTarget.kind !== 108 /* SuperKeyword */) {
      return false;
    }
    const callArgument = singleOrUndefined(statementExpression.arguments);
    if (!callArgument || !nodeIsSynthesized(callArgument) || callArgument.kind !== 230 /* SpreadElement */) {
      return false;
    }
    const expression = callArgument.expression;
    return isIdentifier(expression) && expression.escapedText === "arguments";
  }
}

// src/compiler/transformers/generators.ts
function getInstructionName(instruction) {
  switch (instruction) {
    case 2 /* Return */:
      return "return";
    case 3 /* Break */:
      return "break";
    case 4 /* Yield */:
      return "yield";
    case 5 /* YieldStar */:
      return "yield*";
    case 7 /* Endfinally */:
      return "endfinally";
    default:
      return void 0;
  }
}
function transformGenerators(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    resumeLexicalEnvironment,
    endLexicalEnvironment,
    hoistFunctionDeclaration,
    hoistVariableDeclaration
  } = context;
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const resolver = context.getEmitResolver();
  const previousOnSubstituteNode = context.onSubstituteNode;
  context.onSubstituteNode = onSubstituteNode;
  let renamedCatchVariables;
  let renamedCatchVariableDeclarations;
  let inGeneratorFunctionBody;
  let inStatementContainingYield;
  let blocks;
  let blockOffsets;
  let blockActions;
  let blockStack;
  let labelOffsets;
  let labelExpressions;
  let nextLabelId = 1;
  let operations;
  let operationArguments;
  let operationLocations;
  let state;
  let blockIndex = 0;
  let labelNumber = 0;
  let labelNumbers;
  let lastOperationWasAbrupt;
  let lastOperationWasCompletion;
  let clauses;
  let statements;
  let exceptionBlockStack;
  let currentExceptionBlock;
  let withBlockStack;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile || (node.transformFlags & 2048 /* ContainsGenerator */) === 0) {
      return node;
    }
    const visited = visitEachChild(node, visitor, context);
    addEmitHelpers(visited, context.readEmitHelpers());
    return visited;
  }
  function visitor(node) {
    const transformFlags = node.transformFlags;
    if (inStatementContainingYield) {
      return visitJavaScriptInStatementContainingYield(node);
    } else if (inGeneratorFunctionBody) {
      return visitJavaScriptInGeneratorFunctionBody(node);
    } else if (isFunctionLikeDeclaration(node) && node.asteriskToken) {
      return visitGenerator(node);
    } else if (transformFlags & 2048 /* ContainsGenerator */) {
      return visitEachChild(node, visitor, context);
    } else {
      return node;
    }
  }
  function visitJavaScriptInStatementContainingYield(node) {
    switch (node.kind) {
      case 246 /* DoStatement */:
        return visitDoStatement(node);
      case 247 /* WhileStatement */:
        return visitWhileStatement(node);
      case 255 /* SwitchStatement */:
        return visitSwitchStatement(node);
      case 256 /* LabeledStatement */:
        return visitLabeledStatement(node);
      default:
        return visitJavaScriptInGeneratorFunctionBody(node);
    }
  }
  function visitJavaScriptInGeneratorFunctionBody(node) {
    switch (node.kind) {
      case 262 /* FunctionDeclaration */:
        return visitFunctionDeclaration(node);
      case 218 /* FunctionExpression */:
        return visitFunctionExpression(node);
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
        return visitAccessorDeclaration(node);
      case 243 /* VariableStatement */:
        return visitVariableStatement(node);
      case 248 /* ForStatement */:
        return visitForStatement(node);
      case 249 /* ForInStatement */:
        return visitForInStatement(node);
      case 252 /* BreakStatement */:
        return visitBreakStatement(node);
      case 251 /* ContinueStatement */:
        return visitContinueStatement(node);
      case 253 /* ReturnStatement */:
        return visitReturnStatement(node);
      default:
        if (node.transformFlags & 1048576 /* ContainsYield */) {
          return visitJavaScriptContainingYield(node);
        } else if (node.transformFlags & (2048 /* ContainsGenerator */ | 4194304 /* ContainsHoistedDeclarationOrCompletion */)) {
          return visitEachChild(node, visitor, context);
        } else {
          return node;
        }
    }
  }
  function visitJavaScriptContainingYield(node) {
    switch (node.kind) {
      case 226 /* BinaryExpression */:
        return visitBinaryExpression(node);
      case 355 /* CommaListExpression */:
        return visitCommaListExpression(node);
      case 227 /* ConditionalExpression */:
        return visitConditionalExpression(node);
      case 229 /* YieldExpression */:
        return visitYieldExpression(node);
      case 209 /* ArrayLiteralExpression */:
        return visitArrayLiteralExpression(node);
      case 210 /* ObjectLiteralExpression */:
        return visitObjectLiteralExpression(node);
      case 212 /* ElementAccessExpression */:
        return visitElementAccessExpression(node);
      case 213 /* CallExpression */:
        return visitCallExpression(node);
      case 214 /* NewExpression */:
        return visitNewExpression(node);
      default:
        return visitEachChild(node, visitor, context);
    }
  }
  function visitGenerator(node) {
    switch (node.kind) {
      case 262 /* FunctionDeclaration */:
        return visitFunctionDeclaration(node);
      case 218 /* FunctionExpression */:
        return visitFunctionExpression(node);
      default:
        return Debug.failBadSyntaxKind(node);
    }
  }
  function visitFunctionDeclaration(node) {
    if (node.asteriskToken) {
      node = setOriginalNode(
        setTextRange(
          factory2.createFunctionDeclaration(
            node.modifiers,
            /*asteriskToken*/
            void 0,
            node.name,
            /*typeParameters*/
            void 0,
            visitParameterList(node.parameters, visitor, context),
            /*type*/
            void 0,
            transformGeneratorFunctionBody(node.body)
          ),
          /*location*/
          node
        ),
        node
      );
    } else {
      const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
      const savedInStatementContainingYield = inStatementContainingYield;
      inGeneratorFunctionBody = false;
      inStatementContainingYield = false;
      node = visitEachChild(node, visitor, context);
      inGeneratorFunctionBody = savedInGeneratorFunctionBody;
      inStatementContainingYield = savedInStatementContainingYield;
    }
    if (inGeneratorFunctionBody) {
      hoistFunctionDeclaration(node);
      return void 0;
    } else {
      return node;
    }
  }
  function visitFunctionExpression(node) {
    if (node.asteriskToken) {
      node = setOriginalNode(
        setTextRange(
          factory2.createFunctionExpression(
            /*modifiers*/
            void 0,
            /*asteriskToken*/
            void 0,
            node.name,
            /*typeParameters*/
            void 0,
            visitParameterList(node.parameters, visitor, context),
            /*type*/
            void 0,
            transformGeneratorFunctionBody(node.body)
          ),
          /*location*/
          node
        ),
        node
      );
    } else {
      const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
      const savedInStatementContainingYield = inStatementContainingYield;
      inGeneratorFunctionBody = false;
      inStatementContainingYield = false;
      node = visitEachChild(node, visitor, context);
      inGeneratorFunctionBody = savedInGeneratorFunctionBody;
      inStatementContainingYield = savedInStatementContainingYield;
    }
    return node;
  }
  function visitAccessorDeclaration(node) {
    const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
    const savedInStatementContainingYield = inStatementContainingYield;
    inGeneratorFunctionBody = false;
    inStatementContainingYield = false;
    node = visitEachChild(node, visitor, context);
    inGeneratorFunctionBody = savedInGeneratorFunctionBody;
    inStatementContainingYield = savedInStatementContainingYield;
    return node;
  }
  function transformGeneratorFunctionBody(body) {
    const statements2 = [];
    const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
    const savedInStatementContainingYield = inStatementContainingYield;
    const savedBlocks = blocks;
    const savedBlockOffsets = blockOffsets;
    const savedBlockActions = blockActions;
    const savedBlockStack = blockStack;
    const savedLabelOffsets = labelOffsets;
    const savedLabelExpressions = labelExpressions;
    const savedNextLabelId = nextLabelId;
    const savedOperations = operations;
    const savedOperationArguments = operationArguments;
    const savedOperationLocations = operationLocations;
    const savedState = state;
    inGeneratorFunctionBody = true;
    inStatementContainingYield = false;
    blocks = void 0;
    blockOffsets = void 0;
    blockActions = void 0;
    blockStack = void 0;
    labelOffsets = void 0;
    labelExpressions = void 0;
    nextLabelId = 1;
    operations = void 0;
    operationArguments = void 0;
    operationLocations = void 0;
    state = factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    resumeLexicalEnvironment();
    const statementOffset = factory2.copyPrologue(
      body.statements,
      statements2,
      /*ensureUseStrict*/
      false,
      visitor
    );
    transformAndEmitStatements(body.statements, statementOffset);
    const buildResult = build2();
    insertStatementsAfterStandardPrologue(statements2, endLexicalEnvironment());
    statements2.push(factory2.createReturnStatement(buildResult));
    inGeneratorFunctionBody = savedInGeneratorFunctionBody;
    inStatementContainingYield = savedInStatementContainingYield;
    blocks = savedBlocks;
    blockOffsets = savedBlockOffsets;
    blockActions = savedBlockActions;
    blockStack = savedBlockStack;
    labelOffsets = savedLabelOffsets;
    labelExpressions = savedLabelExpressions;
    nextLabelId = savedNextLabelId;
    operations = savedOperations;
    operationArguments = savedOperationArguments;
    operationLocations = savedOperationLocations;
    state = savedState;
    return setTextRange(factory2.createBlock(statements2, body.multiLine), body);
  }
  function visitVariableStatement(node) {
    if (node.transformFlags & 1048576 /* ContainsYield */) {
      transformAndEmitVariableDeclarationList(node.declarationList);
      return void 0;
    } else {
      if (getEmitFlags(node) & 2097152 /* CustomPrologue */) {
        return node;
      }
      for (const variable of node.declarationList.declarations) {
        hoistVariableDeclaration(variable.name);
      }
      const variables = getInitializedVariables(node.declarationList);
      if (variables.length === 0) {
        return void 0;
      }
      return setSourceMapRange(
        factory2.createExpressionStatement(
          factory2.inlineExpressions(
            map(variables, transformInitializedVariable)
          )
        ),
        node
      );
    }
  }
  function visitBinaryExpression(node) {
    const assoc = getExpressionAssociativity(node);
    switch (assoc) {
      case 0 /* Left */:
        return visitLeftAssociativeBinaryExpression(node);
      case 1 /* Right */:
        return visitRightAssociativeBinaryExpression(node);
      default:
        return Debug.assertNever(assoc);
    }
  }
  function visitRightAssociativeBinaryExpression(node) {
    const { left, right } = node;
    if (containsYield(right)) {
      let target;
      switch (left.kind) {
        case 211 /* PropertyAccessExpression */:
          target = factory2.updatePropertyAccessExpression(
            left,
            cacheExpression(Debug.checkDefined(visitNode(left.expression, visitor, isLeftHandSideExpression))),
            left.name
          );
          break;
        case 212 /* ElementAccessExpression */:
          target = factory2.updateElementAccessExpression(left, cacheExpression(Debug.checkDefined(visitNode(left.expression, visitor, isLeftHandSideExpression))), cacheExpression(Debug.checkDefined(visitNode(left.argumentExpression, visitor, isExpression))));
          break;
        default:
          target = Debug.checkDefined(visitNode(left, visitor, isExpression));
          break;
      }
      const operator = node.operatorToken.kind;
      if (isCompoundAssignment(operator)) {
        return setTextRange(
          factory2.createAssignment(
            target,
            setTextRange(
              factory2.createBinaryExpression(
                cacheExpression(target),
                getNonAssignmentOperatorForCompoundAssignment(operator),
                Debug.checkDefined(visitNode(right, visitor, isExpression))
              ),
              node
            )
          ),
          node
        );
      } else {
        return factory2.updateBinaryExpression(node, target, node.operatorToken, Debug.checkDefined(visitNode(right, visitor, isExpression)));
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitLeftAssociativeBinaryExpression(node) {
    if (containsYield(node.right)) {
      if (isLogicalOperator(node.operatorToken.kind)) {
        return visitLogicalBinaryExpression(node);
      } else if (node.operatorToken.kind === 28 /* CommaToken */) {
        return visitCommaExpression(node);
      }
      return factory2.updateBinaryExpression(node, cacheExpression(Debug.checkDefined(visitNode(node.left, visitor, isExpression))), node.operatorToken, Debug.checkDefined(visitNode(node.right, visitor, isExpression)));
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCommaExpression(node) {
    let pendingExpressions = [];
    visit(node.left);
    visit(node.right);
    return factory2.inlineExpressions(pendingExpressions);
    function visit(node2) {
      if (isBinaryExpression(node2) && node2.operatorToken.kind === 28 /* CommaToken */) {
        visit(node2.left);
        visit(node2.right);
      } else {
        if (containsYield(node2) && pendingExpressions.length > 0) {
          emitWorker(1 /* Statement */, [factory2.createExpressionStatement(factory2.inlineExpressions(pendingExpressions))]);
          pendingExpressions = [];
        }
        pendingExpressions.push(Debug.checkDefined(visitNode(node2, visitor, isExpression)));
      }
    }
  }
  function visitCommaListExpression(node) {
    let pendingExpressions = [];
    for (const elem of node.elements) {
      if (isBinaryExpression(elem) && elem.operatorToken.kind === 28 /* CommaToken */) {
        pendingExpressions.push(visitCommaExpression(elem));
      } else {
        if (containsYield(elem) && pendingExpressions.length > 0) {
          emitWorker(1 /* Statement */, [factory2.createExpressionStatement(factory2.inlineExpressions(pendingExpressions))]);
          pendingExpressions = [];
        }
        pendingExpressions.push(Debug.checkDefined(visitNode(elem, visitor, isExpression)));
      }
    }
    return factory2.inlineExpressions(pendingExpressions);
  }
  function visitLogicalBinaryExpression(node) {
    const resultLabel = defineLabel();
    const resultLocal = declareLocal();
    emitAssignment(
      resultLocal,
      Debug.checkDefined(visitNode(node.left, visitor, isExpression)),
      /*location*/
      node.left
    );
    if (node.operatorToken.kind === 56 /* AmpersandAmpersandToken */) {
      emitBreakWhenFalse(
        resultLabel,
        resultLocal,
        /*location*/
        node.left
      );
    } else {
      emitBreakWhenTrue(
        resultLabel,
        resultLocal,
        /*location*/
        node.left
      );
    }
    emitAssignment(
      resultLocal,
      Debug.checkDefined(visitNode(node.right, visitor, isExpression)),
      /*location*/
      node.right
    );
    markLabel(resultLabel);
    return resultLocal;
  }
  function visitConditionalExpression(node) {
    if (containsYield(node.whenTrue) || containsYield(node.whenFalse)) {
      const whenFalseLabel = defineLabel();
      const resultLabel = defineLabel();
      const resultLocal = declareLocal();
      emitBreakWhenFalse(
        whenFalseLabel,
        Debug.checkDefined(visitNode(node.condition, visitor, isExpression)),
        /*location*/
        node.condition
      );
      emitAssignment(
        resultLocal,
        Debug.checkDefined(visitNode(node.whenTrue, visitor, isExpression)),
        /*location*/
        node.whenTrue
      );
      emitBreak(resultLabel);
      markLabel(whenFalseLabel);
      emitAssignment(
        resultLocal,
        Debug.checkDefined(visitNode(node.whenFalse, visitor, isExpression)),
        /*location*/
        node.whenFalse
      );
      markLabel(resultLabel);
      return resultLocal;
    }
    return visitEachChild(node, visitor, context);
  }
  function visitYieldExpression(node) {
    const resumeLabel = defineLabel();
    const expression = visitNode(node.expression, visitor, isExpression);
    if (node.asteriskToken) {
      const iterator = (getEmitFlags(node.expression) & 8388608 /* Iterator */) === 0 ? setTextRange(emitHelpers().createValuesHelper(expression), node) : expression;
      emitYieldStar(
        iterator,
        /*location*/
        node
      );
    } else {
      emitYield(
        expression,
        /*location*/
        node
      );
    }
    markLabel(resumeLabel);
    return createGeneratorResume(
      /*location*/
      node
    );
  }
  function visitArrayLiteralExpression(node) {
    return visitElements(
      node.elements,
      /*leadingElement*/
      void 0,
      /*location*/
      void 0,
      node.multiLine
    );
  }
  function visitElements(elements, leadingElement, location, multiLine) {
    const numInitialElements = countInitialNodesWithoutYield(elements);
    let temp;
    if (numInitialElements > 0) {
      temp = declareLocal();
      const initialElements = visitNodes2(elements, visitor, isExpression, 0, numInitialElements);
      emitAssignment(
        temp,
        factory2.createArrayLiteralExpression(
          leadingElement ? [leadingElement, ...initialElements] : initialElements
        )
      );
      leadingElement = void 0;
    }
    const expressions = reduceLeft(elements, reduceElement, [], numInitialElements);
    return temp ? factory2.createArrayConcatCall(temp, [factory2.createArrayLiteralExpression(expressions, multiLine)]) : setTextRange(
      factory2.createArrayLiteralExpression(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine),
      location
    );
    function reduceElement(expressions2, element) {
      if (containsYield(element) && expressions2.length > 0) {
        const hasAssignedTemp = temp !== void 0;
        if (!temp) {
          temp = declareLocal();
        }
        emitAssignment(
          temp,
          hasAssignedTemp ? factory2.createArrayConcatCall(
            temp,
            [factory2.createArrayLiteralExpression(expressions2, multiLine)]
          ) : factory2.createArrayLiteralExpression(
            leadingElement ? [leadingElement, ...expressions2] : expressions2,
            multiLine
          )
        );
        leadingElement = void 0;
        expressions2 = [];
      }
      expressions2.push(Debug.checkDefined(visitNode(element, visitor, isExpression)));
      return expressions2;
    }
  }
  function visitObjectLiteralExpression(node) {
    const properties = node.properties;
    const multiLine = node.multiLine;
    const numInitialProperties = countInitialNodesWithoutYield(properties);
    const temp = declareLocal();
    emitAssignment(
      temp,
      factory2.createObjectLiteralExpression(
        visitNodes2(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
        multiLine
      )
    );
    const expressions = reduceLeft(properties, reduceProperty, [], numInitialProperties);
    expressions.push(multiLine ? startOnNewLine(setParent(setTextRange(factory2.cloneNode(temp), temp), temp.parent)) : temp);
    return factory2.inlineExpressions(expressions);
    function reduceProperty(expressions2, property) {
      if (containsYield(property) && expressions2.length > 0) {
        emitStatement(factory2.createExpressionStatement(factory2.inlineExpressions(expressions2)));
        expressions2 = [];
      }
      const expression = createExpressionForObjectLiteralElementLike(factory2, node, property, temp);
      const visited = visitNode(expression, visitor, isExpression);
      if (visited) {
        if (multiLine) {
          startOnNewLine(visited);
        }
        expressions2.push(visited);
      }
      return expressions2;
    }
  }
  function visitElementAccessExpression(node) {
    if (containsYield(node.argumentExpression)) {
      return factory2.updateElementAccessExpression(node, cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isLeftHandSideExpression))), Debug.checkDefined(visitNode(node.argumentExpression, visitor, isExpression)));
    }
    return visitEachChild(node, visitor, context);
  }
  function visitCallExpression(node) {
    if (!isImportCall(node) && forEach(node.arguments, containsYield)) {
      const { target, thisArg } = factory2.createCallBinding(
        node.expression,
        hoistVariableDeclaration,
        languageVersion,
        /*cacheIdentifiers*/
        true
      );
      return setOriginalNode(
        setTextRange(
          factory2.createFunctionApplyCall(
            cacheExpression(Debug.checkDefined(visitNode(target, visitor, isLeftHandSideExpression))),
            thisArg,
            visitElements(node.arguments)
          ),
          node
        ),
        node
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function visitNewExpression(node) {
    if (forEach(node.arguments, containsYield)) {
      const { target, thisArg } = factory2.createCallBinding(factory2.createPropertyAccessExpression(node.expression, "bind"), hoistVariableDeclaration);
      return setOriginalNode(
        setTextRange(
          factory2.createNewExpression(
            factory2.createFunctionApplyCall(
              cacheExpression(Debug.checkDefined(visitNode(target, visitor, isExpression))),
              thisArg,
              visitElements(
                node.arguments,
                /*leadingElement*/
                factory2.createVoidZero()
              )
            ),
            /*typeArguments*/
            void 0,
            []
          ),
          node
        ),
        node
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function transformAndEmitStatements(statements2, start = 0) {
    const numStatements = statements2.length;
    for (let i = start; i < numStatements; i++) {
      transformAndEmitStatement(statements2[i]);
    }
  }
  function transformAndEmitEmbeddedStatement(node) {
    if (isBlock(node)) {
      transformAndEmitStatements(node.statements);
    } else {
      transformAndEmitStatement(node);
    }
  }
  function transformAndEmitStatement(node) {
    const savedInStatementContainingYield = inStatementContainingYield;
    if (!inStatementContainingYield) {
      inStatementContainingYield = containsYield(node);
    }
    transformAndEmitStatementWorker(node);
    inStatementContainingYield = savedInStatementContainingYield;
  }
  function transformAndEmitStatementWorker(node) {
    switch (node.kind) {
      case 241 /* Block */:
        return transformAndEmitBlock(node);
      case 244 /* ExpressionStatement */:
        return transformAndEmitExpressionStatement(node);
      case 245 /* IfStatement */:
        return transformAndEmitIfStatement(node);
      case 246 /* DoStatement */:
        return transformAndEmitDoStatement(node);
      case 247 /* WhileStatement */:
        return transformAndEmitWhileStatement(node);
      case 248 /* ForStatement */:
        return transformAndEmitForStatement(node);
      case 249 /* ForInStatement */:
        return transformAndEmitForInStatement(node);
      case 251 /* ContinueStatement */:
        return transformAndEmitContinueStatement(node);
      case 252 /* BreakStatement */:
        return transformAndEmitBreakStatement(node);
      case 253 /* ReturnStatement */:
        return transformAndEmitReturnStatement(node);
      case 254 /* WithStatement */:
        return transformAndEmitWithStatement(node);
      case 255 /* SwitchStatement */:
        return transformAndEmitSwitchStatement(node);
      case 256 /* LabeledStatement */:
        return transformAndEmitLabeledStatement(node);
      case 257 /* ThrowStatement */:
        return transformAndEmitThrowStatement(node);
      case 258 /* TryStatement */:
        return transformAndEmitTryStatement(node);
      default:
        return emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function transformAndEmitBlock(node) {
    if (containsYield(node)) {
      transformAndEmitStatements(node.statements);
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function transformAndEmitExpressionStatement(node) {
    emitStatement(visitNode(node, visitor, isStatement));
  }
  function transformAndEmitVariableDeclarationList(node) {
    for (const variable of node.declarations) {
      const name = factory2.cloneNode(variable.name);
      setCommentRange(name, variable.name);
      hoistVariableDeclaration(name);
    }
    const variables = getInitializedVariables(node);
    const numVariables = variables.length;
    let variablesWritten = 0;
    let pendingExpressions = [];
    while (variablesWritten < numVariables) {
      for (let i = variablesWritten; i < numVariables; i++) {
        const variable = variables[i];
        if (containsYield(variable.initializer) && pendingExpressions.length > 0) {
          break;
        }
        pendingExpressions.push(transformInitializedVariable(variable));
      }
      if (pendingExpressions.length) {
        emitStatement(factory2.createExpressionStatement(factory2.inlineExpressions(pendingExpressions)));
        variablesWritten += pendingExpressions.length;
        pendingExpressions = [];
      }
    }
    return void 0;
  }
  function transformInitializedVariable(node) {
    return setSourceMapRange(
      factory2.createAssignment(
        setSourceMapRange(factory2.cloneNode(node.name), node.name),
        Debug.checkDefined(visitNode(node.initializer, visitor, isExpression))
      ),
      node
    );
  }
  function transformAndEmitIfStatement(node) {
    if (containsYield(node)) {
      if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
        const endLabel = defineLabel();
        const elseLabel = node.elseStatement ? defineLabel() : void 0;
        emitBreakWhenFalse(
          node.elseStatement ? elseLabel : endLabel,
          Debug.checkDefined(visitNode(node.expression, visitor, isExpression)),
          /*location*/
          node.expression
        );
        transformAndEmitEmbeddedStatement(node.thenStatement);
        if (node.elseStatement) {
          emitBreak(endLabel);
          markLabel(elseLabel);
          transformAndEmitEmbeddedStatement(node.elseStatement);
        }
        markLabel(endLabel);
      } else {
        emitStatement(visitNode(node, visitor, isStatement));
      }
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function transformAndEmitDoStatement(node) {
    if (containsYield(node)) {
      const conditionLabel = defineLabel();
      const loopLabel = defineLabel();
      beginLoopBlock(
        /*continueLabel*/
        conditionLabel
      );
      markLabel(loopLabel);
      transformAndEmitEmbeddedStatement(node.statement);
      markLabel(conditionLabel);
      emitBreakWhenTrue(loopLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
      endLoopBlock();
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function visitDoStatement(node) {
    if (inStatementContainingYield) {
      beginScriptLoopBlock();
      node = visitEachChild(node, visitor, context);
      endLoopBlock();
      return node;
    } else {
      return visitEachChild(node, visitor, context);
    }
  }
  function transformAndEmitWhileStatement(node) {
    if (containsYield(node)) {
      const loopLabel = defineLabel();
      const endLabel = beginLoopBlock(loopLabel);
      markLabel(loopLabel);
      emitBreakWhenFalse(endLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
      transformAndEmitEmbeddedStatement(node.statement);
      emitBreak(loopLabel);
      endLoopBlock();
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function visitWhileStatement(node) {
    if (inStatementContainingYield) {
      beginScriptLoopBlock();
      node = visitEachChild(node, visitor, context);
      endLoopBlock();
      return node;
    } else {
      return visitEachChild(node, visitor, context);
    }
  }
  function transformAndEmitForStatement(node) {
    if (containsYield(node)) {
      const conditionLabel = defineLabel();
      const incrementLabel = defineLabel();
      const endLabel = beginLoopBlock(incrementLabel);
      if (node.initializer) {
        const initializer = node.initializer;
        if (isVariableDeclarationList(initializer)) {
          transformAndEmitVariableDeclarationList(initializer);
        } else {
          emitStatement(
            setTextRange(
              factory2.createExpressionStatement(
                Debug.checkDefined(visitNode(initializer, visitor, isExpression))
              ),
              initializer
            )
          );
        }
      }
      markLabel(conditionLabel);
      if (node.condition) {
        emitBreakWhenFalse(endLabel, Debug.checkDefined(visitNode(node.condition, visitor, isExpression)));
      }
      transformAndEmitEmbeddedStatement(node.statement);
      markLabel(incrementLabel);
      if (node.incrementor) {
        emitStatement(
          setTextRange(
            factory2.createExpressionStatement(
              Debug.checkDefined(visitNode(node.incrementor, visitor, isExpression))
            ),
            node.incrementor
          )
        );
      }
      emitBreak(conditionLabel);
      endLoopBlock();
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function visitForStatement(node) {
    if (inStatementContainingYield) {
      beginScriptLoopBlock();
    }
    const initializer = node.initializer;
    if (initializer && isVariableDeclarationList(initializer)) {
      for (const variable of initializer.declarations) {
        hoistVariableDeclaration(variable.name);
      }
      const variables = getInitializedVariables(initializer);
      node = factory2.updateForStatement(
        node,
        variables.length > 0 ? factory2.inlineExpressions(map(variables, transformInitializedVariable)) : void 0,
        visitNode(node.condition, visitor, isExpression),
        visitNode(node.incrementor, visitor, isExpression),
        visitIterationBody(node.statement, visitor, context)
      );
    } else {
      node = visitEachChild(node, visitor, context);
    }
    if (inStatementContainingYield) {
      endLoopBlock();
    }
    return node;
  }
  function transformAndEmitForInStatement(node) {
    if (containsYield(node)) {
      const obj = declareLocal();
      const keysArray = declareLocal();
      const key = declareLocal();
      const keysIndex = factory2.createLoopVariable();
      const initializer = node.initializer;
      hoistVariableDeclaration(keysIndex);
      emitAssignment(obj, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
      emitAssignment(keysArray, factory2.createArrayLiteralExpression());
      emitStatement(
        factory2.createForInStatement(
          key,
          obj,
          factory2.createExpressionStatement(
            factory2.createCallExpression(
              factory2.createPropertyAccessExpression(keysArray, "push"),
              /*typeArguments*/
              void 0,
              [key]
            )
          )
        )
      );
      emitAssignment(keysIndex, factory2.createNumericLiteral(0));
      const conditionLabel = defineLabel();
      const incrementLabel = defineLabel();
      const endLoopLabel = beginLoopBlock(incrementLabel);
      markLabel(conditionLabel);
      emitBreakWhenFalse(endLoopLabel, factory2.createLessThan(keysIndex, factory2.createPropertyAccessExpression(keysArray, "length")));
      emitAssignment(key, factory2.createElementAccessExpression(keysArray, keysIndex));
      emitBreakWhenFalse(incrementLabel, factory2.createBinaryExpression(key, 103 /* InKeyword */, obj));
      let variable;
      if (isVariableDeclarationList(initializer)) {
        for (const variable2 of initializer.declarations) {
          hoistVariableDeclaration(variable2.name);
        }
        variable = factory2.cloneNode(initializer.declarations[0].name);
      } else {
        variable = Debug.checkDefined(visitNode(initializer, visitor, isExpression));
        Debug.assert(isLeftHandSideExpression(variable));
      }
      emitAssignment(variable, key);
      transformAndEmitEmbeddedStatement(node.statement);
      markLabel(incrementLabel);
      emitStatement(factory2.createExpressionStatement(factory2.createPostfixIncrement(keysIndex)));
      emitBreak(conditionLabel);
      endLoopBlock();
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function visitForInStatement(node) {
    if (inStatementContainingYield) {
      beginScriptLoopBlock();
    }
    const initializer = node.initializer;
    if (isVariableDeclarationList(initializer)) {
      for (const variable of initializer.declarations) {
        hoistVariableDeclaration(variable.name);
      }
      node = factory2.updateForInStatement(node, initializer.declarations[0].name, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory2.liftToBlock)));
    } else {
      node = visitEachChild(node, visitor, context);
    }
    if (inStatementContainingYield) {
      endLoopBlock();
    }
    return node;
  }
  function transformAndEmitContinueStatement(node) {
    const label = findContinueTarget(node.label ? idText(node.label) : void 0);
    if (label > 0) {
      emitBreak(
        label,
        /*location*/
        node
      );
    } else {
      emitStatement(node);
    }
  }
  function visitContinueStatement(node) {
    if (inStatementContainingYield) {
      const label = findContinueTarget(node.label && idText(node.label));
      if (label > 0) {
        return createInlineBreak(
          label,
          /*location*/
          node
        );
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function transformAndEmitBreakStatement(node) {
    const label = findBreakTarget(node.label ? idText(node.label) : void 0);
    if (label > 0) {
      emitBreak(
        label,
        /*location*/
        node
      );
    } else {
      emitStatement(node);
    }
  }
  function visitBreakStatement(node) {
    if (inStatementContainingYield) {
      const label = findBreakTarget(node.label && idText(node.label));
      if (label > 0) {
        return createInlineBreak(
          label,
          /*location*/
          node
        );
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function transformAndEmitReturnStatement(node) {
    emitReturn(
      visitNode(node.expression, visitor, isExpression),
      /*location*/
      node
    );
  }
  function visitReturnStatement(node) {
    return createInlineReturn(
      visitNode(node.expression, visitor, isExpression),
      /*location*/
      node
    );
  }
  function transformAndEmitWithStatement(node) {
    if (containsYield(node)) {
      beginWithBlock(cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isExpression))));
      transformAndEmitEmbeddedStatement(node.statement);
      endWithBlock();
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function transformAndEmitSwitchStatement(node) {
    if (containsYield(node.caseBlock)) {
      const caseBlock = node.caseBlock;
      const numClauses = caseBlock.clauses.length;
      const endLabel = beginSwitchBlock();
      const expression = cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isExpression)));
      const clauseLabels = [];
      let defaultClauseIndex = -1;
      for (let i = 0; i < numClauses; i++) {
        const clause = caseBlock.clauses[i];
        clauseLabels.push(defineLabel());
        if (clause.kind === 297 /* DefaultClause */ && defaultClauseIndex === -1) {
          defaultClauseIndex = i;
        }
      }
      let clausesWritten = 0;
      let pendingClauses = [];
      while (clausesWritten < numClauses) {
        let defaultClausesSkipped = 0;
        for (let i = clausesWritten; i < numClauses; i++) {
          const clause = caseBlock.clauses[i];
          if (clause.kind === 296 /* CaseClause */) {
            if (containsYield(clause.expression) && pendingClauses.length > 0) {
              break;
            }
            pendingClauses.push(
              factory2.createCaseClause(
                Debug.checkDefined(visitNode(clause.expression, visitor, isExpression)),
                [
                  createInlineBreak(
                    clauseLabels[i],
                    /*location*/
                    clause.expression
                  )
                ]
              )
            );
          } else {
            defaultClausesSkipped++;
          }
        }
        if (pendingClauses.length) {
          emitStatement(factory2.createSwitchStatement(expression, factory2.createCaseBlock(pendingClauses)));
          clausesWritten += pendingClauses.length;
          pendingClauses = [];
        }
        if (defaultClausesSkipped > 0) {
          clausesWritten += defaultClausesSkipped;
          defaultClausesSkipped = 0;
        }
      }
      if (defaultClauseIndex >= 0) {
        emitBreak(clauseLabels[defaultClauseIndex]);
      } else {
        emitBreak(endLabel);
      }
      for (let i = 0; i < numClauses; i++) {
        markLabel(clauseLabels[i]);
        transformAndEmitStatements(caseBlock.clauses[i].statements);
      }
      endSwitchBlock();
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function visitSwitchStatement(node) {
    if (inStatementContainingYield) {
      beginScriptSwitchBlock();
    }
    node = visitEachChild(node, visitor, context);
    if (inStatementContainingYield) {
      endSwitchBlock();
    }
    return node;
  }
  function transformAndEmitLabeledStatement(node) {
    if (containsYield(node)) {
      beginLabeledBlock(idText(node.label));
      transformAndEmitEmbeddedStatement(node.statement);
      endLabeledBlock();
    } else {
      emitStatement(visitNode(node, visitor, isStatement));
    }
  }
  function visitLabeledStatement(node) {
    if (inStatementContainingYield) {
      beginScriptLabeledBlock(idText(node.label));
    }
    node = visitEachChild(node, visitor, context);
    if (inStatementContainingYield) {
      endLabeledBlock();
    }
    return node;
  }
  function transformAndEmitThrowStatement(node) {
    emitThrow(
      Debug.checkDefined(visitNode(node.expression ?? factory2.createVoidZero(), visitor, isExpression)),
      /*location*/
      node
    );
  }
  function transformAndEmitTryStatement(node) {
    if (containsYield(node)) {
      beginExceptionBlock();
      transformAndEmitEmbeddedStatement(node.tryBlock);
      if (node.catchClause) {
        beginCatchBlock(node.catchClause.variableDeclaration);
        transformAndEmitEmbeddedStatement(node.catchClause.block);
      }
      if (node.finallyBlock) {
        beginFinallyBlock();
        transformAndEmitEmbeddedStatement(node.finallyBlock);
      }
      endExceptionBlock();
    } else {
      emitStatement(visitEachChild(node, visitor, context));
    }
  }
  function containsYield(node) {
    return !!node && (node.transformFlags & 1048576 /* ContainsYield */) !== 0;
  }
  function countInitialNodesWithoutYield(nodes) {
    const numNodes = nodes.length;
    for (let i = 0; i < numNodes; i++) {
      if (containsYield(nodes[i])) {
        return i;
      }
    }
    return -1;
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (hint === 1 /* Expression */) {
      return substituteExpression(node);
    }
    return node;
  }
  function substituteExpression(node) {
    if (isIdentifier(node)) {
      return substituteExpressionIdentifier(node);
    }
    return node;
  }
  function substituteExpressionIdentifier(node) {
    if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(idText(node))) {
      const original = getOriginalNode(node);
      if (isIdentifier(original) && original.parent) {
        const declaration = resolver.getReferencedValueDeclaration(original);
        if (declaration) {
          const name = renamedCatchVariableDeclarations[getOriginalNodeId(declaration)];
          if (name) {
            const clone = setParent(setTextRange(factory2.cloneNode(name), name), name.parent);
            setSourceMapRange(clone, node);
            setCommentRange(clone, node);
            return clone;
          }
        }
      }
    }
    return node;
  }
  function cacheExpression(node) {
    if (isGeneratedIdentifier(node) || getEmitFlags(node) & 8192 /* HelperName */) {
      return node;
    }
    const temp = factory2.createTempVariable(hoistVariableDeclaration);
    emitAssignment(
      temp,
      node,
      /*location*/
      node
    );
    return temp;
  }
  function declareLocal(name) {
    const temp = name ? factory2.createUniqueName(name) : factory2.createTempVariable(
      /*recordTempVariable*/
      void 0
    );
    hoistVariableDeclaration(temp);
    return temp;
  }
  function defineLabel() {
    if (!labelOffsets) {
      labelOffsets = [];
    }
    const label = nextLabelId;
    nextLabelId++;
    labelOffsets[label] = -1;
    return label;
  }
  function markLabel(label) {
    Debug.assert(labelOffsets !== void 0, "No labels were defined.");
    labelOffsets[label] = operations ? operations.length : 0;
  }
  function beginBlock(block) {
    if (!blocks) {
      blocks = [];
      blockActions = [];
      blockOffsets = [];
      blockStack = [];
    }
    const index = blockActions.length;
    blockActions[index] = 0 /* Open */;
    blockOffsets[index] = operations ? operations.length : 0;
    blocks[index] = block;
    blockStack.push(block);
    return index;
  }
  function endBlock() {
    const block = peekBlock();
    if (block === void 0) return Debug.fail("beginBlock was never called.");
    const index = blockActions.length;
    blockActions[index] = 1 /* Close */;
    blockOffsets[index] = operations ? operations.length : 0;
    blocks[index] = block;
    blockStack.pop();
    return block;
  }
  function peekBlock() {
    return lastOrUndefined(blockStack);
  }
  function peekBlockKind() {
    const block = peekBlock();
    return block && block.kind;
  }
  function beginWithBlock(expression) {
    const startLabel = defineLabel();
    const endLabel = defineLabel();
    markLabel(startLabel);
    beginBlock({
      kind: 1 /* With */,
      expression,
      startLabel,
      endLabel
    });
  }
  function endWithBlock() {
    Debug.assert(peekBlockKind() === 1 /* With */);
    const block = endBlock();
    markLabel(block.endLabel);
  }
  function beginExceptionBlock() {
    const startLabel = defineLabel();
    const endLabel = defineLabel();
    markLabel(startLabel);
    beginBlock({
      kind: 0 /* Exception */,
      state: 0 /* Try */,
      startLabel,
      endLabel
    });
    emitNop();
    return endLabel;
  }
  function beginCatchBlock(variable) {
    Debug.assert(peekBlockKind() === 0 /* Exception */);
    let name;
    if (isGeneratedIdentifier(variable.name)) {
      name = variable.name;
      hoistVariableDeclaration(variable.name);
    } else {
      const text = idText(variable.name);
      name = declareLocal(text);
      if (!renamedCatchVariables) {
        renamedCatchVariables = /* @__PURE__ */ new Map();
        renamedCatchVariableDeclarations = [];
        context.enableSubstitution(80 /* Identifier */);
      }
      renamedCatchVariables.set(text, true);
      renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name;
    }
    const exception = peekBlock();
    Debug.assert(exception.state < 1 /* Catch */);
    const endLabel = exception.endLabel;
    emitBreak(endLabel);
    const catchLabel = defineLabel();
    markLabel(catchLabel);
    exception.state = 1 /* Catch */;
    exception.catchVariable = name;
    exception.catchLabel = catchLabel;
    emitAssignment(name, factory2.createCallExpression(
      factory2.createPropertyAccessExpression(state, "sent"),
      /*typeArguments*/
      void 0,
      []
    ));
    emitNop();
  }
  function beginFinallyBlock() {
    Debug.assert(peekBlockKind() === 0 /* Exception */);
    const exception = peekBlock();
    Debug.assert(exception.state < 2 /* Finally */);
    const endLabel = exception.endLabel;
    emitBreak(endLabel);
    const finallyLabel = defineLabel();
    markLabel(finallyLabel);
    exception.state = 2 /* Finally */;
    exception.finallyLabel = finallyLabel;
  }
  function endExceptionBlock() {
    Debug.assert(peekBlockKind() === 0 /* Exception */);
    const exception = endBlock();
    const state2 = exception.state;
    if (state2 < 2 /* Finally */) {
      emitBreak(exception.endLabel);
    } else {
      emitEndfinally();
    }
    markLabel(exception.endLabel);
    emitNop();
    exception.state = 3 /* Done */;
  }
  function beginScriptLoopBlock() {
    beginBlock({
      kind: 3 /* Loop */,
      isScript: true,
      breakLabel: -1,
      continueLabel: -1
    });
  }
  function beginLoopBlock(continueLabel) {
    const breakLabel = defineLabel();
    beginBlock({
      kind: 3 /* Loop */,
      isScript: false,
      breakLabel,
      continueLabel
    });
    return breakLabel;
  }
  function endLoopBlock() {
    Debug.assert(peekBlockKind() === 3 /* Loop */);
    const block = endBlock();
    const breakLabel = block.breakLabel;
    if (!block.isScript) {
      markLabel(breakLabel);
    }
  }
  function beginScriptSwitchBlock() {
    beginBlock({
      kind: 2 /* Switch */,
      isScript: true,
      breakLabel: -1
    });
  }
  function beginSwitchBlock() {
    const breakLabel = defineLabel();
    beginBlock({
      kind: 2 /* Switch */,
      isScript: false,
      breakLabel
    });
    return breakLabel;
  }
  function endSwitchBlock() {
    Debug.assert(peekBlockKind() === 2 /* Switch */);
    const block = endBlock();
    const breakLabel = block.breakLabel;
    if (!block.isScript) {
      markLabel(breakLabel);
    }
  }
  function beginScriptLabeledBlock(labelText) {
    beginBlock({
      kind: 4 /* Labeled */,
      isScript: true,
      labelText,
      breakLabel: -1
    });
  }
  function beginLabeledBlock(labelText) {
    const breakLabel = defineLabel();
    beginBlock({
      kind: 4 /* Labeled */,
      isScript: false,
      labelText,
      breakLabel
    });
  }
  function endLabeledBlock() {
    Debug.assert(peekBlockKind() === 4 /* Labeled */);
    const block = endBlock();
    if (!block.isScript) {
      markLabel(block.breakLabel);
    }
  }
  function supportsUnlabeledBreak(block) {
    return block.kind === 2 /* Switch */ || block.kind === 3 /* Loop */;
  }
  function supportsLabeledBreakOrContinue(block) {
    return block.kind === 4 /* Labeled */;
  }
  function supportsUnlabeledContinue(block) {
    return block.kind === 3 /* Loop */;
  }
  function hasImmediateContainingLabeledBlock(labelText, start) {
    for (let j = start; j >= 0; j--) {
      const containingBlock = blockStack[j];
      if (supportsLabeledBreakOrContinue(containingBlock)) {
        if (containingBlock.labelText === labelText) {
          return true;
        }
      } else {
        break;
      }
    }
    return false;
  }
  function findBreakTarget(labelText) {
    if (blockStack) {
      if (labelText) {
        for (let i = blockStack.length - 1; i >= 0; i--) {
          const block = blockStack[i];
          if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
            return block.breakLabel;
          } else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
            return block.breakLabel;
          }
        }
      } else {
        for (let i = blockStack.length - 1; i >= 0; i--) {
          const block = blockStack[i];
          if (supportsUnlabeledBreak(block)) {
            return block.breakLabel;
          }
        }
      }
    }
    return 0;
  }
  function findContinueTarget(labelText) {
    if (blockStack) {
      if (labelText) {
        for (let i = blockStack.length - 1; i >= 0; i--) {
          const block = blockStack[i];
          if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
            return block.continueLabel;
          }
        }
      } else {
        for (let i = blockStack.length - 1; i >= 0; i--) {
          const block = blockStack[i];
          if (supportsUnlabeledContinue(block)) {
            return block.continueLabel;
          }
        }
      }
    }
    return 0;
  }
  function createLabel(label) {
    if (label !== void 0 && label > 0) {
      if (labelExpressions === void 0) {
        labelExpressions = [];
      }
      const expression = factory2.createNumericLiteral(Number.MAX_SAFE_INTEGER);
      if (labelExpressions[label] === void 0) {
        labelExpressions[label] = [expression];
      } else {
        labelExpressions[label].push(expression);
      }
      return expression;
    }
    return factory2.createOmittedExpression();
  }
  function createInstruction(instruction) {
    const literal = factory2.createNumericLiteral(instruction);
    addSyntheticTrailingComment(literal, 3 /* MultiLineCommentTrivia */, getInstructionName(instruction));
    return literal;
  }
  function createInlineBreak(label, location) {
    Debug.assertLessThan(0, label, "Invalid label");
    return setTextRange(
      factory2.createReturnStatement(
        factory2.createArrayLiteralExpression([
          createInstruction(3 /* Break */),
          createLabel(label)
        ])
      ),
      location
    );
  }
  function createInlineReturn(expression, location) {
    return setTextRange(
      factory2.createReturnStatement(
        factory2.createArrayLiteralExpression(
          expression ? [createInstruction(2 /* Return */), expression] : [createInstruction(2 /* Return */)]
        )
      ),
      location
    );
  }
  function createGeneratorResume(location) {
    return setTextRange(
      factory2.createCallExpression(
        factory2.createPropertyAccessExpression(state, "sent"),
        /*typeArguments*/
        void 0,
        []
      ),
      location
    );
  }
  function emitNop() {
    emitWorker(0 /* Nop */);
  }
  function emitStatement(node) {
    if (node) {
      emitWorker(1 /* Statement */, [node]);
    } else {
      emitNop();
    }
  }
  function emitAssignment(left, right, location) {
    emitWorker(2 /* Assign */, [left, right], location);
  }
  function emitBreak(label, location) {
    emitWorker(3 /* Break */, [label], location);
  }
  function emitBreakWhenTrue(label, condition, location) {
    emitWorker(4 /* BreakWhenTrue */, [label, condition], location);
  }
  function emitBreakWhenFalse(label, condition, location) {
    emitWorker(5 /* BreakWhenFalse */, [label, condition], location);
  }
  function emitYieldStar(expression, location) {
    emitWorker(7 /* YieldStar */, [expression], location);
  }
  function emitYield(expression, location) {
    emitWorker(6 /* Yield */, [expression], location);
  }
  function emitReturn(expression, location) {
    emitWorker(8 /* Return */, [expression], location);
  }
  function emitThrow(expression, location) {
    emitWorker(9 /* Throw */, [expression], location);
  }
  function emitEndfinally() {
    emitWorker(10 /* Endfinally */);
  }
  function emitWorker(code, args, location) {
    if (operations === void 0) {
      operations = [];
      operationArguments = [];
      operationLocations = [];
    }
    if (labelOffsets === void 0) {
      markLabel(defineLabel());
    }
    const operationIndex = operations.length;
    operations[operationIndex] = code;
    operationArguments[operationIndex] = args;
    operationLocations[operationIndex] = location;
  }
  function build2() {
    blockIndex = 0;
    labelNumber = 0;
    labelNumbers = void 0;
    lastOperationWasAbrupt = false;
    lastOperationWasCompletion = false;
    clauses = void 0;
    statements = void 0;
    exceptionBlockStack = void 0;
    currentExceptionBlock = void 0;
    withBlockStack = void 0;
    const buildResult = buildStatements();
    return emitHelpers().createGeneratorHelper(
      setEmitFlags(
        factory2.createFunctionExpression(
          /*modifiers*/
          void 0,
          /*asteriskToken*/
          void 0,
          /*name*/
          void 0,
          /*typeParameters*/
          void 0,
          [factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            /*dotDotDotToken*/
            void 0,
            state
          )],
          /*type*/
          void 0,
          factory2.createBlock(
            buildResult,
            /*multiLine*/
            buildResult.length > 0
          )
        ),
        1048576 /* ReuseTempVariableScope */
      )
    );
  }
  function buildStatements() {
    if (operations) {
      for (let operationIndex = 0; operationIndex < operations.length; operationIndex++) {
        writeOperation(operationIndex);
      }
      flushFinalLabel(operations.length);
    } else {
      flushFinalLabel(0);
    }
    if (clauses) {
      const labelExpression = factory2.createPropertyAccessExpression(state, "label");
      const switchStatement = factory2.createSwitchStatement(labelExpression, factory2.createCaseBlock(clauses));
      return [startOnNewLine(switchStatement)];
    }
    if (statements) {
      return statements;
    }
    return [];
  }
  function flushLabel() {
    if (!statements) {
      return;
    }
    appendLabel(
      /*markLabelEnd*/
      !lastOperationWasAbrupt
    );
    lastOperationWasAbrupt = false;
    lastOperationWasCompletion = false;
    labelNumber++;
  }
  function flushFinalLabel(operationIndex) {
    if (isFinalLabelReachable(operationIndex)) {
      tryEnterLabel(operationIndex);
      withBlockStack = void 0;
      writeReturn(
        /*expression*/
        void 0,
        /*operationLocation*/
        void 0
      );
    }
    if (statements && clauses) {
      appendLabel(
        /*markLabelEnd*/
        false
      );
    }
    updateLabelExpressions();
  }
  function isFinalLabelReachable(operationIndex) {
    if (!lastOperationWasCompletion) {
      return true;
    }
    if (!labelOffsets || !labelExpressions) {
      return false;
    }
    for (let label = 0; label < labelOffsets.length; label++) {
      if (labelOffsets[label] === operationIndex && labelExpressions[label]) {
        return true;
      }
    }
    return false;
  }
  function appendLabel(markLabelEnd) {
    if (!clauses) {
      clauses = [];
    }
    if (statements) {
      if (withBlockStack) {
        for (let i = withBlockStack.length - 1; i >= 0; i--) {
          const withBlock = withBlockStack[i];
          statements = [factory2.createWithStatement(withBlock.expression, factory2.createBlock(statements))];
        }
      }
      if (currentExceptionBlock) {
        const { startLabel, catchLabel, finallyLabel, endLabel } = currentExceptionBlock;
        statements.unshift(
          factory2.createExpressionStatement(
            factory2.createCallExpression(
              factory2.createPropertyAccessExpression(factory2.createPropertyAccessExpression(state, "trys"), "push"),
              /*typeArguments*/
              void 0,
              [
                factory2.createArrayLiteralExpression([
                  createLabel(startLabel),
                  createLabel(catchLabel),
                  createLabel(finallyLabel),
                  createLabel(endLabel)
                ])
              ]
            )
          )
        );
        currentExceptionBlock = void 0;
      }
      if (markLabelEnd) {
        statements.push(
          factory2.createExpressionStatement(
            factory2.createAssignment(
              factory2.createPropertyAccessExpression(state, "label"),
              factory2.createNumericLiteral(labelNumber + 1)
            )
          )
        );
      }
    }
    clauses.push(
      factory2.createCaseClause(
        factory2.createNumericLiteral(labelNumber),
        statements || []
      )
    );
    statements = void 0;
  }
  function tryEnterLabel(operationIndex) {
    if (!labelOffsets) {
      return;
    }
    for (let label = 0; label < labelOffsets.length; label++) {
      if (labelOffsets[label] === operationIndex) {
        flushLabel();
        if (labelNumbers === void 0) {
          labelNumbers = [];
        }
        if (labelNumbers[labelNumber] === void 0) {
          labelNumbers[labelNumber] = [label];
        } else {
          labelNumbers[labelNumber].push(label);
        }
      }
    }
  }
  function updateLabelExpressions() {
    if (labelExpressions !== void 0 && labelNumbers !== void 0) {
      for (let labelNumber2 = 0; labelNumber2 < labelNumbers.length; labelNumber2++) {
        const labels = labelNumbers[labelNumber2];
        if (labels !== void 0) {
          for (const label of labels) {
            const expressions = labelExpressions[label];
            if (expressions !== void 0) {
              for (const expression of expressions) {
                expression.text = String(labelNumber2);
              }
            }
          }
        }
      }
    }
  }
  function tryEnterOrLeaveBlock(operationIndex) {
    if (blocks) {
      for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) {
        const block = blocks[blockIndex];
        const blockAction = blockActions[blockIndex];
        switch (block.kind) {
          case 0 /* Exception */:
            if (blockAction === 0 /* Open */) {
              if (!exceptionBlockStack) {
                exceptionBlockStack = [];
              }
              if (!statements) {
                statements = [];
              }
              exceptionBlockStack.push(currentExceptionBlock);
              currentExceptionBlock = block;
            } else if (blockAction === 1 /* Close */) {
              currentExceptionBlock = exceptionBlockStack.pop();
            }
            break;
          case 1 /* With */:
            if (blockAction === 0 /* Open */) {
              if (!withBlockStack) {
                withBlockStack = [];
              }
              withBlockStack.push(block);
            } else if (blockAction === 1 /* Close */) {
              withBlockStack.pop();
            }
            break;
        }
      }
    }
  }
  function writeOperation(operationIndex) {
    tryEnterLabel(operationIndex);
    tryEnterOrLeaveBlock(operationIndex);
    if (lastOperationWasAbrupt) {
      return;
    }
    lastOperationWasAbrupt = false;
    lastOperationWasCompletion = false;
    const opcode = operations[operationIndex];
    if (opcode === 0 /* Nop */) {
      return;
    } else if (opcode === 10 /* Endfinally */) {
      return writeEndfinally();
    }
    const args = operationArguments[operationIndex];
    if (opcode === 1 /* Statement */) {
      return writeStatement(args[0]);
    }
    const location = operationLocations[operationIndex];
    switch (opcode) {
      case 2 /* Assign */:
        return writeAssign(args[0], args[1], location);
      case 3 /* Break */:
        return writeBreak(args[0], location);
      case 4 /* BreakWhenTrue */:
        return writeBreakWhenTrue(args[0], args[1], location);
      case 5 /* BreakWhenFalse */:
        return writeBreakWhenFalse(args[0], args[1], location);
      case 6 /* Yield */:
        return writeYield(args[0], location);
      case 7 /* YieldStar */:
        return writeYieldStar(args[0], location);
      case 8 /* Return */:
        return writeReturn(args[0], location);
      case 9 /* Throw */:
        return writeThrow(args[0], location);
    }
  }
  function writeStatement(statement) {
    if (statement) {
      if (!statements) {
        statements = [statement];
      } else {
        statements.push(statement);
      }
    }
  }
  function writeAssign(left, right, operationLocation) {
    writeStatement(setTextRange(factory2.createExpressionStatement(factory2.createAssignment(left, right)), operationLocation));
  }
  function writeThrow(expression, operationLocation) {
    lastOperationWasAbrupt = true;
    lastOperationWasCompletion = true;
    writeStatement(setTextRange(factory2.createThrowStatement(expression), operationLocation));
  }
  function writeReturn(expression, operationLocation) {
    lastOperationWasAbrupt = true;
    lastOperationWasCompletion = true;
    writeStatement(
      setEmitFlags(
        setTextRange(
          factory2.createReturnStatement(
            factory2.createArrayLiteralExpression(
              expression ? [createInstruction(2 /* Return */), expression] : [createInstruction(2 /* Return */)]
            )
          ),
          operationLocation
        ),
        768 /* NoTokenSourceMaps */
      )
    );
  }
  function writeBreak(label, operationLocation) {
    lastOperationWasAbrupt = true;
    writeStatement(
      setEmitFlags(
        setTextRange(
          factory2.createReturnStatement(
            factory2.createArrayLiteralExpression([
              createInstruction(3 /* Break */),
              createLabel(label)
            ])
          ),
          operationLocation
        ),
        768 /* NoTokenSourceMaps */
      )
    );
  }
  function writeBreakWhenTrue(label, condition, operationLocation) {
    writeStatement(
      setEmitFlags(
        factory2.createIfStatement(
          condition,
          setEmitFlags(
            setTextRange(
              factory2.createReturnStatement(
                factory2.createArrayLiteralExpression([
                  createInstruction(3 /* Break */),
                  createLabel(label)
                ])
              ),
              operationLocation
            ),
            768 /* NoTokenSourceMaps */
          )
        ),
        1 /* SingleLine */
      )
    );
  }
  function writeBreakWhenFalse(label, condition, operationLocation) {
    writeStatement(
      setEmitFlags(
        factory2.createIfStatement(
          factory2.createLogicalNot(condition),
          setEmitFlags(
            setTextRange(
              factory2.createReturnStatement(
                factory2.createArrayLiteralExpression([
                  createInstruction(3 /* Break */),
                  createLabel(label)
                ])
              ),
              operationLocation
            ),
            768 /* NoTokenSourceMaps */
          )
        ),
        1 /* SingleLine */
      )
    );
  }
  function writeYield(expression, operationLocation) {
    lastOperationWasAbrupt = true;
    writeStatement(
      setEmitFlags(
        setTextRange(
          factory2.createReturnStatement(
            factory2.createArrayLiteralExpression(
              expression ? [createInstruction(4 /* Yield */), expression] : [createInstruction(4 /* Yield */)]
            )
          ),
          operationLocation
        ),
        768 /* NoTokenSourceMaps */
      )
    );
  }
  function writeYieldStar(expression, operationLocation) {
    lastOperationWasAbrupt = true;
    writeStatement(
      setEmitFlags(
        setTextRange(
          factory2.createReturnStatement(
            factory2.createArrayLiteralExpression([
              createInstruction(5 /* YieldStar */),
              expression
            ])
          ),
          operationLocation
        ),
        768 /* NoTokenSourceMaps */
      )
    );
  }
  function writeEndfinally() {
    lastOperationWasAbrupt = true;
    writeStatement(
      factory2.createReturnStatement(
        factory2.createArrayLiteralExpression([
          createInstruction(7 /* Endfinally */)
        ])
      )
    );
  }
}

// src/compiler/transformers/module/module.ts
function transformModule(context) {
  function getTransformModuleDelegate(moduleKind2) {
    switch (moduleKind2) {
      case 2 /* AMD */:
        return transformAMDModule;
      case 3 /* UMD */:
        return transformUMDModule;
      default:
        return transformCommonJSModule;
    }
  }
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers,
    startLexicalEnvironment,
    endLexicalEnvironment,
    hoistVariableDeclaration
  } = context;
  const compilerOptions = context.getCompilerOptions();
  const resolver = context.getEmitResolver();
  const host = context.getEmitHost();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const moduleKind = getEmitModuleKind(compilerOptions);
  const previousOnSubstituteNode = context.onSubstituteNode;
  const previousOnEmitNode = context.onEmitNode;
  context.onSubstituteNode = onSubstituteNode;
  context.onEmitNode = onEmitNode;
  context.enableSubstitution(213 /* CallExpression */);
  context.enableSubstitution(215 /* TaggedTemplateExpression */);
  context.enableSubstitution(80 /* Identifier */);
  context.enableSubstitution(226 /* BinaryExpression */);
  context.enableSubstitution(304 /* ShorthandPropertyAssignment */);
  context.enableEmitNotification(307 /* SourceFile */);
  const moduleInfoMap = [];
  let currentSourceFile;
  let currentModuleInfo;
  const noSubstitution = [];
  let needUMDDynamicImportHelper;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 8388608 /* ContainsDynamicImport */ || isJsonSourceFile(node) && hasJsonModuleEmitEnabled(compilerOptions) && compilerOptions.outFile)) {
      return node;
    }
    currentSourceFile = node;
    currentModuleInfo = collectExternalModuleInfo(context, node);
    moduleInfoMap[getOriginalNodeId(node)] = currentModuleInfo;
    const transformModule2 = getTransformModuleDelegate(moduleKind);
    const updated = transformModule2(node);
    currentSourceFile = void 0;
    currentModuleInfo = void 0;
    needUMDDynamicImportHelper = false;
    return updated;
  }
  function shouldEmitUnderscoreUnderscoreESModule() {
    if (hasJSFileExtension(currentSourceFile.fileName) && currentSourceFile.commonJsModuleIndicator && (!currentSourceFile.externalModuleIndicator || currentSourceFile.externalModuleIndicator === true)) {
      return false;
    }
    if (!currentModuleInfo.exportEquals && isExternalModule(currentSourceFile)) {
      return true;
    }
    return false;
  }
  function transformCommonJSModule(node) {
    startLexicalEnvironment();
    const statements = [];
    const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || isExternalModule(currentSourceFile);
    const statementOffset = factory2.copyPrologue(node.statements, statements, ensureUseStrict && !isJsonSourceFile(node), topLevelVisitor);
    if (shouldEmitUnderscoreUnderscoreESModule()) {
      append(statements, createUnderscoreUnderscoreESModule());
    }
    if (some(currentModuleInfo.exportedNames)) {
      const chunkSize = 50;
      for (let i = 0; i < currentModuleInfo.exportedNames.length; i += chunkSize) {
        append(
          statements,
          factory2.createExpressionStatement(
            reduceLeft(
              currentModuleInfo.exportedNames.slice(i, i + chunkSize),
              (prev, nextId) => factory2.createAssignment(factory2.createPropertyAccessExpression(factory2.createIdentifier("exports"), factory2.createIdentifier(idText(nextId))), prev),
              factory2.createVoidZero()
            )
          )
        );
      }
    }
    for (const f of currentModuleInfo.exportedFunctions) {
      appendExportsOfHoistedDeclaration(statements, f);
    }
    append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, topLevelVisitor, isStatement));
    addRange(statements, visitNodes2(node.statements, topLevelVisitor, isStatement, statementOffset));
    addExportEqualsIfNeeded(
      statements,
      /*emitAsReturn*/
      false
    );
    insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
    const updated = factory2.updateSourceFile(node, setTextRange(factory2.createNodeArray(statements), node.statements));
    addEmitHelpers(updated, context.readEmitHelpers());
    return updated;
  }
  function transformAMDModule(node) {
    const define = factory2.createIdentifier("define");
    const moduleName = tryGetModuleNameFromFile(factory2, node, host, compilerOptions);
    const jsonSourceFile = isJsonSourceFile(node) && node;
    const { aliasedModuleNames, unaliasedModuleNames, importAliasNames } = collectAsynchronousDependencies(
      node,
      /*includeNonAmdDependencies*/
      true
    );
    const updated = factory2.updateSourceFile(
      node,
      setTextRange(
        factory2.createNodeArray([
          factory2.createExpressionStatement(
            factory2.createCallExpression(
              define,
              /*typeArguments*/
              void 0,
              [
                // Add the module name (if provided).
                ...moduleName ? [moduleName] : [],
                // Add the dependency array argument:
                //
                //     ["require", "exports", module1", "module2", ...]
                factory2.createArrayLiteralExpression(
                  jsonSourceFile ? emptyArray : [
                    factory2.createStringLiteral("require"),
                    factory2.createStringLiteral("exports"),
                    ...aliasedModuleNames,
                    ...unaliasedModuleNames
                  ]
                ),
                // Add the module body function argument:
                //
                //     function (require, exports, module1, module2) ...
                jsonSourceFile ? jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : factory2.createObjectLiteralExpression() : factory2.createFunctionExpression(
                  /*modifiers*/
                  void 0,
                  /*asteriskToken*/
                  void 0,
                  /*name*/
                  void 0,
                  /*typeParameters*/
                  void 0,
                  [
                    factory2.createParameterDeclaration(
                      /*modifiers*/
                      void 0,
                      /*dotDotDotToken*/
                      void 0,
                      "require"
                    ),
                    factory2.createParameterDeclaration(
                      /*modifiers*/
                      void 0,
                      /*dotDotDotToken*/
                      void 0,
                      "exports"
                    ),
                    ...importAliasNames
                  ],
                  /*type*/
                  void 0,
                  transformAsynchronousModuleBody(node)
                )
              ]
            )
          )
        ]),
        /*location*/
        node.statements
      )
    );
    addEmitHelpers(updated, context.readEmitHelpers());
    return updated;
  }
  function transformUMDModule(node) {
    const { aliasedModuleNames, unaliasedModuleNames, importAliasNames } = collectAsynchronousDependencies(
      node,
      /*includeNonAmdDependencies*/
      false
    );
    const moduleName = tryGetModuleNameFromFile(factory2, node, host, compilerOptions);
    const umdHeader = factory2.createFunctionExpression(
      /*modifiers*/
      void 0,
      /*asteriskToken*/
      void 0,
      /*name*/
      void 0,
      /*typeParameters*/
      void 0,
      [factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        "factory"
      )],
      /*type*/
      void 0,
      setTextRange(
        factory2.createBlock(
          [
            factory2.createIfStatement(
              factory2.createLogicalAnd(
                factory2.createTypeCheck(factory2.createIdentifier("module"), "object"),
                factory2.createTypeCheck(factory2.createPropertyAccessExpression(factory2.createIdentifier("module"), "exports"), "object")
              ),
              factory2.createBlock([
                factory2.createVariableStatement(
                  /*modifiers*/
                  void 0,
                  [
                    factory2.createVariableDeclaration(
                      "v",
                      /*exclamationToken*/
                      void 0,
                      /*type*/
                      void 0,
                      factory2.createCallExpression(
                        factory2.createIdentifier("factory"),
                        /*typeArguments*/
                        void 0,
                        [
                          factory2.createIdentifier("require"),
                          factory2.createIdentifier("exports")
                        ]
                      )
                    )
                  ]
                ),
                setEmitFlags(
                  factory2.createIfStatement(
                    factory2.createStrictInequality(
                      factory2.createIdentifier("v"),
                      factory2.createIdentifier("undefined")
                    ),
                    factory2.createExpressionStatement(
                      factory2.createAssignment(
                        factory2.createPropertyAccessExpression(factory2.createIdentifier("module"), "exports"),
                        factory2.createIdentifier("v")
                      )
                    )
                  ),
                  1 /* SingleLine */
                )
              ]),
              factory2.createIfStatement(
                factory2.createLogicalAnd(
                  factory2.createTypeCheck(factory2.createIdentifier("define"), "function"),
                  factory2.createPropertyAccessExpression(factory2.createIdentifier("define"), "amd")
                ),
                factory2.createBlock([
                  factory2.createExpressionStatement(
                    factory2.createCallExpression(
                      factory2.createIdentifier("define"),
                      /*typeArguments*/
                      void 0,
                      [
                        // Add the module name (if provided).
                        ...moduleName ? [moduleName] : [],
                        factory2.createArrayLiteralExpression([
                          factory2.createStringLiteral("require"),
                          factory2.createStringLiteral("exports"),
                          ...aliasedModuleNames,
                          ...unaliasedModuleNames
                        ]),
                        factory2.createIdentifier("factory")
                      ]
                    )
                  )
                ])
              )
            )
          ],
          /*multiLine*/
          true
        ),
        /*location*/
        void 0
      )
    );
    const updated = factory2.updateSourceFile(
      node,
      setTextRange(
        factory2.createNodeArray([
          factory2.createExpressionStatement(
            factory2.createCallExpression(
              umdHeader,
              /*typeArguments*/
              void 0,
              [
                // Add the module body function argument:
                //
                //     function (require, exports) ...
                factory2.createFunctionExpression(
                  /*modifiers*/
                  void 0,
                  /*asteriskToken*/
                  void 0,
                  /*name*/
                  void 0,
                  /*typeParameters*/
                  void 0,
                  [
                    factory2.createParameterDeclaration(
                      /*modifiers*/
                      void 0,
                      /*dotDotDotToken*/
                      void 0,
                      "require"
                    ),
                    factory2.createParameterDeclaration(
                      /*modifiers*/
                      void 0,
                      /*dotDotDotToken*/
                      void 0,
                      "exports"
                    ),
                    ...importAliasNames
                  ],
                  /*type*/
                  void 0,
                  transformAsynchronousModuleBody(node)
                )
              ]
            )
          )
        ]),
        /*location*/
        node.statements
      )
    );
    addEmitHelpers(updated, context.readEmitHelpers());
    return updated;
  }
  function collectAsynchronousDependencies(node, includeNonAmdDependencies) {
    const aliasedModuleNames = [];
    const unaliasedModuleNames = [];
    const importAliasNames = [];
    for (const amdDependency of node.amdDependencies) {
      if (amdDependency.name) {
        aliasedModuleNames.push(factory2.createStringLiteral(amdDependency.path));
        importAliasNames.push(factory2.createParameterDeclaration(
          /*modifiers*/
          void 0,
          /*dotDotDotToken*/
          void 0,
          amdDependency.name
        ));
      } else {
        unaliasedModuleNames.push(factory2.createStringLiteral(amdDependency.path));
      }
    }
    for (const importNode of currentModuleInfo.externalImports) {
      const externalModuleName = getExternalModuleNameLiteral(factory2, importNode, currentSourceFile, host, resolver, compilerOptions);
      const importAliasName = getLocalNameForExternalImport(factory2, importNode, currentSourceFile);
      if (externalModuleName) {
        if (includeNonAmdDependencies && importAliasName) {
          setEmitFlags(importAliasName, 8 /* NoSubstitution */);
          aliasedModuleNames.push(externalModuleName);
          importAliasNames.push(factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            /*dotDotDotToken*/
            void 0,
            importAliasName
          ));
        } else {
          unaliasedModuleNames.push(externalModuleName);
        }
      }
    }
    return { aliasedModuleNames, unaliasedModuleNames, importAliasNames };
  }
  function getAMDImportExpressionForImport(node) {
    if (isImportEqualsDeclaration(node) || isExportDeclaration(node) || !getExternalModuleNameLiteral(factory2, node, currentSourceFile, host, resolver, compilerOptions)) {
      return void 0;
    }
    const name = getLocalNameForExternalImport(factory2, node, currentSourceFile);
    const expr = getHelperExpressionForImport(node, name);
    if (expr === name) {
      return void 0;
    }
    return factory2.createExpressionStatement(factory2.createAssignment(name, expr));
  }
  function transformAsynchronousModuleBody(node) {
    startLexicalEnvironment();
    const statements = [];
    const statementOffset = factory2.copyPrologue(
      node.statements,
      statements,
      /*ensureUseStrict*/
      true,
      topLevelVisitor
    );
    if (shouldEmitUnderscoreUnderscoreESModule()) {
      append(statements, createUnderscoreUnderscoreESModule());
    }
    if (some(currentModuleInfo.exportedNames)) {
      append(statements, factory2.createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => factory2.createAssignment(factory2.createPropertyAccessExpression(factory2.createIdentifier("exports"), factory2.createIdentifier(idText(nextId))), prev), factory2.createVoidZero())));
    }
    for (const f of currentModuleInfo.exportedFunctions) {
      appendExportsOfHoistedDeclaration(statements, f);
    }
    append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, topLevelVisitor, isStatement));
    if (moduleKind === 2 /* AMD */) {
      addRange(statements, mapDefined(currentModuleInfo.externalImports, getAMDImportExpressionForImport));
    }
    addRange(statements, visitNodes2(node.statements, topLevelVisitor, isStatement, statementOffset));
    addExportEqualsIfNeeded(
      statements,
      /*emitAsReturn*/
      true
    );
    insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
    const body = factory2.createBlock(
      statements,
      /*multiLine*/
      true
    );
    if (needUMDDynamicImportHelper) {
      addEmitHelper(body, dynamicImportUMDHelper);
    }
    return body;
  }
  function addExportEqualsIfNeeded(statements, emitAsReturn) {
    if (currentModuleInfo.exportEquals) {
      const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, visitor, isExpression);
      if (expressionResult) {
        if (emitAsReturn) {
          const statement = factory2.createReturnStatement(expressionResult);
          setTextRange(statement, currentModuleInfo.exportEquals);
          setEmitFlags(statement, 768 /* NoTokenSourceMaps */ | 3072 /* NoComments */);
          statements.push(statement);
        } else {
          const statement = factory2.createExpressionStatement(
            factory2.createAssignment(
              factory2.createPropertyAccessExpression(
                factory2.createIdentifier("module"),
                "exports"
              ),
              expressionResult
            )
          );
          setTextRange(statement, currentModuleInfo.exportEquals);
          setEmitFlags(statement, 3072 /* NoComments */);
          statements.push(statement);
        }
      }
    }
  }
  function topLevelVisitor(node) {
    switch (node.kind) {
      case 272 /* ImportDeclaration */:
        return visitTopLevelImportDeclaration(node);
      case 271 /* ImportEqualsDeclaration */:
        return visitTopLevelImportEqualsDeclaration(node);
      case 278 /* ExportDeclaration */:
        return visitTopLevelExportDeclaration(node);
      case 277 /* ExportAssignment */:
        return visitTopLevelExportAssignment(node);
      default:
        return topLevelNestedVisitor(node);
    }
  }
  function topLevelNestedVisitor(node) {
    switch (node.kind) {
      case 243 /* VariableStatement */:
        return visitVariableStatement(node);
      case 262 /* FunctionDeclaration */:
        return visitFunctionDeclaration(node);
      case 263 /* ClassDeclaration */:
        return visitClassDeclaration(node);
      case 248 /* ForStatement */:
        return visitForStatement(
          node,
          /*isTopLevel*/
          true
        );
      case 249 /* ForInStatement */:
        return visitForInStatement(node);
      case 250 /* ForOfStatement */:
        return visitForOfStatement(node);
      case 246 /* DoStatement */:
        return visitDoStatement(node);
      case 247 /* WhileStatement */:
        return visitWhileStatement(node);
      case 256 /* LabeledStatement */:
        return visitLabeledStatement(node);
      case 254 /* WithStatement */:
        return visitWithStatement(node);
      case 245 /* IfStatement */:
        return visitIfStatement(node);
      case 255 /* SwitchStatement */:
        return visitSwitchStatement(node);
      case 269 /* CaseBlock */:
        return visitCaseBlock(node);
      case 296 /* CaseClause */:
        return visitCaseClause(node);
      case 297 /* DefaultClause */:
        return visitDefaultClause(node);
      case 258 /* TryStatement */:
        return visitTryStatement(node);
      case 299 /* CatchClause */:
        return visitCatchClause(node);
      case 241 /* Block */:
        return visitBlock(node);
      default:
        return visitor(node);
    }
  }
  function visitorWorker(node, valueIsDiscarded) {
    if (!(node.transformFlags & (8388608 /* ContainsDynamicImport */ | 4096 /* ContainsDestructuringAssignment */ | 268435456 /* ContainsUpdateExpressionForIdentifier */))) {
      return node;
    }
    switch (node.kind) {
      case 248 /* ForStatement */:
        return visitForStatement(
          node,
          /*isTopLevel*/
          false
        );
      case 244 /* ExpressionStatement */:
        return visitExpressionStatement(node);
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(node, valueIsDiscarded);
      case 354 /* PartiallyEmittedExpression */:
        return visitPartiallyEmittedExpression(node, valueIsDiscarded);
      case 213 /* CallExpression */:
        if (isImportCall(node) && currentSourceFile.impliedNodeFormat === void 0) {
          return visitImportCallExpression(node);
        }
        break;
      case 226 /* BinaryExpression */:
        if (isDestructuringAssignment(node)) {
          return visitDestructuringAssignment(node, valueIsDiscarded);
        }
        break;
      case 224 /* PrefixUnaryExpression */:
      case 225 /* PostfixUnaryExpression */:
        return visitPreOrPostfixUnaryExpression(node, valueIsDiscarded);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitor(node) {
    return visitorWorker(
      node,
      /*valueIsDiscarded*/
      false
    );
  }
  function discardedValueVisitor(node) {
    return visitorWorker(
      node,
      /*valueIsDiscarded*/
      true
    );
  }
  function destructuringNeedsFlattening(node) {
    if (isObjectLiteralExpression(node)) {
      for (const elem of node.properties) {
        switch (elem.kind) {
          case 303 /* PropertyAssignment */:
            if (destructuringNeedsFlattening(elem.initializer)) {
              return true;
            }
            break;
          case 304 /* ShorthandPropertyAssignment */:
            if (destructuringNeedsFlattening(elem.name)) {
              return true;
            }
            break;
          case 305 /* SpreadAssignment */:
            if (destructuringNeedsFlattening(elem.expression)) {
              return true;
            }
            break;
          case 174 /* MethodDeclaration */:
          case 177 /* GetAccessor */:
          case 178 /* SetAccessor */:
            return false;
          default:
            Debug.assertNever(elem, "Unhandled object member kind");
        }
      }
    } else if (isArrayLiteralExpression(node)) {
      for (const elem of node.elements) {
        if (isSpreadElement(elem)) {
          if (destructuringNeedsFlattening(elem.expression)) {
            return true;
          }
        } else if (destructuringNeedsFlattening(elem)) {
          return true;
        }
      }
    } else if (isIdentifier(node)) {
      return length(getExports(node)) > (isExportName(node) ? 1 : 0);
    }
    return false;
  }
  function visitDestructuringAssignment(node, valueIsDiscarded) {
    if (destructuringNeedsFlattening(node.left)) {
      return flattenDestructuringAssignment(node, visitor, context, 0 /* All */, !valueIsDiscarded, createAllExportExpressions);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitForStatement(node, isTopLevel) {
    if (isTopLevel && node.initializer && isVariableDeclarationList(node.initializer) && !(node.initializer.flags & 7 /* BlockScoped */)) {
      const exportStatements = appendExportsOfVariableDeclarationList(
        /*statements*/
        void 0,
        node.initializer,
        /*isForInOrOfInitializer*/
        false
      );
      if (exportStatements) {
        const statements = [];
        const varDeclList = visitNode(node.initializer, discardedValueVisitor, isVariableDeclarationList);
        const varStatement = factory2.createVariableStatement(
          /*modifiers*/
          void 0,
          varDeclList
        );
        statements.push(varStatement);
        addRange(statements, exportStatements);
        const condition = visitNode(node.condition, visitor, isExpression);
        const incrementor = visitNode(node.incrementor, discardedValueVisitor, isExpression);
        const body = visitIterationBody(node.statement, isTopLevel ? topLevelNestedVisitor : visitor, context);
        statements.push(factory2.updateForStatement(
          node,
          /*initializer*/
          void 0,
          condition,
          incrementor,
          body
        ));
        return statements;
      }
    }
    return factory2.updateForStatement(
      node,
      visitNode(node.initializer, discardedValueVisitor, isForInitializer),
      visitNode(node.condition, visitor, isExpression),
      visitNode(node.incrementor, discardedValueVisitor, isExpression),
      visitIterationBody(node.statement, isTopLevel ? topLevelNestedVisitor : visitor, context)
    );
  }
  function visitForInStatement(node) {
    if (isVariableDeclarationList(node.initializer) && !(node.initializer.flags & 7 /* BlockScoped */)) {
      const exportStatements = appendExportsOfVariableDeclarationList(
        /*statements*/
        void 0,
        node.initializer,
        /*isForInOrOfInitializer*/
        true
      );
      if (some(exportStatements)) {
        const initializer = visitNode(node.initializer, discardedValueVisitor, isForInitializer);
        const expression = visitNode(node.expression, visitor, isExpression);
        const body = visitIterationBody(node.statement, topLevelNestedVisitor, context);
        const mergedBody = isBlock(body) ? factory2.updateBlock(body, [...exportStatements, ...body.statements]) : factory2.createBlock(
          [...exportStatements, body],
          /*multiLine*/
          true
        );
        return factory2.updateForInStatement(node, initializer, expression, mergedBody);
      }
    }
    return factory2.updateForInStatement(
      node,
      visitNode(node.initializer, discardedValueVisitor, isForInitializer),
      visitNode(node.expression, visitor, isExpression),
      visitIterationBody(node.statement, topLevelNestedVisitor, context)
    );
  }
  function visitForOfStatement(node) {
    if (isVariableDeclarationList(node.initializer) && !(node.initializer.flags & 7 /* BlockScoped */)) {
      const exportStatements = appendExportsOfVariableDeclarationList(
        /*statements*/
        void 0,
        node.initializer,
        /*isForInOrOfInitializer*/
        true
      );
      const initializer = visitNode(node.initializer, discardedValueVisitor, isForInitializer);
      const expression = visitNode(node.expression, visitor, isExpression);
      let body = visitIterationBody(node.statement, topLevelNestedVisitor, context);
      if (some(exportStatements)) {
        body = isBlock(body) ? factory2.updateBlock(body, [...exportStatements, ...body.statements]) : factory2.createBlock(
          [...exportStatements, body],
          /*multiLine*/
          true
        );
      }
      return factory2.updateForOfStatement(node, node.awaitModifier, initializer, expression, body);
    }
    return factory2.updateForOfStatement(
      node,
      node.awaitModifier,
      visitNode(node.initializer, discardedValueVisitor, isForInitializer),
      visitNode(node.expression, visitor, isExpression),
      visitIterationBody(node.statement, topLevelNestedVisitor, context)
    );
  }
  function visitDoStatement(node) {
    return factory2.updateDoStatement(
      node,
      visitIterationBody(node.statement, topLevelNestedVisitor, context),
      visitNode(node.expression, visitor, isExpression)
    );
  }
  function visitWhileStatement(node) {
    return factory2.updateWhileStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      visitIterationBody(node.statement, topLevelNestedVisitor, context)
    );
  }
  function visitLabeledStatement(node) {
    return factory2.updateLabeledStatement(
      node,
      node.label,
      Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory2.liftToBlock))
    );
  }
  function visitWithStatement(node) {
    return factory2.updateWithStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory2.liftToBlock))
    );
  }
  function visitIfStatement(node) {
    return factory2.updateIfStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      Debug.checkDefined(visitNode(node.thenStatement, topLevelNestedVisitor, isStatement, factory2.liftToBlock)),
      visitNode(node.elseStatement, topLevelNestedVisitor, isStatement, factory2.liftToBlock)
    );
  }
  function visitSwitchStatement(node) {
    return factory2.updateSwitchStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      Debug.checkDefined(visitNode(node.caseBlock, topLevelNestedVisitor, isCaseBlock))
    );
  }
  function visitCaseBlock(node) {
    return factory2.updateCaseBlock(
      node,
      visitNodes2(node.clauses, topLevelNestedVisitor, isCaseOrDefaultClause)
    );
  }
  function visitCaseClause(node) {
    return factory2.updateCaseClause(
      node,
      visitNode(node.expression, visitor, isExpression),
      visitNodes2(node.statements, topLevelNestedVisitor, isStatement)
    );
  }
  function visitDefaultClause(node) {
    return visitEachChild(node, topLevelNestedVisitor, context);
  }
  function visitTryStatement(node) {
    return visitEachChild(node, topLevelNestedVisitor, context);
  }
  function visitCatchClause(node) {
    return factory2.updateCatchClause(
      node,
      node.variableDeclaration,
      Debug.checkDefined(visitNode(node.block, topLevelNestedVisitor, isBlock))
    );
  }
  function visitBlock(node) {
    node = visitEachChild(node, topLevelNestedVisitor, context);
    return node;
  }
  function visitExpressionStatement(node) {
    return factory2.updateExpressionStatement(
      node,
      visitNode(node.expression, discardedValueVisitor, isExpression)
    );
  }
  function visitParenthesizedExpression(node, valueIsDiscarded) {
    return factory2.updateParenthesizedExpression(node, visitNode(node.expression, valueIsDiscarded ? discardedValueVisitor : visitor, isExpression));
  }
  function visitPartiallyEmittedExpression(node, valueIsDiscarded) {
    return factory2.updatePartiallyEmittedExpression(node, visitNode(node.expression, valueIsDiscarded ? discardedValueVisitor : visitor, isExpression));
  }
  function visitPreOrPostfixUnaryExpression(node, valueIsDiscarded) {
    if ((node.operator === 46 /* PlusPlusToken */ || node.operator === 47 /* MinusMinusToken */) && isIdentifier(node.operand) && !isGeneratedIdentifier(node.operand) && !isLocalName(node.operand) && !isDeclarationNameOfEnumOrNamespace(node.operand)) {
      const exportedNames = getExports(node.operand);
      if (exportedNames) {
        let temp;
        let expression = visitNode(node.operand, visitor, isExpression);
        if (isPrefixUnaryExpression(node)) {
          expression = factory2.updatePrefixUnaryExpression(node, expression);
        } else {
          expression = factory2.updatePostfixUnaryExpression(node, expression);
          if (!valueIsDiscarded) {
            temp = factory2.createTempVariable(hoistVariableDeclaration);
            expression = factory2.createAssignment(temp, expression);
            setTextRange(expression, node);
          }
          expression = factory2.createComma(expression, factory2.cloneNode(node.operand));
          setTextRange(expression, node);
        }
        for (const exportName of exportedNames) {
          noSubstitution[getNodeId(expression)] = true;
          expression = createExportExpression(exportName, expression);
          setTextRange(expression, node);
        }
        if (temp) {
          noSubstitution[getNodeId(expression)] = true;
          expression = factory2.createComma(expression, temp);
          setTextRange(expression, node);
        }
        return expression;
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function visitImportCallExpression(node) {
    if (moduleKind === 0 /* None */ && languageVersion >= 7 /* ES2020 */) {
      return visitEachChild(node, visitor, context);
    }
    const externalModuleName = getExternalModuleNameLiteral(factory2, node, currentSourceFile, host, resolver, compilerOptions);
    const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor, isExpression);
    const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName : firstArgument;
    const containsLexicalThis = !!(node.transformFlags & 16384 /* ContainsLexicalThis */);
    switch (compilerOptions.module) {
      case 2 /* AMD */:
        return createImportCallExpressionAMD(argument, containsLexicalThis);
      case 3 /* UMD */:
        return createImportCallExpressionUMD(argument ?? factory2.createVoidZero(), containsLexicalThis);
      case 1 /* CommonJS */:
      default:
        return createImportCallExpressionCommonJS(argument);
    }
  }
  function createImportCallExpressionUMD(arg, containsLexicalThis) {
    needUMDDynamicImportHelper = true;
    if (isSimpleCopiableExpression(arg)) {
      const argClone = isGeneratedIdentifier(arg) ? arg : isStringLiteral(arg) ? factory2.createStringLiteralFromNode(arg) : setEmitFlags(setTextRange(factory2.cloneNode(arg), arg), 3072 /* NoComments */);
      return factory2.createConditionalExpression(
        /*condition*/
        factory2.createIdentifier("__syncRequire"),
        /*questionToken*/
        void 0,
        /*whenTrue*/
        createImportCallExpressionCommonJS(arg),
        /*colonToken*/
        void 0,
        /*whenFalse*/
        createImportCallExpressionAMD(argClone, containsLexicalThis)
      );
    } else {
      const temp = factory2.createTempVariable(hoistVariableDeclaration);
      return factory2.createComma(
        factory2.createAssignment(temp, arg),
        factory2.createConditionalExpression(
          /*condition*/
          factory2.createIdentifier("__syncRequire"),
          /*questionToken*/
          void 0,
          /*whenTrue*/
          createImportCallExpressionCommonJS(
            temp,
            /*isInlineable*/
            true
          ),
          /*colonToken*/
          void 0,
          /*whenFalse*/
          createImportCallExpressionAMD(temp, containsLexicalThis)
        )
      );
    }
  }
  function createImportCallExpressionAMD(arg, containsLexicalThis) {
    const resolve = factory2.createUniqueName("resolve");
    const reject = factory2.createUniqueName("reject");
    const parameters = [
      factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        /*name*/
        resolve
      ),
      factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        /*name*/
        reject
      )
    ];
    const body = factory2.createBlock([
      factory2.createExpressionStatement(
        factory2.createCallExpression(
          factory2.createIdentifier("require"),
          /*typeArguments*/
          void 0,
          [factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve, reject]
        )
      )
    ]);
    let func;
    if (languageVersion >= 2 /* ES2015 */) {
      func = factory2.createArrowFunction(
        /*modifiers*/
        void 0,
        /*typeParameters*/
        void 0,
        parameters,
        /*type*/
        void 0,
        /*equalsGreaterThanToken*/
        void 0,
        body
      );
    } else {
      func = factory2.createFunctionExpression(
        /*modifiers*/
        void 0,
        /*asteriskToken*/
        void 0,
        /*name*/
        void 0,
        /*typeParameters*/
        void 0,
        parameters,
        /*type*/
        void 0,
        body
      );
      if (containsLexicalThis) {
        setEmitFlags(func, 16 /* CapturesThis */);
      }
    }
    const promise = factory2.createNewExpression(
      factory2.createIdentifier("Promise"),
      /*typeArguments*/
      void 0,
      [func]
    );
    if (getESModuleInterop(compilerOptions)) {
      return factory2.createCallExpression(
        factory2.createPropertyAccessExpression(promise, factory2.createIdentifier("then")),
        /*typeArguments*/
        void 0,
        [emitHelpers().createImportStarCallbackHelper()]
      );
    }
    return promise;
  }
  function createImportCallExpressionCommonJS(arg, isInlineable) {
    const needSyncEval = arg && !isSimpleInlineableExpression(arg) && !isInlineable;
    const promiseResolveCall = factory2.createCallExpression(
      factory2.createPropertyAccessExpression(factory2.createIdentifier("Promise"), "resolve"),
      /*typeArguments*/
      void 0,
      /*argumentsArray*/
      needSyncEval ? languageVersion >= 2 /* ES2015 */ ? [
        factory2.createTemplateExpression(factory2.createTemplateHead(""), [
          factory2.createTemplateSpan(arg, factory2.createTemplateTail(""))
        ])
      ] : [
        factory2.createCallExpression(
          factory2.createPropertyAccessExpression(factory2.createStringLiteral(""), "concat"),
          /*typeArguments*/
          void 0,
          [arg]
        )
      ] : []
    );
    let requireCall = factory2.createCallExpression(
      factory2.createIdentifier("require"),
      /*typeArguments*/
      void 0,
      needSyncEval ? [factory2.createIdentifier("s")] : arg ? [arg] : []
    );
    if (getESModuleInterop(compilerOptions)) {
      requireCall = emitHelpers().createImportStarHelper(requireCall);
    }
    const parameters = needSyncEval ? [
      factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        /*name*/
        "s"
      )
    ] : [];
    let func;
    if (languageVersion >= 2 /* ES2015 */) {
      func = factory2.createArrowFunction(
        /*modifiers*/
        void 0,
        /*typeParameters*/
        void 0,
        /*parameters*/
        parameters,
        /*type*/
        void 0,
        /*equalsGreaterThanToken*/
        void 0,
        requireCall
      );
    } else {
      func = factory2.createFunctionExpression(
        /*modifiers*/
        void 0,
        /*asteriskToken*/
        void 0,
        /*name*/
        void 0,
        /*typeParameters*/
        void 0,
        /*parameters*/
        parameters,
        /*type*/
        void 0,
        factory2.createBlock([factory2.createReturnStatement(requireCall)])
      );
    }
    const downleveledImport = factory2.createCallExpression(
      factory2.createPropertyAccessExpression(promiseResolveCall, "then"),
      /*typeArguments*/
      void 0,
      [func]
    );
    return downleveledImport;
  }
  function getHelperExpressionForExport(node, innerExpr) {
    if (!getESModuleInterop(compilerOptions) || getInternalEmitFlags(node) & 2 /* NeverApplyImportHelper */) {
      return innerExpr;
    }
    if (getExportNeedsImportStarHelper(node)) {
      return emitHelpers().createImportStarHelper(innerExpr);
    }
    return innerExpr;
  }
  function getHelperExpressionForImport(node, innerExpr) {
    if (!getESModuleInterop(compilerOptions) || getInternalEmitFlags(node) & 2 /* NeverApplyImportHelper */) {
      return innerExpr;
    }
    if (getImportNeedsImportStarHelper(node)) {
      return emitHelpers().createImportStarHelper(innerExpr);
    }
    if (getImportNeedsImportDefaultHelper(node)) {
      return emitHelpers().createImportDefaultHelper(innerExpr);
    }
    return innerExpr;
  }
  function visitTopLevelImportDeclaration(node) {
    let statements;
    const namespaceDeclaration = getNamespaceDeclarationNode(node);
    if (moduleKind !== 2 /* AMD */) {
      if (!node.importClause) {
        return setOriginalNode(setTextRange(factory2.createExpressionStatement(createRequireCall(node)), node), node);
      } else {
        const variables = [];
        if (namespaceDeclaration && !isDefaultImport(node)) {
          variables.push(
            factory2.createVariableDeclaration(
              factory2.cloneNode(namespaceDeclaration.name),
              /*exclamationToken*/
              void 0,
              /*type*/
              void 0,
              getHelperExpressionForImport(node, createRequireCall(node))
            )
          );
        } else {
          variables.push(
            factory2.createVariableDeclaration(
              factory2.getGeneratedNameForNode(node),
              /*exclamationToken*/
              void 0,
              /*type*/
              void 0,
              getHelperExpressionForImport(node, createRequireCall(node))
            )
          );
          if (namespaceDeclaration && isDefaultImport(node)) {
            variables.push(
              factory2.createVariableDeclaration(
                factory2.cloneNode(namespaceDeclaration.name),
                /*exclamationToken*/
                void 0,
                /*type*/
                void 0,
                factory2.getGeneratedNameForNode(node)
              )
            );
          }
        }
        statements = append(
          statements,
          setOriginalNode(
            setTextRange(
              factory2.createVariableStatement(
                /*modifiers*/
                void 0,
                factory2.createVariableDeclarationList(
                  variables,
                  languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */
                )
              ),
              /*location*/
              node
            ),
            /*original*/
            node
          )
        );
      }
    } else if (namespaceDeclaration && isDefaultImport(node)) {
      statements = append(
        statements,
        factory2.createVariableStatement(
          /*modifiers*/
          void 0,
          factory2.createVariableDeclarationList(
            [
              setOriginalNode(
                setTextRange(
                  factory2.createVariableDeclaration(
                    factory2.cloneNode(namespaceDeclaration.name),
                    /*exclamationToken*/
                    void 0,
                    /*type*/
                    void 0,
                    factory2.getGeneratedNameForNode(node)
                  ),
                  /*location*/
                  node
                ),
                /*original*/
                node
              )
            ],
            languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */
          )
        )
      );
    }
    statements = appendExportsOfImportDeclaration(statements, node);
    return singleOrMany(statements);
  }
  function createRequireCall(importNode) {
    const moduleName = getExternalModuleNameLiteral(factory2, importNode, currentSourceFile, host, resolver, compilerOptions);
    const args = [];
    if (moduleName) {
      args.push(moduleName);
    }
    return factory2.createCallExpression(
      factory2.createIdentifier("require"),
      /*typeArguments*/
      void 0,
      args
    );
  }
  function visitTopLevelImportEqualsDeclaration(node) {
    Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
    let statements;
    if (moduleKind !== 2 /* AMD */) {
      if (hasSyntacticModifier(node, 32 /* Export */)) {
        statements = append(
          statements,
          setOriginalNode(
            setTextRange(
              factory2.createExpressionStatement(
                createExportExpression(
                  node.name,
                  createRequireCall(node)
                )
              ),
              node
            ),
            node
          )
        );
      } else {
        statements = append(
          statements,
          setOriginalNode(
            setTextRange(
              factory2.createVariableStatement(
                /*modifiers*/
                void 0,
                factory2.createVariableDeclarationList(
                  [
                    factory2.createVariableDeclaration(
                      factory2.cloneNode(node.name),
                      /*exclamationToken*/
                      void 0,
                      /*type*/
                      void 0,
                      createRequireCall(node)
                    )
                  ],
                  /*flags*/
                  languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */
                )
              ),
              node
            ),
            node
          )
        );
      }
    } else {
      if (hasSyntacticModifier(node, 32 /* Export */)) {
        statements = append(
          statements,
          setOriginalNode(
            setTextRange(
              factory2.createExpressionStatement(
                createExportExpression(factory2.getExportName(node), factory2.getLocalName(node))
              ),
              node
            ),
            node
          )
        );
      }
    }
    statements = appendExportsOfImportEqualsDeclaration(statements, node);
    return singleOrMany(statements);
  }
  function visitTopLevelExportDeclaration(node) {
    if (!node.moduleSpecifier) {
      return void 0;
    }
    const generatedName = factory2.getGeneratedNameForNode(node);
    if (node.exportClause && isNamedExports(node.exportClause)) {
      const statements = [];
      if (moduleKind !== 2 /* AMD */) {
        statements.push(
          setOriginalNode(
            setTextRange(
              factory2.createVariableStatement(
                /*modifiers*/
                void 0,
                factory2.createVariableDeclarationList([
                  factory2.createVariableDeclaration(
                    generatedName,
                    /*exclamationToken*/
                    void 0,
                    /*type*/
                    void 0,
                    createRequireCall(node)
                  )
                ])
              ),
              /*location*/
              node
            ),
            /* original */
            node
          )
        );
      }
      for (const specifier of node.exportClause.elements) {
        const exportNeedsImportDefault = !!getESModuleInterop(compilerOptions) && !(getInternalEmitFlags(node) & 2 /* NeverApplyImportHelper */) && idText(specifier.propertyName || specifier.name) === "default";
        const exportedValue = factory2.createPropertyAccessExpression(
          exportNeedsImportDefault ? emitHelpers().createImportDefaultHelper(generatedName) : generatedName,
          specifier.propertyName || specifier.name
        );
        statements.push(
          setOriginalNode(
            setTextRange(
              factory2.createExpressionStatement(
                createExportExpression(
                  factory2.getExportName(specifier),
                  exportedValue,
                  /*location*/
                  void 0,
                  /*liveBinding*/
                  true
                )
              ),
              specifier
            ),
            specifier
          )
        );
      }
      return singleOrMany(statements);
    } else if (node.exportClause) {
      const statements = [];
      statements.push(
        setOriginalNode(
          setTextRange(
            factory2.createExpressionStatement(
              createExportExpression(
                factory2.cloneNode(node.exportClause.name),
                getHelperExpressionForExport(
                  node,
                  moduleKind !== 2 /* AMD */ ? createRequireCall(node) : isExportNamespaceAsDefaultDeclaration(node) ? generatedName : factory2.createIdentifier(idText(node.exportClause.name))
                )
              )
            ),
            node
          ),
          node
        )
      );
      return singleOrMany(statements);
    } else {
      return setOriginalNode(
        setTextRange(
          factory2.createExpressionStatement(
            emitHelpers().createExportStarHelper(moduleKind !== 2 /* AMD */ ? createRequireCall(node) : generatedName)
          ),
          node
        ),
        node
      );
    }
  }
  function visitTopLevelExportAssignment(node) {
    if (node.isExportEquals) {
      return void 0;
    }
    return createExportStatement(
      factory2.createIdentifier("default"),
      visitNode(node.expression, visitor, isExpression),
      /*location*/
      node,
      /*allowComments*/
      true
    );
  }
  function visitFunctionDeclaration(node) {
    let statements;
    if (hasSyntacticModifier(node, 32 /* Export */)) {
      statements = append(
        statements,
        setOriginalNode(
          setTextRange(
            factory2.createFunctionDeclaration(
              visitNodes2(node.modifiers, modifierVisitor, isModifier),
              node.asteriskToken,
              factory2.getDeclarationName(
                node,
                /*allowComments*/
                true,
                /*allowSourceMaps*/
                true
              ),
              /*typeParameters*/
              void 0,
              visitNodes2(node.parameters, visitor, isParameter),
              /*type*/
              void 0,
              visitEachChild(node.body, visitor, context)
            ),
            /*location*/
            node
          ),
          /*original*/
          node
        )
      );
    } else {
      statements = append(statements, visitEachChild(node, visitor, context));
    }
    return singleOrMany(statements);
  }
  function visitClassDeclaration(node) {
    let statements;
    if (hasSyntacticModifier(node, 32 /* Export */)) {
      statements = append(
        statements,
        setOriginalNode(
          setTextRange(
            factory2.createClassDeclaration(
              visitNodes2(node.modifiers, modifierVisitor, isModifierLike),
              factory2.getDeclarationName(
                node,
                /*allowComments*/
                true,
                /*allowSourceMaps*/
                true
              ),
              /*typeParameters*/
              void 0,
              visitNodes2(node.heritageClauses, visitor, isHeritageClause),
              visitNodes2(node.members, visitor, isClassElement)
            ),
            node
          ),
          node
        )
      );
    } else {
      statements = append(statements, visitEachChild(node, visitor, context));
    }
    statements = appendExportsOfHoistedDeclaration(statements, node);
    return singleOrMany(statements);
  }
  function visitVariableStatement(node) {
    let statements;
    let variables;
    let expressions;
    if (hasSyntacticModifier(node, 32 /* Export */)) {
      let modifiers;
      let removeCommentsOnExpressions = false;
      for (const variable of node.declarationList.declarations) {
        if (isIdentifier(variable.name) && isLocalName(variable.name)) {
          if (!modifiers) {
            modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifier);
          }
          if (variable.initializer) {
            const updatedVariable = factory2.updateVariableDeclaration(
              variable,
              variable.name,
              /*exclamationToken*/
              void 0,
              /*type*/
              void 0,
              createExportExpression(
                variable.name,
                visitNode(variable.initializer, visitor, isExpression)
              )
            );
            variables = append(variables, updatedVariable);
          } else {
            variables = append(variables, variable);
          }
        } else if (variable.initializer) {
          if (!isBindingPattern(variable.name) && (isArrowFunction(variable.initializer) || isFunctionExpression(variable.initializer) || isClassExpression(variable.initializer))) {
            const expression = factory2.createAssignment(
              setTextRange(
                factory2.createPropertyAccessExpression(
                  factory2.createIdentifier("exports"),
                  variable.name
                ),
                /*location*/
                variable.name
              ),
              factory2.createIdentifier(getTextOfIdentifierOrLiteral(variable.name))
            );
            const updatedVariable = factory2.createVariableDeclaration(
              variable.name,
              variable.exclamationToken,
              variable.type,
              visitNode(variable.initializer, visitor, isExpression)
            );
            variables = append(variables, updatedVariable);
            expressions = append(expressions, expression);
            removeCommentsOnExpressions = true;
          } else {
            expressions = append(expressions, transformInitializedVariable(variable));
          }
        }
      }
      if (variables) {
        statements = append(statements, factory2.updateVariableStatement(node, modifiers, factory2.updateVariableDeclarationList(node.declarationList, variables)));
      }
      if (expressions) {
        const statement = setOriginalNode(setTextRange(factory2.createExpressionStatement(factory2.inlineExpressions(expressions)), node), node);
        if (removeCommentsOnExpressions) {
          removeAllComments(statement);
        }
        statements = append(statements, statement);
      }
    } else {
      statements = append(statements, visitEachChild(node, visitor, context));
    }
    statements = appendExportsOfVariableStatement(statements, node);
    return singleOrMany(statements);
  }
  function createAllExportExpressions(name, value, location) {
    const exportedNames = getExports(name);
    if (exportedNames) {
      let expression = isExportName(name) ? value : factory2.createAssignment(name, value);
      for (const exportName of exportedNames) {
        setEmitFlags(expression, 8 /* NoSubstitution */);
        expression = createExportExpression(
          exportName,
          expression,
          /*location*/
          location
        );
      }
      return expression;
    }
    return factory2.createAssignment(name, value);
  }
  function transformInitializedVariable(node) {
    if (isBindingPattern(node.name)) {
      return flattenDestructuringAssignment(
        visitNode(node, visitor, isInitializedVariable),
        visitor,
        context,
        0 /* All */,
        /*needsValue*/
        false,
        createAllExportExpressions
      );
    } else {
      return factory2.createAssignment(
        setTextRange(
          factory2.createPropertyAccessExpression(
            factory2.createIdentifier("exports"),
            node.name
          ),
          /*location*/
          node.name
        ),
        node.initializer ? visitNode(node.initializer, visitor, isExpression) : factory2.createVoidZero()
      );
    }
  }
  function appendExportsOfImportDeclaration(statements, decl) {
    if (currentModuleInfo.exportEquals) {
      return statements;
    }
    const importClause = decl.importClause;
    if (!importClause) {
      return statements;
    }
    const seen = new IdentifierNameMap();
    if (importClause.name) {
      statements = appendExportsOfDeclaration(statements, seen, importClause);
    }
    const namedBindings = importClause.namedBindings;
    if (namedBindings) {
      switch (namedBindings.kind) {
        case 274 /* NamespaceImport */:
          statements = appendExportsOfDeclaration(statements, seen, namedBindings);
          break;
        case 275 /* NamedImports */:
          for (const importBinding of namedBindings.elements) {
            statements = appendExportsOfDeclaration(
              statements,
              seen,
              importBinding,
              /*liveBinding*/
              true
            );
          }
          break;
      }
    }
    return statements;
  }
  function appendExportsOfImportEqualsDeclaration(statements, decl) {
    if (currentModuleInfo.exportEquals) {
      return statements;
    }
    return appendExportsOfDeclaration(statements, new IdentifierNameMap(), decl);
  }
  function appendExportsOfVariableStatement(statements, node) {
    return appendExportsOfVariableDeclarationList(
      statements,
      node.declarationList,
      /*isForInOrOfInitializer*/
      false
    );
  }
  function appendExportsOfVariableDeclarationList(statements, node, isForInOrOfInitializer) {
    if (currentModuleInfo.exportEquals) {
      return statements;
    }
    for (const decl of node.declarations) {
      statements = appendExportsOfBindingElement(statements, decl, isForInOrOfInitializer);
    }
    return statements;
  }
  function appendExportsOfBindingElement(statements, decl, isForInOrOfInitializer) {
    if (currentModuleInfo.exportEquals) {
      return statements;
    }
    if (isBindingPattern(decl.name)) {
      for (const element of decl.name.elements) {
        if (!isOmittedExpression(element)) {
          statements = appendExportsOfBindingElement(statements, element, isForInOrOfInitializer);
        }
      }
    } else if (!isGeneratedIdentifier(decl.name) && (!isVariableDeclaration(decl) || decl.initializer || isForInOrOfInitializer)) {
      statements = appendExportsOfDeclaration(statements, new IdentifierNameMap(), decl);
    }
    return statements;
  }
  function appendExportsOfHoistedDeclaration(statements, decl) {
    if (currentModuleInfo.exportEquals) {
      return statements;
    }
    const seen = new IdentifierNameMap();
    if (hasSyntacticModifier(decl, 32 /* Export */)) {
      const exportName = hasSyntacticModifier(decl, 2048 /* Default */) ? factory2.createIdentifier("default") : factory2.getDeclarationName(decl);
      statements = appendExportStatement(
        statements,
        seen,
        exportName,
        factory2.getLocalName(decl),
        /*location*/
        decl
      );
    }
    if (decl.name) {
      statements = appendExportsOfDeclaration(statements, seen, decl);
    }
    return statements;
  }
  function appendExportsOfDeclaration(statements, seen, decl, liveBinding) {
    const name = factory2.getDeclarationName(decl);
    const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(name);
    if (exportSpecifiers) {
      for (const exportSpecifier of exportSpecifiers) {
        statements = appendExportStatement(
          statements,
          seen,
          exportSpecifier.name,
          name,
          /*location*/
          exportSpecifier.name,
          /*allowComments*/
          void 0,
          liveBinding
        );
      }
    }
    return statements;
  }
  function appendExportStatement(statements, seen, exportName, expression, location, allowComments, liveBinding) {
    if (!seen.has(exportName)) {
      seen.set(exportName, true);
      statements = append(statements, createExportStatement(exportName, expression, location, allowComments, liveBinding));
    }
    return statements;
  }
  function createUnderscoreUnderscoreESModule() {
    const statement = factory2.createExpressionStatement(
      factory2.createCallExpression(
        factory2.createPropertyAccessExpression(factory2.createIdentifier("Object"), "defineProperty"),
        /*typeArguments*/
        void 0,
        [
          factory2.createIdentifier("exports"),
          factory2.createStringLiteral("__esModule"),
          factory2.createObjectLiteralExpression([
            factory2.createPropertyAssignment("value", factory2.createTrue())
          ])
        ]
      )
    );
    setEmitFlags(statement, 2097152 /* CustomPrologue */);
    return statement;
  }
  function createExportStatement(name, value, location, allowComments, liveBinding) {
    const statement = setTextRange(factory2.createExpressionStatement(createExportExpression(
      name,
      value,
      /*location*/
      void 0,
      liveBinding
    )), location);
    startOnNewLine(statement);
    if (!allowComments) {
      setEmitFlags(statement, 3072 /* NoComments */);
    }
    return statement;
  }
  function createExportExpression(name, value, location, liveBinding) {
    return setTextRange(
      liveBinding ? factory2.createCallExpression(
        factory2.createPropertyAccessExpression(
          factory2.createIdentifier("Object"),
          "defineProperty"
        ),
        /*typeArguments*/
        void 0,
        [
          factory2.createIdentifier("exports"),
          factory2.createStringLiteralFromNode(name),
          factory2.createObjectLiteralExpression([
            factory2.createPropertyAssignment("enumerable", factory2.createTrue()),
            factory2.createPropertyAssignment(
              "get",
              factory2.createFunctionExpression(
                /*modifiers*/
                void 0,
                /*asteriskToken*/
                void 0,
                /*name*/
                void 0,
                /*typeParameters*/
                void 0,
                /*parameters*/
                [],
                /*type*/
                void 0,
                factory2.createBlock([factory2.createReturnStatement(value)])
              )
            )
          ])
        ]
      ) : factory2.createAssignment(
        factory2.createPropertyAccessExpression(
          factory2.createIdentifier("exports"),
          factory2.cloneNode(name)
        ),
        value
      ),
      location
    );
  }
  function modifierVisitor(node) {
    switch (node.kind) {
      case 95 /* ExportKeyword */:
      case 90 /* DefaultKeyword */:
        return void 0;
    }
    return node;
  }
  function onEmitNode(hint, node, emitCallback) {
    if (node.kind === 307 /* SourceFile */) {
      currentSourceFile = node;
      currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)];
      previousOnEmitNode(hint, node, emitCallback);
      currentSourceFile = void 0;
      currentModuleInfo = void 0;
    } else {
      previousOnEmitNode(hint, node, emitCallback);
    }
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (node.id && noSubstitution[node.id]) {
      return node;
    }
    if (hint === 1 /* Expression */) {
      return substituteExpression(node);
    } else if (isShorthandPropertyAssignment(node)) {
      return substituteShorthandPropertyAssignment(node);
    }
    return node;
  }
  function substituteShorthandPropertyAssignment(node) {
    const name = node.name;
    const exportedOrImportedName = substituteExpressionIdentifier(name);
    if (exportedOrImportedName !== name) {
      if (node.objectAssignmentInitializer) {
        const initializer = factory2.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
        return setTextRange(factory2.createPropertyAssignment(name, initializer), node);
      }
      return setTextRange(factory2.createPropertyAssignment(name, exportedOrImportedName), node);
    }
    return node;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 80 /* Identifier */:
        return substituteExpressionIdentifier(node);
      case 213 /* CallExpression */:
        return substituteCallExpression(node);
      case 215 /* TaggedTemplateExpression */:
        return substituteTaggedTemplateExpression(node);
      case 226 /* BinaryExpression */:
        return substituteBinaryExpression(node);
    }
    return node;
  }
  function substituteCallExpression(node) {
    if (isIdentifier(node.expression)) {
      const expression = substituteExpressionIdentifier(node.expression);
      noSubstitution[getNodeId(expression)] = true;
      if (!isIdentifier(expression) && !(getEmitFlags(node.expression) & 8192 /* HelperName */)) {
        return addInternalEmitFlags(
          factory2.updateCallExpression(
            node,
            expression,
            /*typeArguments*/
            void 0,
            node.arguments
          ),
          16 /* IndirectCall */
        );
      }
    }
    return node;
  }
  function substituteTaggedTemplateExpression(node) {
    if (isIdentifier(node.tag)) {
      const tag = substituteExpressionIdentifier(node.tag);
      noSubstitution[getNodeId(tag)] = true;
      if (!isIdentifier(tag) && !(getEmitFlags(node.tag) & 8192 /* HelperName */)) {
        return addInternalEmitFlags(
          factory2.updateTaggedTemplateExpression(
            node,
            tag,
            /*typeArguments*/
            void 0,
            node.template
          ),
          16 /* IndirectCall */
        );
      }
    }
    return node;
  }
  function substituteExpressionIdentifier(node) {
    var _a, _b;
    if (getEmitFlags(node) & 8192 /* HelperName */) {
      const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile);
      if (externalHelpersModuleName) {
        return factory2.createPropertyAccessExpression(externalHelpersModuleName, node);
      }
      return node;
    } else if (!(isGeneratedIdentifier(node) && !(node.emitNode.autoGenerate.flags & 64 /* AllowNameSubstitution */)) && !isLocalName(node)) {
      const exportContainer = resolver.getReferencedExportContainer(node, isExportName(node));
      if (exportContainer && exportContainer.kind === 307 /* SourceFile */) {
        return setTextRange(
          factory2.createPropertyAccessExpression(
            factory2.createIdentifier("exports"),
            factory2.cloneNode(node)
          ),
          /*location*/
          node
        );
      }
      const importDeclaration = resolver.getReferencedImportDeclaration(node);
      if (importDeclaration) {
        if (isImportClause(importDeclaration)) {
          return setTextRange(
            factory2.createPropertyAccessExpression(
              factory2.getGeneratedNameForNode(importDeclaration.parent),
              factory2.createIdentifier("default")
            ),
            /*location*/
            node
          );
        } else if (isImportSpecifier(importDeclaration)) {
          const name = importDeclaration.propertyName || importDeclaration.name;
          return setTextRange(
            factory2.createPropertyAccessExpression(
              factory2.getGeneratedNameForNode(((_b = (_a = importDeclaration.parent) == null ? void 0 : _a.parent) == null ? void 0 : _b.parent) || importDeclaration),
              factory2.cloneNode(name)
            ),
            /*location*/
            node
          );
        }
      }
    }
    return node;
  }
  function substituteBinaryExpression(node) {
    if (isAssignmentOperator(node.operatorToken.kind) && isIdentifier(node.left) && (!isGeneratedIdentifier(node.left) || isFileLevelReservedGeneratedIdentifier(node.left)) && !isLocalName(node.left)) {
      const exportedNames = getExports(node.left);
      if (exportedNames) {
        let expression = node;
        for (const exportName of exportedNames) {
          noSubstitution[getNodeId(expression)] = true;
          expression = createExportExpression(
            exportName,
            expression,
            /*location*/
            node
          );
        }
        return expression;
      }
    }
    return node;
  }
  function getExports(name) {
    if (!isGeneratedIdentifier(name)) {
      const importDeclaration = resolver.getReferencedImportDeclaration(name);
      if (importDeclaration) {
        return currentModuleInfo == null ? void 0 : currentModuleInfo.exportedBindings[getOriginalNodeId(importDeclaration)];
      }
      const bindingsSet = /* @__PURE__ */ new Set();
      const declarations = resolver.getReferencedValueDeclarations(name);
      if (declarations) {
        for (const declaration of declarations) {
          const bindings = currentModuleInfo == null ? void 0 : currentModuleInfo.exportedBindings[getOriginalNodeId(declaration)];
          if (bindings) {
            for (const binding of bindings) {
              bindingsSet.add(binding);
            }
          }
        }
        if (bindingsSet.size) {
          return arrayFrom(bindingsSet);
        }
      }
    } else if (isFileLevelReservedGeneratedIdentifier(name)) {
      const exportSpecifiers = currentModuleInfo == null ? void 0 : currentModuleInfo.exportSpecifiers.get(name);
      if (exportSpecifiers) {
        const exportedNames = [];
        for (const exportSpecifier of exportSpecifiers) {
          exportedNames.push(exportSpecifier.name);
        }
        return exportedNames;
      }
    }
  }
}
var dynamicImportUMDHelper = {
  name: "typescript:dynamicimport-sync-require",
  scoped: true,
  text: `
            var __syncRequire = typeof module === "object" && typeof module.exports === "object";`
};

// src/compiler/transformers/module/system.ts
function transformSystemModule(context) {
  const {
    factory: factory2,
    startLexicalEnvironment,
    endLexicalEnvironment,
    hoistVariableDeclaration
  } = context;
  const compilerOptions = context.getCompilerOptions();
  const resolver = context.getEmitResolver();
  const host = context.getEmitHost();
  const previousOnSubstituteNode = context.onSubstituteNode;
  const previousOnEmitNode = context.onEmitNode;
  context.onSubstituteNode = onSubstituteNode;
  context.onEmitNode = onEmitNode;
  context.enableSubstitution(80 /* Identifier */);
  context.enableSubstitution(304 /* ShorthandPropertyAssignment */);
  context.enableSubstitution(226 /* BinaryExpression */);
  context.enableSubstitution(236 /* MetaProperty */);
  context.enableEmitNotification(307 /* SourceFile */);
  const moduleInfoMap = [];
  const exportFunctionsMap = [];
  const noSubstitutionMap = [];
  const contextObjectMap = [];
  let currentSourceFile;
  let moduleInfo;
  let exportFunction;
  let contextObject;
  let hoistedStatements;
  let enclosingBlockScopedContainer;
  let noSubstitution;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 8388608 /* ContainsDynamicImport */)) {
      return node;
    }
    const id = getOriginalNodeId(node);
    currentSourceFile = node;
    enclosingBlockScopedContainer = node;
    moduleInfo = moduleInfoMap[id] = collectExternalModuleInfo(context, node);
    exportFunction = factory2.createUniqueName("exports");
    exportFunctionsMap[id] = exportFunction;
    contextObject = contextObjectMap[id] = factory2.createUniqueName("context");
    const dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
    const moduleBodyBlock = createSystemModuleBody(node, dependencyGroups);
    const moduleBodyFunction = factory2.createFunctionExpression(
      /*modifiers*/
      void 0,
      /*asteriskToken*/
      void 0,
      /*name*/
      void 0,
      /*typeParameters*/
      void 0,
      [
        factory2.createParameterDeclaration(
          /*modifiers*/
          void 0,
          /*dotDotDotToken*/
          void 0,
          exportFunction
        ),
        factory2.createParameterDeclaration(
          /*modifiers*/
          void 0,
          /*dotDotDotToken*/
          void 0,
          contextObject
        )
      ],
      /*type*/
      void 0,
      moduleBodyBlock
    );
    const moduleName = tryGetModuleNameFromFile(factory2, node, host, compilerOptions);
    const dependencies = factory2.createArrayLiteralExpression(map(dependencyGroups, (dependencyGroup) => dependencyGroup.name));
    const updated = setEmitFlags(
      factory2.updateSourceFile(
        node,
        setTextRange(
          factory2.createNodeArray([
            factory2.createExpressionStatement(
              factory2.createCallExpression(
                factory2.createPropertyAccessExpression(factory2.createIdentifier("System"), "register"),
                /*typeArguments*/
                void 0,
                moduleName ? [moduleName, dependencies, moduleBodyFunction] : [dependencies, moduleBodyFunction]
              )
            )
          ]),
          node.statements
        )
      ),
      2048 /* NoTrailingComments */
    );
    if (!compilerOptions.outFile) {
      moveEmitHelpers(updated, moduleBodyBlock, (helper) => !helper.scoped);
    }
    if (noSubstitution) {
      noSubstitutionMap[id] = noSubstitution;
      noSubstitution = void 0;
    }
    currentSourceFile = void 0;
    moduleInfo = void 0;
    exportFunction = void 0;
    contextObject = void 0;
    hoistedStatements = void 0;
    enclosingBlockScopedContainer = void 0;
    return updated;
  }
  function collectDependencyGroups(externalImports) {
    const groupIndices = /* @__PURE__ */ new Map();
    const dependencyGroups = [];
    for (const externalImport of externalImports) {
      const externalModuleName = getExternalModuleNameLiteral(factory2, externalImport, currentSourceFile, host, resolver, compilerOptions);
      if (externalModuleName) {
        const text = externalModuleName.text;
        const groupIndex = groupIndices.get(text);
        if (groupIndex !== void 0) {
          dependencyGroups[groupIndex].externalImports.push(externalImport);
        } else {
          groupIndices.set(text, dependencyGroups.length);
          dependencyGroups.push({
            name: externalModuleName,
            externalImports: [externalImport]
          });
        }
      }
    }
    return dependencyGroups;
  }
  function createSystemModuleBody(node, dependencyGroups) {
    const statements = [];
    startLexicalEnvironment();
    const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || isExternalModule(currentSourceFile);
    const statementOffset = factory2.copyPrologue(node.statements, statements, ensureUseStrict, topLevelVisitor);
    statements.push(
      factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList([
          factory2.createVariableDeclaration(
            "__moduleName",
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            factory2.createLogicalAnd(
              contextObject,
              factory2.createPropertyAccessExpression(contextObject, "id")
            )
          )
        ])
      )
    );
    visitNode(moduleInfo.externalHelpersImportDeclaration, topLevelVisitor, isStatement);
    const executeStatements = visitNodes2(node.statements, topLevelVisitor, isStatement, statementOffset);
    addRange(statements, hoistedStatements);
    insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
    const exportStarFunction = addExportStarIfNeeded(statements);
    const modifiers = node.transformFlags & 2097152 /* ContainsAwait */ ? factory2.createModifiersFromModifierFlags(1024 /* Async */) : void 0;
    const moduleObject = factory2.createObjectLiteralExpression(
      [
        factory2.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups)),
        factory2.createPropertyAssignment(
          "execute",
          factory2.createFunctionExpression(
            modifiers,
            /*asteriskToken*/
            void 0,
            /*name*/
            void 0,
            /*typeParameters*/
            void 0,
            /*parameters*/
            [],
            /*type*/
            void 0,
            factory2.createBlock(
              executeStatements,
              /*multiLine*/
              true
            )
          )
        )
      ],
      /*multiLine*/
      true
    );
    statements.push(factory2.createReturnStatement(moduleObject));
    return factory2.createBlock(
      statements,
      /*multiLine*/
      true
    );
  }
  function addExportStarIfNeeded(statements) {
    if (!moduleInfo.hasExportStarsToExportValues) {
      return;
    }
    if (!some(moduleInfo.exportedNames) && moduleInfo.exportedFunctions.size === 0 && moduleInfo.exportSpecifiers.size === 0) {
      let hasExportDeclarationWithExportClause = false;
      for (const externalImport of moduleInfo.externalImports) {
        if (externalImport.kind === 278 /* ExportDeclaration */ && externalImport.exportClause) {
          hasExportDeclarationWithExportClause = true;
          break;
        }
      }
      if (!hasExportDeclarationWithExportClause) {
        const exportStarFunction2 = createExportStarFunction(
          /*localNames*/
          void 0
        );
        statements.push(exportStarFunction2);
        return exportStarFunction2.name;
      }
    }
    const exportedNames = [];
    if (moduleInfo.exportedNames) {
      for (const exportedLocalName of moduleInfo.exportedNames) {
        if (exportedLocalName.escapedText === "default") {
          continue;
        }
        exportedNames.push(
          factory2.createPropertyAssignment(
            factory2.createStringLiteralFromNode(exportedLocalName),
            factory2.createTrue()
          )
        );
      }
    }
    for (const f of moduleInfo.exportedFunctions) {
      if (hasSyntacticModifier(f, 2048 /* Default */)) {
        continue;
      }
      Debug.assert(!!f.name);
      exportedNames.push(
        factory2.createPropertyAssignment(
          factory2.createStringLiteralFromNode(f.name),
          factory2.createTrue()
        )
      );
    }
    const exportedNamesStorageRef = factory2.createUniqueName("exportedNames");
    statements.push(
      factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList([
          factory2.createVariableDeclaration(
            exportedNamesStorageRef,
            /*exclamationToken*/
            void 0,
            /*type*/
            void 0,
            factory2.createObjectLiteralExpression(
              exportedNames,
              /*multiLine*/
              true
            )
          )
        ])
      )
    );
    const exportStarFunction = createExportStarFunction(exportedNamesStorageRef);
    statements.push(exportStarFunction);
    return exportStarFunction.name;
  }
  function createExportStarFunction(localNames) {
    const exportStarFunction = factory2.createUniqueName("exportStar");
    const m = factory2.createIdentifier("m");
    const n = factory2.createIdentifier("n");
    const exports2 = factory2.createIdentifier("exports");
    let condition = factory2.createStrictInequality(n, factory2.createStringLiteral("default"));
    if (localNames) {
      condition = factory2.createLogicalAnd(
        condition,
        factory2.createLogicalNot(
          factory2.createCallExpression(
            factory2.createPropertyAccessExpression(localNames, "hasOwnProperty"),
            /*typeArguments*/
            void 0,
            [n]
          )
        )
      );
    }
    return factory2.createFunctionDeclaration(
      /*modifiers*/
      void 0,
      /*asteriskToken*/
      void 0,
      exportStarFunction,
      /*typeParameters*/
      void 0,
      [factory2.createParameterDeclaration(
        /*modifiers*/
        void 0,
        /*dotDotDotToken*/
        void 0,
        m
      )],
      /*type*/
      void 0,
      factory2.createBlock(
        [
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            factory2.createVariableDeclarationList([
              factory2.createVariableDeclaration(
                exports2,
                /*exclamationToken*/
                void 0,
                /*type*/
                void 0,
                factory2.createObjectLiteralExpression([])
              )
            ])
          ),
          factory2.createForInStatement(
            factory2.createVariableDeclarationList([
              factory2.createVariableDeclaration(n)
            ]),
            m,
            factory2.createBlock([
              setEmitFlags(
                factory2.createIfStatement(
                  condition,
                  factory2.createExpressionStatement(
                    factory2.createAssignment(
                      factory2.createElementAccessExpression(exports2, n),
                      factory2.createElementAccessExpression(m, n)
                    )
                  )
                ),
                1 /* SingleLine */
              )
            ])
          ),
          factory2.createExpressionStatement(
            factory2.createCallExpression(
              exportFunction,
              /*typeArguments*/
              void 0,
              [exports2]
            )
          )
        ],
        /*multiLine*/
        true
      )
    );
  }
  function createSettersArray(exportStarFunction, dependencyGroups) {
    const setters = [];
    for (const group2 of dependencyGroups) {
      const localName = forEach(group2.externalImports, (i) => getLocalNameForExternalImport(factory2, i, currentSourceFile));
      const parameterName = localName ? factory2.getGeneratedNameForNode(localName) : factory2.createUniqueName("");
      const statements = [];
      for (const entry of group2.externalImports) {
        const importVariableName = getLocalNameForExternalImport(factory2, entry, currentSourceFile);
        switch (entry.kind) {
          case 272 /* ImportDeclaration */:
            if (!entry.importClause) {
              break;
            }
          case 271 /* ImportEqualsDeclaration */:
            Debug.assert(importVariableName !== void 0);
            statements.push(
              factory2.createExpressionStatement(
                factory2.createAssignment(importVariableName, parameterName)
              )
            );
            if (hasSyntacticModifier(entry, 32 /* Export */)) {
              statements.push(
                factory2.createExpressionStatement(
                  factory2.createCallExpression(
                    exportFunction,
                    /*typeArguments*/
                    void 0,
                    [
                      factory2.createStringLiteral(idText(importVariableName)),
                      parameterName
                    ]
                  )
                )
              );
            }
            break;
          case 278 /* ExportDeclaration */:
            Debug.assert(importVariableName !== void 0);
            if (entry.exportClause) {
              if (isNamedExports(entry.exportClause)) {
                const properties = [];
                for (const e of entry.exportClause.elements) {
                  properties.push(
                    factory2.createPropertyAssignment(
                      factory2.createStringLiteral(idText(e.name)),
                      factory2.createElementAccessExpression(
                        parameterName,
                        factory2.createStringLiteral(idText(e.propertyName || e.name))
                      )
                    )
                  );
                }
                statements.push(
                  factory2.createExpressionStatement(
                    factory2.createCallExpression(
                      exportFunction,
                      /*typeArguments*/
                      void 0,
                      [factory2.createObjectLiteralExpression(
                        properties,
                        /*multiLine*/
                        true
                      )]
                    )
                  )
                );
              } else {
                statements.push(
                  factory2.createExpressionStatement(
                    factory2.createCallExpression(
                      exportFunction,
                      /*typeArguments*/
                      void 0,
                      [
                        factory2.createStringLiteral(idText(entry.exportClause.name)),
                        parameterName
                      ]
                    )
                  )
                );
              }
            } else {
              statements.push(
                factory2.createExpressionStatement(
                  factory2.createCallExpression(
                    exportStarFunction,
                    /*typeArguments*/
                    void 0,
                    [parameterName]
                  )
                )
              );
            }
            break;
        }
      }
      setters.push(
        factory2.createFunctionExpression(
          /*modifiers*/
          void 0,
          /*asteriskToken*/
          void 0,
          /*name*/
          void 0,
          /*typeParameters*/
          void 0,
          [factory2.createParameterDeclaration(
            /*modifiers*/
            void 0,
            /*dotDotDotToken*/
            void 0,
            parameterName
          )],
          /*type*/
          void 0,
          factory2.createBlock(
            statements,
            /*multiLine*/
            true
          )
        )
      );
    }
    return factory2.createArrayLiteralExpression(
      setters,
      /*multiLine*/
      true
    );
  }
  function topLevelVisitor(node) {
    switch (node.kind) {
      case 272 /* ImportDeclaration */:
        return visitImportDeclaration(node);
      case 271 /* ImportEqualsDeclaration */:
        return visitImportEqualsDeclaration(node);
      case 278 /* ExportDeclaration */:
        return visitExportDeclaration(node);
      case 277 /* ExportAssignment */:
        return visitExportAssignment(node);
      default:
        return topLevelNestedVisitor(node);
    }
  }
  function visitImportDeclaration(node) {
    let statements;
    if (node.importClause) {
      hoistVariableDeclaration(getLocalNameForExternalImport(factory2, node, currentSourceFile));
    }
    return singleOrMany(appendExportsOfImportDeclaration(statements, node));
  }
  function visitExportDeclaration(node) {
    Debug.assertIsDefined(node);
    return void 0;
  }
  function visitImportEqualsDeclaration(node) {
    Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
    let statements;
    hoistVariableDeclaration(getLocalNameForExternalImport(factory2, node, currentSourceFile));
    return singleOrMany(appendExportsOfImportEqualsDeclaration(statements, node));
  }
  function visitExportAssignment(node) {
    if (node.isExportEquals) {
      return void 0;
    }
    const expression = visitNode(node.expression, visitor, isExpression);
    return createExportStatement(
      factory2.createIdentifier("default"),
      expression,
      /*allowComments*/
      true
    );
  }
  function visitFunctionDeclaration(node) {
    if (hasSyntacticModifier(node, 32 /* Export */)) {
      hoistedStatements = append(
        hoistedStatements,
        factory2.updateFunctionDeclaration(
          node,
          visitNodes2(node.modifiers, modifierVisitor, isModifierLike),
          node.asteriskToken,
          factory2.getDeclarationName(
            node,
            /*allowComments*/
            true,
            /*allowSourceMaps*/
            true
          ),
          /*typeParameters*/
          void 0,
          visitNodes2(node.parameters, visitor, isParameter),
          /*type*/
          void 0,
          visitNode(node.body, visitor, isBlock)
        )
      );
    } else {
      hoistedStatements = append(hoistedStatements, visitEachChild(node, visitor, context));
    }
    hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
    return void 0;
  }
  function visitClassDeclaration(node) {
    let statements;
    const name = factory2.getLocalName(node);
    hoistVariableDeclaration(name);
    statements = append(
      statements,
      setTextRange(
        factory2.createExpressionStatement(
          factory2.createAssignment(
            name,
            setTextRange(
              factory2.createClassExpression(
                visitNodes2(node.modifiers, modifierVisitor, isModifierLike),
                node.name,
                /*typeParameters*/
                void 0,
                visitNodes2(node.heritageClauses, visitor, isHeritageClause),
                visitNodes2(node.members, visitor, isClassElement)
              ),
              node
            )
          )
        ),
        node
      )
    );
    statements = appendExportsOfHoistedDeclaration(statements, node);
    return singleOrMany(statements);
  }
  function visitVariableStatement(node) {
    if (!shouldHoistVariableDeclarationList(node.declarationList)) {
      return visitNode(node, visitor, isStatement);
    }
    let statements;
    if (isVarUsing(node.declarationList) || isVarAwaitUsing(node.declarationList)) {
      const modifiers = visitNodes2(node.modifiers, modifierVisitor, isModifierLike);
      const declarations = [];
      for (const variable of node.declarationList.declarations) {
        declarations.push(factory2.updateVariableDeclaration(
          variable,
          factory2.getGeneratedNameForNode(variable.name),
          /*exclamationToken*/
          void 0,
          /*type*/
          void 0,
          transformInitializedVariable(
            variable,
            /*isExportedDeclaration*/
            false
          )
        ));
      }
      const declarationList = factory2.updateVariableDeclarationList(
        node.declarationList,
        declarations
      );
      statements = append(statements, factory2.updateVariableStatement(node, modifiers, declarationList));
    } else {
      let expressions;
      const isExportedDeclaration = hasSyntacticModifier(node, 32 /* Export */);
      for (const variable of node.declarationList.declarations) {
        if (variable.initializer) {
          expressions = append(expressions, transformInitializedVariable(variable, isExportedDeclaration));
        } else {
          hoistBindingElement(variable);
        }
      }
      if (expressions) {
        statements = append(statements, setTextRange(factory2.createExpressionStatement(factory2.inlineExpressions(expressions)), node));
      }
    }
    statements = appendExportsOfVariableStatement(
      statements,
      node,
      /*exportSelf*/
      false
    );
    return singleOrMany(statements);
  }
  function hoistBindingElement(node) {
    if (isBindingPattern(node.name)) {
      for (const element of node.name.elements) {
        if (!isOmittedExpression(element)) {
          hoistBindingElement(element);
        }
      }
    } else {
      hoistVariableDeclaration(factory2.cloneNode(node.name));
    }
  }
  function shouldHoistVariableDeclarationList(node) {
    return (getEmitFlags(node) & 4194304 /* NoHoisting */) === 0 && (enclosingBlockScopedContainer.kind === 307 /* SourceFile */ || (getOriginalNode(node).flags & 7 /* BlockScoped */) === 0);
  }
  function transformInitializedVariable(node, isExportedDeclaration) {
    const createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
    return isBindingPattern(node.name) ? flattenDestructuringAssignment(
      node,
      visitor,
      context,
      0 /* All */,
      /*needsValue*/
      false,
      createAssignment
    ) : node.initializer ? createAssignment(node.name, visitNode(node.initializer, visitor, isExpression)) : node.name;
  }
  function createExportedVariableAssignment(name, value, location) {
    return createVariableAssignment(
      name,
      value,
      location,
      /*isExportedDeclaration*/
      true
    );
  }
  function createNonExportedVariableAssignment(name, value, location) {
    return createVariableAssignment(
      name,
      value,
      location,
      /*isExportedDeclaration*/
      false
    );
  }
  function createVariableAssignment(name, value, location, isExportedDeclaration) {
    hoistVariableDeclaration(factory2.cloneNode(name));
    return isExportedDeclaration ? createExportExpression(name, preventSubstitution(setTextRange(factory2.createAssignment(name, value), location))) : preventSubstitution(setTextRange(factory2.createAssignment(name, value), location));
  }
  function appendExportsOfImportDeclaration(statements, decl) {
    if (moduleInfo.exportEquals) {
      return statements;
    }
    const importClause = decl.importClause;
    if (!importClause) {
      return statements;
    }
    if (importClause.name) {
      statements = appendExportsOfDeclaration(statements, importClause);
    }
    const namedBindings = importClause.namedBindings;
    if (namedBindings) {
      switch (namedBindings.kind) {
        case 274 /* NamespaceImport */:
          statements = appendExportsOfDeclaration(statements, namedBindings);
          break;
        case 275 /* NamedImports */:
          for (const importBinding of namedBindings.elements) {
            statements = appendExportsOfDeclaration(statements, importBinding);
          }
          break;
      }
    }
    return statements;
  }
  function appendExportsOfImportEqualsDeclaration(statements, decl) {
    if (moduleInfo.exportEquals) {
      return statements;
    }
    return appendExportsOfDeclaration(statements, decl);
  }
  function appendExportsOfVariableStatement(statements, node, exportSelf) {
    if (moduleInfo.exportEquals) {
      return statements;
    }
    for (const decl of node.declarationList.declarations) {
      if (decl.initializer || exportSelf) {
        statements = appendExportsOfBindingElement(statements, decl, exportSelf);
      }
    }
    return statements;
  }
  function appendExportsOfBindingElement(statements, decl, exportSelf) {
    if (moduleInfo.exportEquals) {
      return statements;
    }
    if (isBindingPattern(decl.name)) {
      for (const element of decl.name.elements) {
        if (!isOmittedExpression(element)) {
          statements = appendExportsOfBindingElement(statements, element, exportSelf);
        }
      }
    } else if (!isGeneratedIdentifier(decl.name)) {
      let excludeName;
      if (exportSelf) {
        statements = appendExportStatement(statements, decl.name, factory2.getLocalName(decl));
        excludeName = idText(decl.name);
      }
      statements = appendExportsOfDeclaration(statements, decl, excludeName);
    }
    return statements;
  }
  function appendExportsOfHoistedDeclaration(statements, decl) {
    if (moduleInfo.exportEquals) {
      return statements;
    }
    let excludeName;
    if (hasSyntacticModifier(decl, 32 /* Export */)) {
      const exportName = hasSyntacticModifier(decl, 2048 /* Default */) ? factory2.createStringLiteral("default") : decl.name;
      statements = appendExportStatement(statements, exportName, factory2.getLocalName(decl));
      excludeName = getTextOfIdentifierOrLiteral(exportName);
    }
    if (decl.name) {
      statements = appendExportsOfDeclaration(statements, decl, excludeName);
    }
    return statements;
  }
  function appendExportsOfDeclaration(statements, decl, excludeName) {
    if (moduleInfo.exportEquals) {
      return statements;
    }
    const name = factory2.getDeclarationName(decl);
    const exportSpecifiers = moduleInfo.exportSpecifiers.get(name);
    if (exportSpecifiers) {
      for (const exportSpecifier of exportSpecifiers) {
        if (exportSpecifier.name.escapedText !== excludeName) {
          statements = appendExportStatement(statements, exportSpecifier.name, name);
        }
      }
    }
    return statements;
  }
  function appendExportStatement(statements, exportName, expression, allowComments) {
    statements = append(statements, createExportStatement(exportName, expression, allowComments));
    return statements;
  }
  function createExportStatement(name, value, allowComments) {
    const statement = factory2.createExpressionStatement(createExportExpression(name, value));
    startOnNewLine(statement);
    if (!allowComments) {
      setEmitFlags(statement, 3072 /* NoComments */);
    }
    return statement;
  }
  function createExportExpression(name, value) {
    const exportName = isIdentifier(name) ? factory2.createStringLiteralFromNode(name) : name;
    setEmitFlags(value, getEmitFlags(value) | 3072 /* NoComments */);
    return setCommentRange(factory2.createCallExpression(
      exportFunction,
      /*typeArguments*/
      void 0,
      [exportName, value]
    ), value);
  }
  function topLevelNestedVisitor(node) {
    switch (node.kind) {
      case 243 /* VariableStatement */:
        return visitVariableStatement(node);
      case 262 /* FunctionDeclaration */:
        return visitFunctionDeclaration(node);
      case 263 /* ClassDeclaration */:
        return visitClassDeclaration(node);
      case 248 /* ForStatement */:
        return visitForStatement(
          node,
          /*isTopLevel*/
          true
        );
      case 249 /* ForInStatement */:
        return visitForInStatement(node);
      case 250 /* ForOfStatement */:
        return visitForOfStatement(node);
      case 246 /* DoStatement */:
        return visitDoStatement(node);
      case 247 /* WhileStatement */:
        return visitWhileStatement(node);
      case 256 /* LabeledStatement */:
        return visitLabeledStatement(node);
      case 254 /* WithStatement */:
        return visitWithStatement(node);
      case 245 /* IfStatement */:
        return visitIfStatement(node);
      case 255 /* SwitchStatement */:
        return visitSwitchStatement(node);
      case 269 /* CaseBlock */:
        return visitCaseBlock(node);
      case 296 /* CaseClause */:
        return visitCaseClause(node);
      case 297 /* DefaultClause */:
        return visitDefaultClause(node);
      case 258 /* TryStatement */:
        return visitTryStatement(node);
      case 299 /* CatchClause */:
        return visitCatchClause(node);
      case 241 /* Block */:
        return visitBlock(node);
      default:
        return visitor(node);
    }
  }
  function visitForStatement(node, isTopLevel) {
    const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
    enclosingBlockScopedContainer = node;
    node = factory2.updateForStatement(
      node,
      visitNode(node.initializer, isTopLevel ? visitForInitializer : discardedValueVisitor, isForInitializer),
      visitNode(node.condition, visitor, isExpression),
      visitNode(node.incrementor, discardedValueVisitor, isExpression),
      visitIterationBody(node.statement, isTopLevel ? topLevelNestedVisitor : visitor, context)
    );
    enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
    return node;
  }
  function visitForInStatement(node) {
    const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
    enclosingBlockScopedContainer = node;
    node = factory2.updateForInStatement(
      node,
      visitForInitializer(node.initializer),
      visitNode(node.expression, visitor, isExpression),
      visitIterationBody(node.statement, topLevelNestedVisitor, context)
    );
    enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
    return node;
  }
  function visitForOfStatement(node) {
    const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
    enclosingBlockScopedContainer = node;
    node = factory2.updateForOfStatement(
      node,
      node.awaitModifier,
      visitForInitializer(node.initializer),
      visitNode(node.expression, visitor, isExpression),
      visitIterationBody(node.statement, topLevelNestedVisitor, context)
    );
    enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
    return node;
  }
  function shouldHoistForInitializer(node) {
    return isVariableDeclarationList(node) && shouldHoistVariableDeclarationList(node);
  }
  function visitForInitializer(node) {
    if (shouldHoistForInitializer(node)) {
      let expressions;
      for (const variable of node.declarations) {
        expressions = append(expressions, transformInitializedVariable(
          variable,
          /*isExportedDeclaration*/
          false
        ));
        if (!variable.initializer) {
          hoistBindingElement(variable);
        }
      }
      return expressions ? factory2.inlineExpressions(expressions) : factory2.createOmittedExpression();
    } else {
      return visitNode(node, discardedValueVisitor, isForInitializer);
    }
  }
  function visitDoStatement(node) {
    return factory2.updateDoStatement(
      node,
      visitIterationBody(node.statement, topLevelNestedVisitor, context),
      visitNode(node.expression, visitor, isExpression)
    );
  }
  function visitWhileStatement(node) {
    return factory2.updateWhileStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      visitIterationBody(node.statement, topLevelNestedVisitor, context)
    );
  }
  function visitLabeledStatement(node) {
    return factory2.updateLabeledStatement(
      node,
      node.label,
      Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory2.liftToBlock))
    );
  }
  function visitWithStatement(node) {
    return factory2.updateWithStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory2.liftToBlock))
    );
  }
  function visitIfStatement(node) {
    return factory2.updateIfStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      Debug.checkDefined(visitNode(node.thenStatement, topLevelNestedVisitor, isStatement, factory2.liftToBlock)),
      visitNode(node.elseStatement, topLevelNestedVisitor, isStatement, factory2.liftToBlock)
    );
  }
  function visitSwitchStatement(node) {
    return factory2.updateSwitchStatement(
      node,
      visitNode(node.expression, visitor, isExpression),
      Debug.checkDefined(visitNode(node.caseBlock, topLevelNestedVisitor, isCaseBlock))
    );
  }
  function visitCaseBlock(node) {
    const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
    enclosingBlockScopedContainer = node;
    node = factory2.updateCaseBlock(
      node,
      visitNodes2(node.clauses, topLevelNestedVisitor, isCaseOrDefaultClause)
    );
    enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
    return node;
  }
  function visitCaseClause(node) {
    return factory2.updateCaseClause(
      node,
      visitNode(node.expression, visitor, isExpression),
      visitNodes2(node.statements, topLevelNestedVisitor, isStatement)
    );
  }
  function visitDefaultClause(node) {
    return visitEachChild(node, topLevelNestedVisitor, context);
  }
  function visitTryStatement(node) {
    return visitEachChild(node, topLevelNestedVisitor, context);
  }
  function visitCatchClause(node) {
    const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
    enclosingBlockScopedContainer = node;
    node = factory2.updateCatchClause(
      node,
      node.variableDeclaration,
      Debug.checkDefined(visitNode(node.block, topLevelNestedVisitor, isBlock))
    );
    enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
    return node;
  }
  function visitBlock(node) {
    const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
    enclosingBlockScopedContainer = node;
    node = visitEachChild(node, topLevelNestedVisitor, context);
    enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
    return node;
  }
  function visitorWorker(node, valueIsDiscarded) {
    if (!(node.transformFlags & (4096 /* ContainsDestructuringAssignment */ | 8388608 /* ContainsDynamicImport */ | 268435456 /* ContainsUpdateExpressionForIdentifier */))) {
      return node;
    }
    switch (node.kind) {
      case 248 /* ForStatement */:
        return visitForStatement(
          node,
          /*isTopLevel*/
          false
        );
      case 244 /* ExpressionStatement */:
        return visitExpressionStatement(node);
      case 217 /* ParenthesizedExpression */:
        return visitParenthesizedExpression(node, valueIsDiscarded);
      case 354 /* PartiallyEmittedExpression */:
        return visitPartiallyEmittedExpression(node, valueIsDiscarded);
      case 226 /* BinaryExpression */:
        if (isDestructuringAssignment(node)) {
          return visitDestructuringAssignment(node, valueIsDiscarded);
        }
        break;
      case 213 /* CallExpression */:
        if (isImportCall(node)) {
          return visitImportCallExpression(node);
        }
        break;
      case 224 /* PrefixUnaryExpression */:
      case 225 /* PostfixUnaryExpression */:
        return visitPrefixOrPostfixUnaryExpression(node, valueIsDiscarded);
    }
    return visitEachChild(node, visitor, context);
  }
  function visitor(node) {
    return visitorWorker(
      node,
      /*valueIsDiscarded*/
      false
    );
  }
  function discardedValueVisitor(node) {
    return visitorWorker(
      node,
      /*valueIsDiscarded*/
      true
    );
  }
  function visitExpressionStatement(node) {
    return factory2.updateExpressionStatement(node, visitNode(node.expression, discardedValueVisitor, isExpression));
  }
  function visitParenthesizedExpression(node, valueIsDiscarded) {
    return factory2.updateParenthesizedExpression(node, visitNode(node.expression, valueIsDiscarded ? discardedValueVisitor : visitor, isExpression));
  }
  function visitPartiallyEmittedExpression(node, valueIsDiscarded) {
    return factory2.updatePartiallyEmittedExpression(node, visitNode(node.expression, valueIsDiscarded ? discardedValueVisitor : visitor, isExpression));
  }
  function visitImportCallExpression(node) {
    const externalModuleName = getExternalModuleNameLiteral(factory2, node, currentSourceFile, host, resolver, compilerOptions);
    const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor, isExpression);
    const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName : firstArgument;
    return factory2.createCallExpression(
      factory2.createPropertyAccessExpression(
        contextObject,
        factory2.createIdentifier("import")
      ),
      /*typeArguments*/
      void 0,
      argument ? [argument] : []
    );
  }
  function visitDestructuringAssignment(node, valueIsDiscarded) {
    if (hasExportedReferenceInDestructuringTarget(node.left)) {
      return flattenDestructuringAssignment(
        node,
        visitor,
        context,
        0 /* All */,
        !valueIsDiscarded
      );
    }
    return visitEachChild(node, visitor, context);
  }
  function hasExportedReferenceInDestructuringTarget(node) {
    if (isAssignmentExpression(
      node,
      /*excludeCompoundAssignment*/
      true
    )) {
      return hasExportedReferenceInDestructuringTarget(node.left);
    } else if (isSpreadElement(node)) {
      return hasExportedReferenceInDestructuringTarget(node.expression);
    } else if (isObjectLiteralExpression(node)) {
      return some(node.properties, hasExportedReferenceInDestructuringTarget);
    } else if (isArrayLiteralExpression(node)) {
      return some(node.elements, hasExportedReferenceInDestructuringTarget);
    } else if (isShorthandPropertyAssignment(node)) {
      return hasExportedReferenceInDestructuringTarget(node.name);
    } else if (isPropertyAssignment(node)) {
      return hasExportedReferenceInDestructuringTarget(node.initializer);
    } else if (isIdentifier(node)) {
      const container = resolver.getReferencedExportContainer(node);
      return container !== void 0 && container.kind === 307 /* SourceFile */;
    } else {
      return false;
    }
  }
  function visitPrefixOrPostfixUnaryExpression(node, valueIsDiscarded) {
    if ((node.operator === 46 /* PlusPlusToken */ || node.operator === 47 /* MinusMinusToken */) && isIdentifier(node.operand) && !isGeneratedIdentifier(node.operand) && !isLocalName(node.operand) && !isDeclarationNameOfEnumOrNamespace(node.operand)) {
      const exportedNames = getExports(node.operand);
      if (exportedNames) {
        let temp;
        let expression = visitNode(node.operand, visitor, isExpression);
        if (isPrefixUnaryExpression(node)) {
          expression = factory2.updatePrefixUnaryExpression(node, expression);
        } else {
          expression = factory2.updatePostfixUnaryExpression(node, expression);
          if (!valueIsDiscarded) {
            temp = factory2.createTempVariable(hoistVariableDeclaration);
            expression = factory2.createAssignment(temp, expression);
            setTextRange(expression, node);
          }
          expression = factory2.createComma(expression, factory2.cloneNode(node.operand));
          setTextRange(expression, node);
        }
        for (const exportName of exportedNames) {
          expression = createExportExpression(exportName, preventSubstitution(expression));
        }
        if (temp) {
          expression = factory2.createComma(expression, temp);
          setTextRange(expression, node);
        }
        return expression;
      }
    }
    return visitEachChild(node, visitor, context);
  }
  function modifierVisitor(node) {
    switch (node.kind) {
      case 95 /* ExportKeyword */:
      case 90 /* DefaultKeyword */:
        return void 0;
    }
    return node;
  }
  function onEmitNode(hint, node, emitCallback) {
    if (node.kind === 307 /* SourceFile */) {
      const id = getOriginalNodeId(node);
      currentSourceFile = node;
      moduleInfo = moduleInfoMap[id];
      exportFunction = exportFunctionsMap[id];
      noSubstitution = noSubstitutionMap[id];
      contextObject = contextObjectMap[id];
      if (noSubstitution) {
        delete noSubstitutionMap[id];
      }
      previousOnEmitNode(hint, node, emitCallback);
      currentSourceFile = void 0;
      moduleInfo = void 0;
      exportFunction = void 0;
      contextObject = void 0;
      noSubstitution = void 0;
    } else {
      previousOnEmitNode(hint, node, emitCallback);
    }
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (isSubstitutionPrevented(node)) {
      return node;
    }
    if (hint === 1 /* Expression */) {
      return substituteExpression(node);
    } else if (hint === 4 /* Unspecified */) {
      return substituteUnspecified(node);
    }
    return node;
  }
  function substituteUnspecified(node) {
    switch (node.kind) {
      case 304 /* ShorthandPropertyAssignment */:
        return substituteShorthandPropertyAssignment(node);
    }
    return node;
  }
  function substituteShorthandPropertyAssignment(node) {
    var _a, _b;
    const name = node.name;
    if (!isGeneratedIdentifier(name) && !isLocalName(name)) {
      const importDeclaration = resolver.getReferencedImportDeclaration(name);
      if (importDeclaration) {
        if (isImportClause(importDeclaration)) {
          return setTextRange(
            factory2.createPropertyAssignment(
              factory2.cloneNode(name),
              factory2.createPropertyAccessExpression(
                factory2.getGeneratedNameForNode(importDeclaration.parent),
                factory2.createIdentifier("default")
              )
            ),
            /*location*/
            node
          );
        } else if (isImportSpecifier(importDeclaration)) {
          return setTextRange(
            factory2.createPropertyAssignment(
              factory2.cloneNode(name),
              factory2.createPropertyAccessExpression(
                factory2.getGeneratedNameForNode(((_b = (_a = importDeclaration.parent) == null ? void 0 : _a.parent) == null ? void 0 : _b.parent) || importDeclaration),
                factory2.cloneNode(importDeclaration.propertyName || importDeclaration.name)
              )
            ),
            /*location*/
            node
          );
        }
      }
    }
    return node;
  }
  function substituteExpression(node) {
    switch (node.kind) {
      case 80 /* Identifier */:
        return substituteExpressionIdentifier(node);
      case 226 /* BinaryExpression */:
        return substituteBinaryExpression(node);
      case 236 /* MetaProperty */:
        return substituteMetaProperty(node);
    }
    return node;
  }
  function substituteExpressionIdentifier(node) {
    var _a, _b;
    if (getEmitFlags(node) & 8192 /* HelperName */) {
      const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile);
      if (externalHelpersModuleName) {
        return factory2.createPropertyAccessExpression(externalHelpersModuleName, node);
      }
      return node;
    }
    if (!isGeneratedIdentifier(node) && !isLocalName(node)) {
      const importDeclaration = resolver.getReferencedImportDeclaration(node);
      if (importDeclaration) {
        if (isImportClause(importDeclaration)) {
          return setTextRange(
            factory2.createPropertyAccessExpression(
              factory2.getGeneratedNameForNode(importDeclaration.parent),
              factory2.createIdentifier("default")
            ),
            /*location*/
            node
          );
        } else if (isImportSpecifier(importDeclaration)) {
          return setTextRange(
            factory2.createPropertyAccessExpression(
              factory2.getGeneratedNameForNode(((_b = (_a = importDeclaration.parent) == null ? void 0 : _a.parent) == null ? void 0 : _b.parent) || importDeclaration),
              factory2.cloneNode(importDeclaration.propertyName || importDeclaration.name)
            ),
            /*location*/
            node
          );
        }
      }
    }
    return node;
  }
  function substituteBinaryExpression(node) {
    if (isAssignmentOperator(node.operatorToken.kind) && isIdentifier(node.left) && (!isGeneratedIdentifier(node.left) || isFileLevelReservedGeneratedIdentifier(node.left)) && !isLocalName(node.left)) {
      const exportedNames = getExports(node.left);
      if (exportedNames) {
        let expression = node;
        for (const exportName of exportedNames) {
          expression = createExportExpression(exportName, preventSubstitution(expression));
        }
        return expression;
      }
    }
    return node;
  }
  function substituteMetaProperty(node) {
    if (isImportMeta(node)) {
      return factory2.createPropertyAccessExpression(contextObject, factory2.createIdentifier("meta"));
    }
    return node;
  }
  function getExports(name) {
    let exportedNames;
    const valueDeclaration = getReferencedDeclaration(name);
    if (valueDeclaration) {
      const exportContainer = resolver.getReferencedExportContainer(
        name,
        /*prefixLocals*/
        false
      );
      if (exportContainer && exportContainer.kind === 307 /* SourceFile */) {
        exportedNames = append(exportedNames, factory2.getDeclarationName(valueDeclaration));
      }
      exportedNames = addRange(exportedNames, moduleInfo == null ? void 0 : moduleInfo.exportedBindings[getOriginalNodeId(valueDeclaration)]);
    } else if (isGeneratedIdentifier(name) && isFileLevelReservedGeneratedIdentifier(name)) {
      const exportSpecifiers = moduleInfo == null ? void 0 : moduleInfo.exportSpecifiers.get(name);
      if (exportSpecifiers) {
        const exportedNames2 = [];
        for (const exportSpecifier of exportSpecifiers) {
          exportedNames2.push(exportSpecifier.name);
        }
        return exportedNames2;
      }
    }
    return exportedNames;
  }
  function getReferencedDeclaration(name) {
    if (!isGeneratedIdentifier(name)) {
      const importDeclaration = resolver.getReferencedImportDeclaration(name);
      if (importDeclaration) return importDeclaration;
      const valueDeclaration = resolver.getReferencedValueDeclaration(name);
      if (valueDeclaration && (moduleInfo == null ? void 0 : moduleInfo.exportedBindings[getOriginalNodeId(valueDeclaration)])) return valueDeclaration;
      const declarations = resolver.getReferencedValueDeclarations(name);
      if (declarations) {
        for (const declaration of declarations) {
          if (declaration !== valueDeclaration && (moduleInfo == null ? void 0 : moduleInfo.exportedBindings[getOriginalNodeId(declaration)])) return declaration;
        }
      }
      return valueDeclaration;
    }
  }
  function preventSubstitution(node) {
    if (noSubstitution === void 0) noSubstitution = [];
    noSubstitution[getNodeId(node)] = true;
    return node;
  }
  function isSubstitutionPrevented(node) {
    return noSubstitution && node.id && noSubstitution[node.id];
  }
}

// src/compiler/transformers/module/esnextAnd2015.ts
function transformECMAScriptModule(context) {
  const {
    factory: factory2,
    getEmitHelperFactory: emitHelpers
  } = context;
  const host = context.getEmitHost();
  const resolver = context.getEmitResolver();
  const compilerOptions = context.getCompilerOptions();
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const previousOnEmitNode = context.onEmitNode;
  const previousOnSubstituteNode = context.onSubstituteNode;
  context.onEmitNode = onEmitNode;
  context.onSubstituteNode = onSubstituteNode;
  context.enableEmitNotification(307 /* SourceFile */);
  context.enableSubstitution(80 /* Identifier */);
  let helperNameSubstitutions;
  let currentSourceFile;
  let importRequireStatements;
  return chainBundle(context, transformSourceFile);
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    if (isExternalModule(node) || getIsolatedModules(compilerOptions)) {
      currentSourceFile = node;
      importRequireStatements = void 0;
      let result = updateExternalModule(node);
      currentSourceFile = void 0;
      if (importRequireStatements) {
        result = factory2.updateSourceFile(
          result,
          setTextRange(factory2.createNodeArray(insertStatementsAfterCustomPrologue(result.statements.slice(), importRequireStatements)), result.statements)
        );
      }
      if (!isExternalModule(node) || getEmitModuleKind(compilerOptions) === 200 /* Preserve */ || some(result.statements, isExternalModuleIndicator)) {
        return result;
      }
      return factory2.updateSourceFile(
        result,
        setTextRange(factory2.createNodeArray([...result.statements, createEmptyExports(factory2)]), result.statements)
      );
    }
    return node;
  }
  function updateExternalModule(node) {
    const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(factory2, emitHelpers(), node, compilerOptions);
    if (externalHelpersImportDeclaration) {
      const statements = [];
      const statementOffset = factory2.copyPrologue(node.statements, statements);
      append(statements, externalHelpersImportDeclaration);
      addRange(statements, visitNodes2(node.statements, visitor, isStatement, statementOffset));
      return factory2.updateSourceFile(
        node,
        setTextRange(factory2.createNodeArray(statements), node.statements)
      );
    } else {
      return visitEachChild(node, visitor, context);
    }
  }
  function visitor(node) {
    switch (node.kind) {
      case 271 /* ImportEqualsDeclaration */:
        return getEmitModuleKind(compilerOptions) >= 100 /* Node16 */ ? visitImportEqualsDeclaration(node) : void 0;
      case 277 /* ExportAssignment */:
        return visitExportAssignment(node);
      case 278 /* ExportDeclaration */:
        const exportDecl = node;
        return visitExportDeclaration(exportDecl);
    }
    return node;
  }
  function createRequireCall(importNode) {
    const moduleName = getExternalModuleNameLiteral(factory2, importNode, Debug.checkDefined(currentSourceFile), host, resolver, compilerOptions);
    const args = [];
    if (moduleName) {
      args.push(moduleName);
    }
    if (getEmitModuleKind(compilerOptions) === 200 /* Preserve */) {
      return factory2.createCallExpression(
        factory2.createIdentifier("require"),
        /*typeArguments*/
        void 0,
        args
      );
    }
    if (!importRequireStatements) {
      const createRequireName = factory2.createUniqueName("_createRequire", 16 /* Optimistic */ | 32 /* FileLevel */);
      const importStatement = factory2.createImportDeclaration(
        /*modifiers*/
        void 0,
        factory2.createImportClause(
          /*isTypeOnly*/
          false,
          /*name*/
          void 0,
          factory2.createNamedImports([
            factory2.createImportSpecifier(
              /*isTypeOnly*/
              false,
              factory2.createIdentifier("createRequire"),
              createRequireName
            )
          ])
        ),
        factory2.createStringLiteral("module"),
        /*attributes*/
        void 0
      );
      const requireHelperName = factory2.createUniqueName("__require", 16 /* Optimistic */ | 32 /* FileLevel */);
      const requireStatement = factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList(
          [
            factory2.createVariableDeclaration(
              requireHelperName,
              /*exclamationToken*/
              void 0,
              /*type*/
              void 0,
              factory2.createCallExpression(
                factory2.cloneNode(createRequireName),
                /*typeArguments*/
                void 0,
                [
                  factory2.createPropertyAccessExpression(factory2.createMetaProperty(102 /* ImportKeyword */, factory2.createIdentifier("meta")), factory2.createIdentifier("url"))
                ]
              )
            )
          ],
          /*flags*/
          languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */
        )
      );
      importRequireStatements = [importStatement, requireStatement];
    }
    const name = importRequireStatements[1].declarationList.declarations[0].name;
    Debug.assertNode(name, isIdentifier);
    return factory2.createCallExpression(
      factory2.cloneNode(name),
      /*typeArguments*/
      void 0,
      args
    );
  }
  function visitImportEqualsDeclaration(node) {
    Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
    let statements;
    statements = append(
      statements,
      setOriginalNode(
        setTextRange(
          factory2.createVariableStatement(
            /*modifiers*/
            void 0,
            factory2.createVariableDeclarationList(
              [
                factory2.createVariableDeclaration(
                  factory2.cloneNode(node.name),
                  /*exclamationToken*/
                  void 0,
                  /*type*/
                  void 0,
                  createRequireCall(node)
                )
              ],
              /*flags*/
              languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */
            )
          ),
          node
        ),
        node
      )
    );
    statements = appendExportsOfImportEqualsDeclaration(statements, node);
    return singleOrMany(statements);
  }
  function appendExportsOfImportEqualsDeclaration(statements, node) {
    if (hasSyntacticModifier(node, 32 /* Export */)) {
      statements = append(
        statements,
        factory2.createExportDeclaration(
          /*modifiers*/
          void 0,
          node.isTypeOnly,
          factory2.createNamedExports([factory2.createExportSpecifier(
            /*isTypeOnly*/
            false,
            /*propertyName*/
            void 0,
            idText(node.name)
          )])
        )
      );
    }
    return statements;
  }
  function visitExportAssignment(node) {
    if (node.isExportEquals) {
      if (getEmitModuleKind(compilerOptions) === 200 /* Preserve */) {
        const statement = setOriginalNode(
          factory2.createExpressionStatement(
            factory2.createAssignment(
              factory2.createPropertyAccessExpression(
                factory2.createIdentifier("module"),
                "exports"
              ),
              node.expression
            )
          ),
          node
        );
        return statement;
      }
      return void 0;
    }
    return node;
  }
  function visitExportDeclaration(node) {
    if (compilerOptions.module !== void 0 && compilerOptions.module > 5 /* ES2015 */) {
      return node;
    }
    if (!node.exportClause || !isNamespaceExport(node.exportClause) || !node.moduleSpecifier) {
      return node;
    }
    const oldIdentifier = node.exportClause.name;
    const synthName = factory2.getGeneratedNameForNode(oldIdentifier);
    const importDecl = factory2.createImportDeclaration(
      /*modifiers*/
      void 0,
      factory2.createImportClause(
        /*isTypeOnly*/
        false,
        /*name*/
        void 0,
        factory2.createNamespaceImport(
          synthName
        )
      ),
      node.moduleSpecifier,
      node.attributes
    );
    setOriginalNode(importDecl, node.exportClause);
    const exportDecl = isExportNamespaceAsDefaultDeclaration(node) ? factory2.createExportDefault(synthName) : factory2.createExportDeclaration(
      /*modifiers*/
      void 0,
      /*isTypeOnly*/
      false,
      factory2.createNamedExports([factory2.createExportSpecifier(
        /*isTypeOnly*/
        false,
        synthName,
        oldIdentifier
      )])
    );
    setOriginalNode(exportDecl, node);
    return [importDecl, exportDecl];
  }
  function onEmitNode(hint, node, emitCallback) {
    if (isSourceFile(node)) {
      if ((isExternalModule(node) || getIsolatedModules(compilerOptions)) && compilerOptions.importHelpers) {
        helperNameSubstitutions = /* @__PURE__ */ new Map();
      }
      previousOnEmitNode(hint, node, emitCallback);
      helperNameSubstitutions = void 0;
    } else {
      previousOnEmitNode(hint, node, emitCallback);
    }
  }
  function onSubstituteNode(hint, node) {
    node = previousOnSubstituteNode(hint, node);
    if (helperNameSubstitutions && isIdentifier(node) && getEmitFlags(node) & 8192 /* HelperName */) {
      return substituteHelperName(node);
    }
    return node;
  }
  function substituteHelperName(node) {
    const name = idText(node);
    let substitution = helperNameSubstitutions.get(name);
    if (!substitution) {
      helperNameSubstitutions.set(name, substitution = factory2.createUniqueName(name, 16 /* Optimistic */ | 32 /* FileLevel */));
    }
    return substitution;
  }
}

// src/compiler/transformers/module/node.ts
function transformNodeModule(context) {
  const previousOnSubstituteNode = context.onSubstituteNode;
  const previousOnEmitNode = context.onEmitNode;
  const esmTransform = transformECMAScriptModule(context);
  const esmOnSubstituteNode = context.onSubstituteNode;
  const esmOnEmitNode = context.onEmitNode;
  context.onSubstituteNode = previousOnSubstituteNode;
  context.onEmitNode = previousOnEmitNode;
  const cjsTransform = transformModule(context);
  const cjsOnSubstituteNode = context.onSubstituteNode;
  const cjsOnEmitNode = context.onEmitNode;
  context.onSubstituteNode = onSubstituteNode;
  context.onEmitNode = onEmitNode;
  context.enableSubstitution(307 /* SourceFile */);
  context.enableEmitNotification(307 /* SourceFile */);
  let currentSourceFile;
  return transformSourceFileOrBundle;
  function onSubstituteNode(hint, node) {
    if (isSourceFile(node)) {
      currentSourceFile = node;
      return previousOnSubstituteNode(hint, node);
    } else {
      if (!currentSourceFile) {
        return previousOnSubstituteNode(hint, node);
      }
      if (currentSourceFile.impliedNodeFormat === 99 /* ESNext */) {
        return esmOnSubstituteNode(hint, node);
      }
      return cjsOnSubstituteNode(hint, node);
    }
  }
  function onEmitNode(hint, node, emitCallback) {
    if (isSourceFile(node)) {
      currentSourceFile = node;
    }
    if (!currentSourceFile) {
      return previousOnEmitNode(hint, node, emitCallback);
    }
    if (currentSourceFile.impliedNodeFormat === 99 /* ESNext */) {
      return esmOnEmitNode(hint, node, emitCallback);
    }
    return cjsOnEmitNode(hint, node, emitCallback);
  }
  function getModuleTransformForFile(file) {
    return file.impliedNodeFormat === 99 /* ESNext */ ? esmTransform : cjsTransform;
  }
  function transformSourceFile(node) {
    if (node.isDeclarationFile) {
      return node;
    }
    currentSourceFile = node;
    const result = getModuleTransformForFile(node)(node);
    currentSourceFile = void 0;
    Debug.assert(isSourceFile(result));
    return result;
  }
  function transformSourceFileOrBundle(node) {
    return node.kind === 307 /* SourceFile */ ? transformSourceFile(node) : transformBundle(node);
  }
  function transformBundle(node) {
    return context.factory.createBundle(map(node.sourceFiles, transformSourceFile));
  }
}

// src/compiler/transformers/declarations/diagnostics.ts
function canProduceDiagnostics(node) {
  return isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isBindingElement(node) || isSetAccessor(node) || isGetAccessor(node) || isConstructSignatureDeclaration(node) || isCallSignatureDeclaration(node) || isMethodDeclaration(node) || isMethodSignature(node) || isFunctionDeclaration(node) || isParameter(node) || isTypeParameterDeclaration(node) || isExpressionWithTypeArguments(node) || isImportEqualsDeclaration(node) || isTypeAliasDeclaration(node) || isConstructorDeclaration(node) || isIndexSignatureDeclaration(node) || isPropertyAccessExpression(node) || isElementAccessExpression(node) || isBinaryExpression(node) || isJSDocTypeAlias(node);
}
function createGetSymbolAccessibilityDiagnosticForNodeName(node) {
  if (isSetAccessor(node) || isGetAccessor(node)) {
    return getAccessorNameVisibilityError;
  } else if (isMethodSignature(node) || isMethodDeclaration(node)) {
    return getMethodNameVisibilityError;
  } else {
    return createGetSymbolAccessibilityDiagnosticForNode(node);
  }
  function getAccessorNameVisibilityError(symbolAccessibilityResult) {
    const diagnosticMessage = getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
    return diagnosticMessage !== void 0 ? {
      diagnosticMessage,
      errorNode: node,
      typeName: node.name
    } : void 0;
  }
  function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
    if (isStatic(node)) {
      return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
    } else if (node.parent.kind === 263 /* ClassDeclaration */) {
      return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
    } else {
      return symbolAccessibilityResult.errorModuleName ? Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
    }
  }
  function getMethodNameVisibilityError(symbolAccessibilityResult) {
    const diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
    return diagnosticMessage !== void 0 ? {
      diagnosticMessage,
      errorNode: node,
      typeName: node.name
    } : void 0;
  }
  function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
    if (isStatic(node)) {
      return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1;
    } else if (node.parent.kind === 263 /* ClassDeclaration */) {
      return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1;
    } else {
      return symbolAccessibilityResult.errorModuleName ? Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1;
    }
  }
}
function createGetSymbolAccessibilityDiagnosticForNode(node) {
  if (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isPropertyAccessExpression(node) || isElementAccessExpression(node) || isBinaryExpression(node) || isBindingElement(node) || isConstructorDeclaration(node)) {
    return getVariableDeclarationTypeVisibilityError;
  } else if (isSetAccessor(node) || isGetAccessor(node)) {
    return getAccessorDeclarationTypeVisibilityError;
  } else if (isConstructSignatureDeclaration(node) || isCallSignatureDeclaration(node) || isMethodDeclaration(node) || isMethodSignature(node) || isFunctionDeclaration(node) || isIndexSignatureDeclaration(node)) {
    return getReturnTypeVisibilityError;
  } else if (isParameter(node)) {
    if (isParameterPropertyDeclaration(node, node.parent) && hasSyntacticModifier(node.parent, 2 /* Private */)) {
      return getVariableDeclarationTypeVisibilityError;
    }
    return getParameterDeclarationTypeVisibilityError;
  } else if (isTypeParameterDeclaration(node)) {
    return getTypeParameterConstraintVisibilityError;
  } else if (isExpressionWithTypeArguments(node)) {
    return getHeritageClauseVisibilityError;
  } else if (isImportEqualsDeclaration(node)) {
    return getImportEntityNameVisibilityError;
  } else if (isTypeAliasDeclaration(node) || isJSDocTypeAlias(node)) {
    return getTypeAliasDeclarationVisibilityError;
  } else {
    return Debug.assertNever(node, `Attempted to set a declaration diagnostic context for unhandled node kind: ${Debug.formatSyntaxKind(node.kind)}`);
  }
  function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
    if (node.kind === 260 /* VariableDeclaration */ || node.kind === 208 /* BindingElement */) {
      return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
    } else if (node.kind === 172 /* PropertyDeclaration */ || node.kind === 211 /* PropertyAccessExpression */ || node.kind === 212 /* ElementAccessExpression */ || node.kind === 226 /* BinaryExpression */ || node.kind === 171 /* PropertySignature */ || node.kind === 169 /* Parameter */ && hasSyntacticModifier(node.parent, 2 /* Private */)) {
      if (isStatic(node)) {
        return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
      } else if (node.parent.kind === 263 /* ClassDeclaration */ || node.kind === 169 /* Parameter */) {
        return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
      } else {
        return symbolAccessibilityResult.errorModuleName ? Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
      }
    }
  }
  function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult) {
    const diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
    return diagnosticMessage !== void 0 ? {
      diagnosticMessage,
      errorNode: node,
      typeName: node.name
    } : void 0;
  }
  function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult) {
    let diagnosticMessage;
    if (node.kind === 178 /* SetAccessor */) {
      if (isStatic(node)) {
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1;
      } else {
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1;
      }
    } else {
      if (isStatic(node)) {
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1;
      } else {
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1;
      }
    }
    return {
      diagnosticMessage,
      errorNode: node.name,
      typeName: node.name
    };
  }
  function getReturnTypeVisibilityError(symbolAccessibilityResult) {
    let diagnosticMessage;
    switch (node.kind) {
      case 180 /* ConstructSignature */:
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
        break;
      case 179 /* CallSignature */:
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
        break;
      case 181 /* IndexSignature */:
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
        break;
      case 174 /* MethodDeclaration */:
      case 173 /* MethodSignature */:
        if (isStatic(node)) {
          diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
        } else if (node.parent.kind === 263 /* ClassDeclaration */) {
          diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
        } else {
          diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
        }
        break;
      case 262 /* FunctionDeclaration */:
        diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 : Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
        break;
      default:
        return Debug.fail("This is unknown kind for signature: " + node.kind);
    }
    return {
      diagnosticMessage,
      errorNode: node.name || node
    };
  }
  function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult) {
    const diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
    return diagnosticMessage !== void 0 ? {
      diagnosticMessage,
      errorNode: node,
      typeName: node.name
    } : void 0;
  }
  function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
    switch (node.parent.kind) {
      case 176 /* Constructor */:
        return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
      case 180 /* ConstructSignature */:
      case 185 /* ConstructorType */:
        return symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
      case 179 /* CallSignature */:
        return symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
      case 181 /* IndexSignature */:
        return symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
      case 174 /* MethodDeclaration */:
      case 173 /* MethodSignature */:
        if (isStatic(node.parent)) {
          return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
        } else if (node.parent.parent.kind === 263 /* ClassDeclaration */) {
          return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
        } else {
          return symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
        }
      case 262 /* FunctionDeclaration */:
      case 184 /* FunctionType */:
        return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
      case 178 /* SetAccessor */:
      case 177 /* GetAccessor */:
        return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_accessor_has_or_is_using_private_name_1;
      default:
        return Debug.fail(`Unknown parent for parameter: ${Debug.formatSyntaxKind(node.parent.kind)}`);
    }
  }
  function getTypeParameterConstraintVisibilityError() {
    let diagnosticMessage;
    switch (node.parent.kind) {
      case 263 /* ClassDeclaration */:
        diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
        break;
      case 264 /* InterfaceDeclaration */:
        diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
        break;
      case 200 /* MappedType */:
        diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1;
        break;
      case 185 /* ConstructorType */:
      case 180 /* ConstructSignature */:
        diagnosticMessage = Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
        break;
      case 179 /* CallSignature */:
        diagnosticMessage = Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
        break;
      case 174 /* MethodDeclaration */:
      case 173 /* MethodSignature */:
        if (isStatic(node.parent)) {
          diagnosticMessage = Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
        } else if (node.parent.parent.kind === 263 /* ClassDeclaration */) {
          diagnosticMessage = Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
        } else {
          diagnosticMessage = Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
        }
        break;
      case 184 /* FunctionType */:
      case 262 /* FunctionDeclaration */:
        diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
        break;
      case 195 /* InferType */:
        diagnosticMessage = Diagnostics.Extends_clause_for_inferred_type_0_has_or_is_using_private_name_1;
        break;
      case 265 /* TypeAliasDeclaration */:
        diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1;
        break;
      default:
        return Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
    }
    return {
      diagnosticMessage,
      errorNode: node,
      typeName: node.name
    };
  }
  function getHeritageClauseVisibilityError() {
    let diagnosticMessage;
    if (isClassDeclaration(node.parent.parent)) {
      diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === 119 /* ImplementsKeyword */ ? Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 : node.parent.parent.name ? Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1 : Diagnostics.extends_clause_of_exported_class_has_or_is_using_private_name_0;
    } else {
      diagnosticMessage = Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
    }
    return {
      diagnosticMessage,
      errorNode: node,
      typeName: getNameOfDeclaration(node.parent.parent)
    };
  }
  function getImportEntityNameVisibilityError() {
    return {
      diagnosticMessage: Diagnostics.Import_declaration_0_is_using_private_name_1,
      errorNode: node,
      typeName: node.name
    };
  }
  function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult) {
    return {
      diagnosticMessage: symbolAccessibilityResult.errorModuleName ? Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1_from_module_2 : Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
      errorNode: isJSDocTypeAlias(node) ? Debug.checkDefined(node.typeExpression) : node.type,
      typeName: isJSDocTypeAlias(node) ? getNameOfDeclaration(node) : node.name
    };
  }
}
function createGetIsolatedDeclarationErrors(resolver) {
  const relatedSuggestionByDeclarationKind = {
    [219 /* ArrowFunction */]: Diagnostics.Add_a_return_type_to_the_function_expression,
    [218 /* FunctionExpression */]: Diagnostics.Add_a_return_type_to_the_function_expression,
    [174 /* MethodDeclaration */]: Diagnostics.Add_a_return_type_to_the_method,
    [177 /* GetAccessor */]: Diagnostics.Add_a_return_type_to_the_get_accessor_declaration,
    [178 /* SetAccessor */]: Diagnostics.Add_a_type_to_parameter_of_the_set_accessor_declaration,
    [262 /* FunctionDeclaration */]: Diagnostics.Add_a_return_type_to_the_function_declaration,
    [180 /* ConstructSignature */]: Diagnostics.Add_a_return_type_to_the_function_declaration,
    [169 /* Parameter */]: Diagnostics.Add_a_type_annotation_to_the_parameter_0,
    [260 /* VariableDeclaration */]: Diagnostics.Add_a_type_annotation_to_the_variable_0,
    [172 /* PropertyDeclaration */]: Diagnostics.Add_a_type_annotation_to_the_property_0,
    [171 /* PropertySignature */]: Diagnostics.Add_a_type_annotation_to_the_property_0,
    [277 /* ExportAssignment */]: Diagnostics.Move_the_expression_in_default_export_to_a_variable_and_add_a_type_annotation_to_it
  };
  const errorByDeclarationKind = {
    [218 /* FunctionExpression */]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
    [262 /* FunctionDeclaration */]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
    [219 /* ArrowFunction */]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
    [174 /* MethodDeclaration */]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
    [180 /* ConstructSignature */]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
    [177 /* GetAccessor */]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
    [178 /* SetAccessor */]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
    [169 /* Parameter */]: Diagnostics.Parameter_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
    [260 /* VariableDeclaration */]: Diagnostics.Variable_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
    [172 /* PropertyDeclaration */]: Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
    [171 /* PropertySignature */]: Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
    [167 /* ComputedPropertyName */]: Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations,
    [305 /* SpreadAssignment */]: Diagnostics.Objects_that_contain_spread_assignments_can_t_be_inferred_with_isolatedDeclarations,
    [304 /* ShorthandPropertyAssignment */]: Diagnostics.Objects_that_contain_shorthand_properties_can_t_be_inferred_with_isolatedDeclarations,
    [209 /* ArrayLiteralExpression */]: Diagnostics.Only_const_arrays_can_be_inferred_with_isolatedDeclarations,
    [277 /* ExportAssignment */]: Diagnostics.Default_exports_can_t_be_inferred_with_isolatedDeclarations,
    [230 /* SpreadElement */]: Diagnostics.Arrays_with_spread_elements_can_t_inferred_with_isolatedDeclarations
  };
  return getDiagnostic;
  function getDiagnostic(node) {
    const heritageClause = findAncestor(node, isHeritageClause);
    if (heritageClause) {
      return createDiagnosticForNode(node, Diagnostics.Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations);
    }
    if ((isPartOfTypeNode(node) || isTypeQueryNode(node.parent)) && (isEntityName(node) || isEntityNameExpression(node))) {
      return createEntityInTypeNodeError(node);
    }
    Debug.type(node);
    switch (node.kind) {
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
        return createAccessorTypeError(node);
      case 167 /* ComputedPropertyName */:
      case 304 /* ShorthandPropertyAssignment */:
      case 305 /* SpreadAssignment */:
        return createObjectLiteralError(node);
      case 209 /* ArrayLiteralExpression */:
      case 230 /* SpreadElement */:
        return createArrayLiteralError(node);
      case 174 /* MethodDeclaration */:
      case 180 /* ConstructSignature */:
      case 218 /* FunctionExpression */:
      case 219 /* ArrowFunction */:
      case 262 /* FunctionDeclaration */:
        return createReturnTypeError(node);
      case 208 /* BindingElement */:
        return createBindingElementError(node);
      case 172 /* PropertyDeclaration */:
      case 260 /* VariableDeclaration */:
        return createVariableOrPropertyError(node);
      case 169 /* Parameter */:
        return createParameterError(node);
      case 303 /* PropertyAssignment */:
        return createExpressionError(node.initializer);
      case 231 /* ClassExpression */:
        return createClassExpressionError(node);
      default:
        assertType(node);
        return createExpressionError(node);
    }
  }
  function findNearestDeclaration(node) {
    const result = findAncestor(node, (n) => isExportAssignment(n) || isStatement(n) || isVariableDeclaration(n) || isPropertyDeclaration(n) || isParameter(n));
    if (!result) return void 0;
    if (isExportAssignment(result)) return result;
    if (isReturnStatement(result)) {
      return findAncestor(result, (n) => isFunctionLikeDeclaration(n) && !isConstructorDeclaration(n));
    }
    return isStatement(result) ? void 0 : result;
  }
  function createAccessorTypeError(node) {
    const { getAccessor, setAccessor } = getAllAccessorDeclarations(node.symbol.declarations, node);
    const targetNode = (isSetAccessor(node) ? node.parameters[0] : node) ?? node;
    const diag2 = createDiagnosticForNode(targetNode, errorByDeclarationKind[node.kind]);
    if (setAccessor) {
      addRelatedInfo(diag2, createDiagnosticForNode(setAccessor, relatedSuggestionByDeclarationKind[setAccessor.kind]));
    }
    if (getAccessor) {
      addRelatedInfo(diag2, createDiagnosticForNode(getAccessor, relatedSuggestionByDeclarationKind[getAccessor.kind]));
    }
    return diag2;
  }
  function addParentDeclarationRelatedInfo(node, diag2) {
    const parentDeclaration = findNearestDeclaration(node);
    if (parentDeclaration) {
      const targetStr = isExportAssignment(parentDeclaration) || !parentDeclaration.name ? "" : getTextOfNode(
        parentDeclaration.name,
        /*includeTrivia*/
        false
      );
      addRelatedInfo(diag2, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
    }
    return diag2;
  }
  function createObjectLiteralError(node) {
    const diag2 = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
    addParentDeclarationRelatedInfo(node, diag2);
    return diag2;
  }
  function createArrayLiteralError(node) {
    const diag2 = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
    addParentDeclarationRelatedInfo(node, diag2);
    return diag2;
  }
  function createReturnTypeError(node) {
    const diag2 = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
    addParentDeclarationRelatedInfo(node, diag2);
    addRelatedInfo(diag2, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind]));
    return diag2;
  }
  function createBindingElementError(node) {
    return createDiagnosticForNode(node, Diagnostics.Binding_elements_can_t_be_exported_directly_with_isolatedDeclarations);
  }
  function createVariableOrPropertyError(node) {
    const diag2 = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
    const targetStr = getTextOfNode(
      node.name,
      /*includeTrivia*/
      false
    );
    addRelatedInfo(diag2, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind], targetStr));
    return diag2;
  }
  function createParameterError(node) {
    if (isSetAccessor(node.parent)) {
      return createAccessorTypeError(node.parent);
    }
    const addUndefined = resolver.requiresAddingImplicitUndefined(node);
    if (!addUndefined && node.initializer) {
      return createExpressionError(node.initializer);
    }
    const message = addUndefined ? Diagnostics.Declaration_emit_for_this_parameter_requires_implicitly_adding_undefined_to_it_s_type_This_is_not_supported_with_isolatedDeclarations : errorByDeclarationKind[node.kind];
    const diag2 = createDiagnosticForNode(node, message);
    const targetStr = getTextOfNode(
      node.name,
      /*includeTrivia*/
      false
    );
    addRelatedInfo(diag2, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind], targetStr));
    return diag2;
  }
  function createClassExpressionError(node) {
    return createExpressionError(node, Diagnostics.Inference_from_class_expressions_is_not_supported_with_isolatedDeclarations);
  }
  function createEntityInTypeNodeError(node) {
    const diag2 = createDiagnosticForNode(node, Diagnostics.Type_containing_private_name_0_can_t_be_used_with_isolatedDeclarations, getTextOfNode(
      node,
      /*includeTrivia*/
      false
    ));
    addParentDeclarationRelatedInfo(node, diag2);
    return diag2;
  }
  function createExpressionError(node, diagnosticMessage) {
    const parentDeclaration = findNearestDeclaration(node);
    let diag2;
    if (parentDeclaration) {
      const targetStr = isExportAssignment(parentDeclaration) || !parentDeclaration.name ? "" : getTextOfNode(
        parentDeclaration.name,
        /*includeTrivia*/
        false
      );
      const parent = findAncestor(node.parent, (n) => isExportAssignment(n) || (isStatement(n) ? "quit" : !isParenthesizedExpression(n) && !isTypeAssertionExpression(n) && !isAsExpression(n)));
      if (parentDeclaration === parent) {
        diag2 = createDiagnosticForNode(node, diagnosticMessage ?? errorByDeclarationKind[parentDeclaration.kind]);
        addRelatedInfo(diag2, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
      } else {
        diag2 = createDiagnosticForNode(node, diagnosticMessage ?? Diagnostics.Expression_type_can_t_be_inferred_with_isolatedDeclarations);
        addRelatedInfo(diag2, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
        addRelatedInfo(diag2, createDiagnosticForNode(node, Diagnostics.Add_satisfies_and_a_type_assertion_to_this_expression_satisfies_T_as_T_to_make_the_type_explicit));
      }
    } else {
      diag2 = createDiagnosticForNode(node, diagnosticMessage ?? Diagnostics.Expression_type_can_t_be_inferred_with_isolatedDeclarations);
    }
    return diag2;
  }
}

// src/compiler/transformers/declarations.ts
function getDeclarationDiagnostics(host, resolver, file) {
  const compilerOptions = host.getCompilerOptions();
  const files = filter(getSourceFilesToEmit(host, file), isSourceFileNotJson);
  const result = transformNodes(
    resolver,
    host,
    factory,
    compilerOptions,
    file ? contains(files, file) ? [file] : emptyArray : files,
    [transformDeclarations],
    /*allowDtsFiles*/
    false
  );
  return result.diagnostics;
}
var declarationEmitNodeBuilderFlags = 1024 /* MultilineObjectLiterals */ | 2048 /* WriteClassExpressionAsTypeLiteral */ | 4096 /* UseTypeOfFunction */ | 8 /* UseStructuralFallback */ | 524288 /* AllowEmptyTuple */ | 1 /* AllowUnresolvedNames */ | 4 /* GenerateNamesForShadowedTypeParams */ | 1 /* NoTruncation */;
function transformDeclarations(context) {
  const throwDiagnostic = () => Debug.fail("Diagnostic emitted without context");
  let getSymbolAccessibilityDiagnostic = throwDiagnostic;
  let needsDeclare = true;
  let isBundledEmit = false;
  let resultHasExternalModuleIndicator = false;
  let needsScopeFixMarker = false;
  let resultHasScopeMarker = false;
  let enclosingDeclaration;
  let lateMarkedStatements;
  let lateStatementReplacementMap;
  let suppressNewDiagnosticContexts;
  const { factory: factory2 } = context;
  const host = context.getEmitHost();
  const symbolTracker = {
    trackSymbol,
    reportInaccessibleThisError,
    reportInaccessibleUniqueSymbolError,
    reportCyclicStructureError,
    reportPrivateInBaseOfClassExpression,
    reportLikelyUnsafeImportRequiredError,
    reportTruncationError,
    moduleResolverHost: host,
    reportNonlocalAugmentation,
    reportNonSerializableProperty,
    reportInferenceFallback
  };
  let errorNameNode;
  let errorFallbackNode;
  let currentSourceFile;
  let rawReferencedFiles;
  let rawTypeReferenceDirectives;
  let rawLibReferenceDirectives;
  const resolver = context.getEmitResolver();
  const options = context.getCompilerOptions();
  const getIsolatedDeclarationError = createGetIsolatedDeclarationErrors(resolver);
  const { stripInternal, isolatedDeclarations } = options;
  return transformRoot;
  function reportExpandoFunctionErrors(node) {
    resolver.getPropertiesOfContainerFunction(node).forEach((p) => {
      if (isExpandoPropertyDeclaration(p.valueDeclaration)) {
        const errorTarget = isBinaryExpression(p.valueDeclaration) ? p.valueDeclaration.left : p.valueDeclaration;
        context.addDiagnostic(createDiagnosticForNode(
          errorTarget,
          Diagnostics.Assigning_properties_to_functions_without_declaring_them_is_not_supported_with_isolatedDeclarations_Add_an_explicit_declaration_for_the_properties_assigned_to_this_function
        ));
      }
    });
  }
  function reportInferenceFallback(node) {
    if (!isolatedDeclarations || isSourceFileJS(currentSourceFile)) return;
    if (getSourceFileOfNode(node) !== currentSourceFile) return;
    if (isVariableDeclaration(node) && resolver.isExpandoFunctionDeclaration(node)) {
      reportExpandoFunctionErrors(node);
    } else {
      context.addDiagnostic(getIsolatedDeclarationError(node));
    }
  }
  function handleSymbolAccessibilityError(symbolAccessibilityResult) {
    if (symbolAccessibilityResult.accessibility === 0 /* Accessible */) {
      if (symbolAccessibilityResult.aliasesToMakeVisible) {
        if (!lateMarkedStatements) {
          lateMarkedStatements = symbolAccessibilityResult.aliasesToMakeVisible;
        } else {
          for (const ref of symbolAccessibilityResult.aliasesToMakeVisible) {
            pushIfUnique(lateMarkedStatements, ref);
          }
        }
      }
    } else if (symbolAccessibilityResult.accessibility !== 3 /* NotResolved */) {
      const errorInfo = getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
      if (errorInfo) {
        if (errorInfo.typeName) {
          context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, getTextOfNode(errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
        } else {
          context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
        }
        return true;
      }
    }
    return false;
  }
  function trackSymbol(symbol, enclosingDeclaration2, meaning) {
    if (symbol.flags & 262144 /* TypeParameter */) return false;
    const issuedDiagnostic = handleSymbolAccessibilityError(resolver.isSymbolAccessible(
      symbol,
      enclosingDeclaration2,
      meaning,
      /*shouldComputeAliasToMarkVisible*/
      true
    ));
    return issuedDiagnostic;
  }
  function reportPrivateInBaseOfClassExpression(propertyName) {
    if (errorNameNode || errorFallbackNode) {
      context.addDiagnostic(
        createDiagnosticForNode(errorNameNode || errorFallbackNode, Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName)
      );
    }
  }
  function errorDeclarationNameWithFallback() {
    return errorNameNode ? declarationNameToString(errorNameNode) : errorFallbackNode && getNameOfDeclaration(errorFallbackNode) ? declarationNameToString(getNameOfDeclaration(errorFallbackNode)) : errorFallbackNode && isExportAssignment(errorFallbackNode) ? errorFallbackNode.isExportEquals ? "export=" : "default" : "(Missing)";
  }
  function reportInaccessibleUniqueSymbolError() {
    if (errorNameNode || errorFallbackNode) {
      context.addDiagnostic(createDiagnosticForNode(errorNameNode || errorFallbackNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, errorDeclarationNameWithFallback(), "unique symbol"));
    }
  }
  function reportCyclicStructureError() {
    if (errorNameNode || errorFallbackNode) {
      context.addDiagnostic(createDiagnosticForNode(errorNameNode || errorFallbackNode, Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary, errorDeclarationNameWithFallback()));
    }
  }
  function reportInaccessibleThisError() {
    if (errorNameNode || errorFallbackNode) {
      context.addDiagnostic(createDiagnosticForNode(errorNameNode || errorFallbackNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, errorDeclarationNameWithFallback(), "this"));
    }
  }
  function reportLikelyUnsafeImportRequiredError(specifier) {
    if (errorNameNode || errorFallbackNode) {
      context.addDiagnostic(createDiagnosticForNode(errorNameNode || errorFallbackNode, Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, errorDeclarationNameWithFallback(), specifier));
    }
  }
  function reportTruncationError() {
    if (errorNameNode || errorFallbackNode) {
      context.addDiagnostic(createDiagnosticForNode(errorNameNode || errorFallbackNode, Diagnostics.The_inferred_type_of_this_node_exceeds_the_maximum_length_the_compiler_will_serialize_An_explicit_type_annotation_is_needed));
    }
  }
  function reportNonlocalAugmentation(containingFile, parentSymbol, symbol) {
    var _a;
    const primaryDeclaration = (_a = parentSymbol.declarations) == null ? void 0 : _a.find((d) => getSourceFileOfNode(d) === containingFile);
    const augmentingDeclarations = filter(symbol.declarations, (d) => getSourceFileOfNode(d) !== containingFile);
    if (primaryDeclaration && augmentingDeclarations) {
      for (const augmentations of augmentingDeclarations) {
        context.addDiagnostic(addRelatedInfo(
          createDiagnosticForNode(augmentations, Diagnostics.Declaration_augments_declaration_in_another_file_This_cannot_be_serialized),
          createDiagnosticForNode(primaryDeclaration, Diagnostics.This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file)
        ));
      }
    }
  }
  function reportNonSerializableProperty(propertyName) {
    if (errorNameNode || errorFallbackNode) {
      context.addDiagnostic(createDiagnosticForNode(errorNameNode || errorFallbackNode, Diagnostics.The_type_of_this_node_cannot_be_serialized_because_its_property_0_cannot_be_serialized, propertyName));
    }
  }
  function transformDeclarationsForJS(sourceFile) {
    const oldDiag = getSymbolAccessibilityDiagnostic;
    getSymbolAccessibilityDiagnostic = (s) => s.errorNode && canProduceDiagnostics(s.errorNode) ? createGetSymbolAccessibilityDiagnosticForNode(s.errorNode)(s) : {
      diagnosticMessage: s.errorModuleName ? Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit : Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit,
      errorNode: s.errorNode || sourceFile
    };
    const result = resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, symbolTracker);
    getSymbolAccessibilityDiagnostic = oldDiag;
    return result;
  }
  function transformRoot(node) {
    if (node.kind === 307 /* SourceFile */ && node.isDeclarationFile) {
      return node;
    }
    if (node.kind === 308 /* Bundle */) {
      isBundledEmit = true;
      rawReferencedFiles = [];
      rawTypeReferenceDirectives = [];
      rawLibReferenceDirectives = [];
      let hasNoDefaultLib = false;
      const bundle = factory2.createBundle(
        map(node.sourceFiles, (sourceFile) => {
          if (sourceFile.isDeclarationFile) return void 0;
          hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib;
          currentSourceFile = sourceFile;
          enclosingDeclaration = sourceFile;
          lateMarkedStatements = void 0;
          suppressNewDiagnosticContexts = false;
          lateStatementReplacementMap = /* @__PURE__ */ new Map();
          getSymbolAccessibilityDiagnostic = throwDiagnostic;
          needsScopeFixMarker = false;
          resultHasScopeMarker = false;
          collectFileReferences(sourceFile);
          if (isExternalOrCommonJsModule(sourceFile) || isJsonSourceFile(sourceFile)) {
            resultHasExternalModuleIndicator = false;
            needsDeclare = false;
            const statements = isSourceFileJS(sourceFile) ? factory2.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes2(sourceFile.statements, visitDeclarationStatements, isStatement);
            const newFile = factory2.updateSourceFile(
              sourceFile,
              [factory2.createModuleDeclaration(
                [factory2.createModifier(138 /* DeclareKeyword */)],
                factory2.createStringLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)),
                factory2.createModuleBlock(setTextRange(factory2.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements))
              )],
              /*isDeclarationFile*/
              true,
              /*referencedFiles*/
              [],
              /*typeReferences*/
              [],
              /*hasNoDefaultLib*/
              false,
              /*libReferences*/
              []
            );
            return newFile;
          }
          needsDeclare = true;
          const updated = isSourceFileJS(sourceFile) ? factory2.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes2(sourceFile.statements, visitDeclarationStatements, isStatement);
          return factory2.updateSourceFile(
            sourceFile,
            transformAndReplaceLatePaintedStatements(updated),
            /*isDeclarationFile*/
            true,
            /*referencedFiles*/
            [],
            /*typeReferences*/
            [],
            /*hasNoDefaultLib*/
            false,
            /*libReferences*/
            []
          );
        })
      );
      const outputFilePath2 = getDirectoryPath(normalizeSlashes(getOutputPathsFor(
        node,
        host,
        /*forceDtsPaths*/
        true
      ).declarationFilePath));
      bundle.syntheticFileReferences = getReferencedFiles(outputFilePath2);
      bundle.syntheticTypeReferences = getTypeReferences();
      bundle.syntheticLibReferences = getLibReferences();
      bundle.hasNoDefaultLib = hasNoDefaultLib;
      return bundle;
    }
    needsDeclare = true;
    needsScopeFixMarker = false;
    resultHasScopeMarker = false;
    enclosingDeclaration = node;
    currentSourceFile = node;
    getSymbolAccessibilityDiagnostic = throwDiagnostic;
    isBundledEmit = false;
    resultHasExternalModuleIndicator = false;
    suppressNewDiagnosticContexts = false;
    lateMarkedStatements = void 0;
    lateStatementReplacementMap = /* @__PURE__ */ new Map();
    rawReferencedFiles = [];
    rawTypeReferenceDirectives = [];
    rawLibReferenceDirectives = [];
    collectFileReferences(currentSourceFile);
    let combinedStatements;
    if (isSourceFileJS(currentSourceFile)) {
      combinedStatements = factory2.createNodeArray(transformDeclarationsForJS(node));
    } else {
      const statements = visitNodes2(node.statements, visitDeclarationStatements, isStatement);
      combinedStatements = setTextRange(factory2.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
      if (isExternalModule(node) && (!resultHasExternalModuleIndicator || needsScopeFixMarker && !resultHasScopeMarker)) {
        combinedStatements = setTextRange(factory2.createNodeArray([...combinedStatements, createEmptyExports(factory2)]), combinedStatements);
      }
    }
    const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(
      node,
      host,
      /*forceDtsPaths*/
      true
    ).declarationFilePath));
    return factory2.updateSourceFile(
      node,
      combinedStatements,
      /*isDeclarationFile*/
      true,
      getReferencedFiles(outputFilePath),
      getTypeReferences(),
      node.hasNoDefaultLib,
      getLibReferences()
    );
    function collectFileReferences(sourceFile) {
      rawReferencedFiles = concatenate(rawReferencedFiles, map(sourceFile.referencedFiles, (f) => [sourceFile, f]));
      rawTypeReferenceDirectives = concatenate(rawTypeReferenceDirectives, sourceFile.typeReferenceDirectives);
      rawLibReferenceDirectives = concatenate(rawLibReferenceDirectives, sourceFile.libReferenceDirectives);
    }
    function copyFileReferenceAsSynthetic(ref) {
      const newRef = { ...ref };
      newRef.pos = -1;
      newRef.end = -1;
      return newRef;
    }
    function getTypeReferences() {
      return mapDefined(rawTypeReferenceDirectives, (ref) => {
        if (!ref.preserve) return void 0;
        return copyFileReferenceAsSynthetic(ref);
      });
    }
    function getLibReferences() {
      return mapDefined(rawLibReferenceDirectives, (ref) => {
        if (!ref.preserve) return void 0;
        return copyFileReferenceAsSynthetic(ref);
      });
    }
    function getReferencedFiles(outputFilePath2) {
      return mapDefined(rawReferencedFiles, ([sourceFile, ref]) => {
        if (!ref.preserve) return void 0;
        const file = host.getSourceFileFromReference(sourceFile, ref);
        if (!file) {
          return void 0;
        }
        let declFileName;
        if (file.isDeclarationFile) {
          declFileName = file.fileName;
        } else {
          if (isBundledEmit && contains(node.sourceFiles, file)) return;
          const paths = getOutputPathsFor(
            file,
            host,
            /*forceDtsPaths*/
            true
          );
          declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName;
        }
        if (!declFileName) return void 0;
        const fileName = getRelativePathToDirectoryOrUrl(
          outputFilePath2,
          declFileName,
          host.getCurrentDirectory(),
          host.getCanonicalFileName,
          /*isAbsolutePathAnUrl*/
          false
        );
        const newRef = copyFileReferenceAsSynthetic(ref);
        newRef.fileName = fileName;
        return newRef;
      });
    }
  }
  function filterBindingPatternInitializers(name) {
    if (name.kind === 80 /* Identifier */) {
      return name;
    } else {
      if (name.kind === 207 /* ArrayBindingPattern */) {
        return factory2.updateArrayBindingPattern(name, visitNodes2(name.elements, visitBindingElement, isArrayBindingElement));
      } else {
        return factory2.updateObjectBindingPattern(name, visitNodes2(name.elements, visitBindingElement, isBindingElement));
      }
    }
    function visitBindingElement(elem) {
      if (elem.kind === 232 /* OmittedExpression */) {
        return elem;
      }
      if (elem.propertyName && isComputedPropertyName(elem.propertyName) && isEntityNameExpression(elem.propertyName.expression)) {
        checkEntityNameVisibility(elem.propertyName.expression, enclosingDeclaration);
      }
      return factory2.updateBindingElement(
        elem,
        elem.dotDotDotToken,
        elem.propertyName,
        filterBindingPatternInitializers(elem.name),
        /*initializer*/
        void 0
      );
    }
  }
  function ensureParameter(p, modifierMask, type) {
    let oldDiag;
    if (!suppressNewDiagnosticContexts) {
      oldDiag = getSymbolAccessibilityDiagnostic;
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p);
    }
    const newParam = factory2.updateParameterDeclaration(
      p,
      maskModifiers(factory2, p, modifierMask),
      p.dotDotDotToken,
      filterBindingPatternInitializers(p.name),
      resolver.isOptionalParameter(p) ? p.questionToken || factory2.createToken(58 /* QuestionToken */) : void 0,
      ensureType(
        p,
        type || p.type,
        /*ignorePrivate*/
        true
      ),
      // Ignore private param props, since this type is going straight back into a param
      ensureNoInitializer(p)
    );
    if (!suppressNewDiagnosticContexts) {
      getSymbolAccessibilityDiagnostic = oldDiag;
    }
    return newParam;
  }
  function shouldPrintWithInitializer(node) {
    return canHaveLiteralInitializer(node) && !!node.initializer && resolver.isLiteralConstDeclaration(getParseTreeNode(node));
  }
  function ensureNoInitializer(node) {
    if (shouldPrintWithInitializer(node)) {
      const unwrappedInitializer = unwrapParenthesizedExpression(node.initializer);
      if (!isPrimitiveLiteralValue(unwrappedInitializer)) {
        reportInferenceFallback(node);
      }
      return resolver.createLiteralConstValue(getParseTreeNode(node, canHaveLiteralInitializer), symbolTracker);
    }
    return void 0;
  }
  function ensureType(node, type, ignorePrivate) {
    if (!ignorePrivate && hasEffectiveModifier(node, 2 /* Private */)) {
      return;
    }
    if (shouldPrintWithInitializer(node)) {
      return;
    }
    const shouldAddImplicitUndefined = node.kind === 169 /* Parameter */ && resolver.requiresAddingImplicitUndefined(node);
    if (type && !shouldAddImplicitUndefined) {
      return visitNode(type, visitDeclarationSubtree, isTypeNode);
    }
    errorNameNode = node.name;
    let oldDiag;
    if (!suppressNewDiagnosticContexts) {
      oldDiag = getSymbolAccessibilityDiagnostic;
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(node);
    }
    let typeNode;
    switch (node.kind) {
      case 169 /* Parameter */:
      case 171 /* PropertySignature */:
      case 172 /* PropertyDeclaration */:
      case 208 /* BindingElement */:
      case 260 /* VariableDeclaration */:
        typeNode = resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
        break;
      case 262 /* FunctionDeclaration */:
      case 180 /* ConstructSignature */:
      case 173 /* MethodSignature */:
      case 174 /* MethodDeclaration */:
      case 177 /* GetAccessor */:
      case 179 /* CallSignature */:
        typeNode = resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
        break;
      default:
        Debug.assertNever(node);
    }
    errorNameNode = void 0;
    if (!suppressNewDiagnosticContexts) {
      getSymbolAccessibilityDiagnostic = oldDiag;
    }
    return typeNode ?? factory2.createKeywordTypeNode(133 /* AnyKeyword */);
  }
  function isDeclarationAndNotVisible(node) {
    node = getParseTreeNode(node);
    switch (node.kind) {
      case 262 /* FunctionDeclaration */:
      case 267 /* ModuleDeclaration */:
      case 264 /* InterfaceDeclaration */:
      case 263 /* ClassDeclaration */:
      case 265 /* TypeAliasDeclaration */:
      case 266 /* EnumDeclaration */:
        return !resolver.isDeclarationVisible(node);
      case 260 /* VariableDeclaration */:
        return !getBindingNameVisible(node);
      case 271 /* ImportEqualsDeclaration */:
      case 272 /* ImportDeclaration */:
      case 278 /* ExportDeclaration */:
      case 277 /* ExportAssignment */:
        return false;
      case 175 /* ClassStaticBlockDeclaration */:
        return true;
    }
    return false;
  }
  function shouldEmitFunctionProperties(input) {
    var _a;
    if (input.body) {
      return true;
    }
    const overloadSignatures = (_a = input.symbol.declarations) == null ? void 0 : _a.filter((decl) => isFunctionDeclaration(decl) && !decl.body);
    return !overloadSignatures || overloadSignatures.indexOf(input) === overloadSignatures.length - 1;
  }
  function getBindingNameVisible(elem) {
    if (isOmittedExpression(elem)) {
      return false;
    }
    if (isBindingPattern(elem.name)) {
      return some(elem.name.elements, getBindingNameVisible);
    } else {
      return resolver.isDeclarationVisible(elem);
    }
  }
  function updateParamsList(node, params, modifierMask) {
    if (hasEffectiveModifier(node, 2 /* Private */)) {
      return factory2.createNodeArray();
    }
    const newParams = map(params, (p) => ensureParameter(p, modifierMask));
    if (!newParams) {
      return factory2.createNodeArray();
    }
    return factory2.createNodeArray(newParams, params.hasTrailingComma);
  }
  function updateAccessorParamsList(input, isPrivate) {
    let newParams;
    if (!isPrivate) {
      const thisParameter = getThisParameter(input);
      if (thisParameter) {
        newParams = [ensureParameter(thisParameter)];
      }
    }
    if (isSetAccessorDeclaration(input)) {
      let newValueParameter;
      if (!isPrivate) {
        const valueParameter = getSetAccessorValueParameter(input);
        if (valueParameter) {
          const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, getAllAccessorDeclarations(isObjectLiteralExpression(input.parent) ? input.parent.properties : input.parent.members, input));
          newValueParameter = ensureParameter(
            valueParameter,
            /*modifierMask*/
            void 0,
            accessorType
          );
        }
      }
      if (!newValueParameter) {
        newValueParameter = factory2.createParameterDeclaration(
          /*modifiers*/
          void 0,
          /*dotDotDotToken*/
          void 0,
          "value"
        );
      }
      newParams = append(newParams, newValueParameter);
    }
    return factory2.createNodeArray(newParams || emptyArray);
  }
  function ensureTypeParams(node, params) {
    return hasEffectiveModifier(node, 2 /* Private */) ? void 0 : visitNodes2(params, visitDeclarationSubtree, isTypeParameterDeclaration);
  }
  function isEnclosingDeclaration(node) {
    return isSourceFile(node) || isTypeAliasDeclaration(node) || isModuleDeclaration(node) || isClassDeclaration(node) || isInterfaceDeclaration(node) || isFunctionLike(node) || isIndexSignatureDeclaration(node) || isMappedTypeNode(node);
  }
  function checkEntityNameVisibility(entityName, enclosingDeclaration2) {
    const visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration2);
    handleSymbolAccessibilityError(visibilityResult);
  }
  function preserveJsDoc(updated, original) {
    if (hasJSDocNodes(updated) && hasJSDocNodes(original)) {
      updated.jsDoc = original.jsDoc;
    }
    return setCommentRange(updated, getCommentRange(original));
  }
  function rewriteModuleSpecifier(parent, input) {
    if (!input) return void 0;
    resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== 267 /* ModuleDeclaration */ && parent.kind !== 205 /* ImportType */;
    if (isStringLiteralLike(input)) {
      if (isBundledEmit) {
        const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
        if (newName) {
          return factory2.createStringLiteral(newName);
        }
      }
    }
    return input;
  }
  function transformImportEqualsDeclaration(decl) {
    if (!resolver.isDeclarationVisible(decl)) return;
    if (decl.moduleReference.kind === 283 /* ExternalModuleReference */) {
      const specifier = getExternalModuleImportEqualsDeclarationExpression(decl);
      return factory2.updateImportEqualsDeclaration(
        decl,
        decl.modifiers,
        decl.isTypeOnly,
        decl.name,
        factory2.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier))
      );
    } else {
      const oldDiag = getSymbolAccessibilityDiagnostic;
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(decl);
      checkEntityNameVisibility(decl.moduleReference, enclosingDeclaration);
      getSymbolAccessibilityDiagnostic = oldDiag;
      return decl;
    }
  }
  function transformImportDeclaration(decl) {
    if (!decl.importClause) {
      return factory2.updateImportDeclaration(
        decl,
        decl.modifiers,
        decl.importClause,
        rewriteModuleSpecifier(decl, decl.moduleSpecifier),
        tryGetResolutionModeOverride(decl.attributes)
      );
    }
    const visibleDefaultBinding = decl.importClause && decl.importClause.name && resolver.isDeclarationVisible(decl.importClause) ? decl.importClause.name : void 0;
    if (!decl.importClause.namedBindings) {
      return visibleDefaultBinding && factory2.updateImportDeclaration(
        decl,
        decl.modifiers,
        factory2.updateImportClause(
          decl.importClause,
          decl.importClause.isTypeOnly,
          visibleDefaultBinding,
          /*namedBindings*/
          void 0
        ),
        rewriteModuleSpecifier(decl, decl.moduleSpecifier),
        tryGetResolutionModeOverride(decl.attributes)
      );
    }
    if (decl.importClause.namedBindings.kind === 274 /* NamespaceImport */) {
      const namedBindings = resolver.isDeclarationVisible(decl.importClause.namedBindings) ? decl.importClause.namedBindings : (
        /*namedBindings*/
        void 0
      );
      return visibleDefaultBinding || namedBindings ? factory2.updateImportDeclaration(
        decl,
        decl.modifiers,
        factory2.updateImportClause(
          decl.importClause,
          decl.importClause.isTypeOnly,
          visibleDefaultBinding,
          namedBindings
        ),
        rewriteModuleSpecifier(decl, decl.moduleSpecifier),
        tryGetResolutionModeOverride(decl.attributes)
      ) : void 0;
    }
    const bindingList = mapDefined(decl.importClause.namedBindings.elements, (b) => resolver.isDeclarationVisible(b) ? b : void 0);
    if (bindingList && bindingList.length || visibleDefaultBinding) {
      return factory2.updateImportDeclaration(
        decl,
        decl.modifiers,
        factory2.updateImportClause(
          decl.importClause,
          decl.importClause.isTypeOnly,
          visibleDefaultBinding,
          bindingList && bindingList.length ? factory2.updateNamedImports(decl.importClause.namedBindings, bindingList) : void 0
        ),
        rewriteModuleSpecifier(decl, decl.moduleSpecifier),
        tryGetResolutionModeOverride(decl.attributes)
      );
    }
    if (resolver.isImportRequiredByAugmentation(decl)) {
      if (isolatedDeclarations) {
        context.addDiagnostic(createDiagnosticForNode(decl, Diagnostics.Declaration_emit_for_this_file_requires_preserving_this_import_for_augmentations_This_is_not_supported_with_isolatedDeclarations));
      }
      return factory2.updateImportDeclaration(
        decl,
        decl.modifiers,
        /*importClause*/
        void 0,
        rewriteModuleSpecifier(decl, decl.moduleSpecifier),
        tryGetResolutionModeOverride(decl.attributes)
      );
    }
  }
  function tryGetResolutionModeOverride(node) {
    const mode = getResolutionModeOverride(node);
    return node && mode !== void 0 ? node : void 0;
  }
  function transformAndReplaceLatePaintedStatements(statements) {
    while (length(lateMarkedStatements)) {
      const i = lateMarkedStatements.shift();
      if (!isLateVisibilityPaintedStatement(i)) {
        return Debug.fail(`Late replaced statement was found which is not handled by the declaration transformer!: ${Debug.formatSyntaxKind(i.kind)}`);
      }
      const priorNeedsDeclare = needsDeclare;
      needsDeclare = i.parent && isSourceFile(i.parent) && !(isExternalModule(i.parent) && isBundledEmit);
      const result = transformTopLevelDeclaration(i);
      needsDeclare = priorNeedsDeclare;
      lateStatementReplacementMap.set(getOriginalNodeId(i), result);
    }
    return visitNodes2(statements, visitLateVisibilityMarkedStatements, isStatement);
    function visitLateVisibilityMarkedStatements(statement) {
      if (isLateVisibilityPaintedStatement(statement)) {
        const key = getOriginalNodeId(statement);
        if (lateStatementReplacementMap.has(key)) {
          const result = lateStatementReplacementMap.get(key);
          lateStatementReplacementMap.delete(key);
          if (result) {
            if (isArray(result) ? some(result, needsScopeMarker) : needsScopeMarker(result)) {
              needsScopeFixMarker = true;
            }
            if (isSourceFile(statement.parent) && (isArray(result) ? some(result, isExternalModuleIndicator) : isExternalModuleIndicator(result))) {
              resultHasExternalModuleIndicator = true;
            }
          }
          return result;
        }
      }
      return statement;
    }
  }
  function visitDeclarationSubtree(input) {
    if (shouldStripInternal(input)) return;
    if (isDeclaration(input)) {
      if (isDeclarationAndNotVisible(input)) return;
      if (hasDynamicName(input)) {
        if (isolatedDeclarations) {
          if (!resolver.isDefinitelyReferenceToGlobalSymbolObject(input.name.expression)) {
            if (isClassDeclaration(input.parent) || isObjectLiteralExpression(input.parent)) {
              context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations));
              return;
            } else if (
              // Type declarations just need to double-check that the input computed name is an entity name expression
              (isInterfaceDeclaration(input.parent) || isTypeLiteralNode(input.parent)) && !isEntityNameExpression(input.name.expression)
            ) {
              context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations));
              return;
            }
          }
        } else if (!resolver.isLateBound(getParseTreeNode(input)) || !isEntityNameExpression(input.name.expression)) {
          return;
        }
      }
    }
    if (isFunctionLike(input) && resolver.isImplementationOfOverload(input)) return;
    if (isSemicolonClassElement(input)) return;
    let previousEnclosingDeclaration;
    if (isEnclosingDeclaration(input)) {
      previousEnclosingDeclaration = enclosingDeclaration;
      enclosingDeclaration = input;
    }
    const oldDiag = getSymbolAccessibilityDiagnostic;
    const canProduceDiagnostic = canProduceDiagnostics(input);
    const oldWithinObjectLiteralType = suppressNewDiagnosticContexts;
    let shouldEnterSuppressNewDiagnosticsContextContext = (input.kind === 187 /* TypeLiteral */ || input.kind === 200 /* MappedType */) && input.parent.kind !== 265 /* TypeAliasDeclaration */;
    if (isMethodDeclaration(input) || isMethodSignature(input)) {
      if (hasEffectiveModifier(input, 2 /* Private */)) {
        if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input) return;
        return cleanup(factory2.createPropertyDeclaration(
          ensureModifiers(input),
          input.name,
          /*questionOrExclamationToken*/
          void 0,
          /*type*/
          void 0,
          /*initializer*/
          void 0
        ));
      }
    }
    if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input);
    }
    if (isTypeQueryNode(input)) {
      checkEntityNameVisibility(input.exprName, enclosingDeclaration);
    }
    if (shouldEnterSuppressNewDiagnosticsContextContext) {
      suppressNewDiagnosticContexts = true;
    }
    if (isProcessedComponent(input)) {
      switch (input.kind) {
        case 233 /* ExpressionWithTypeArguments */: {
          if (isEntityName(input.expression) || isEntityNameExpression(input.expression)) {
            checkEntityNameVisibility(input.expression, enclosingDeclaration);
          }
          const node = visitEachChild(input, visitDeclarationSubtree, context);
          return cleanup(factory2.updateExpressionWithTypeArguments(node, node.expression, node.typeArguments));
        }
        case 183 /* TypeReference */: {
          checkEntityNameVisibility(input.typeName, enclosingDeclaration);
          const node = visitEachChild(input, visitDeclarationSubtree, context);
          return cleanup(factory2.updateTypeReferenceNode(node, node.typeName, node.typeArguments));
        }
        case 180 /* ConstructSignature */:
          return cleanup(factory2.updateConstructSignature(
            input,
            ensureTypeParams(input, input.typeParameters),
            updateParamsList(input, input.parameters),
            ensureType(input, input.type)
          ));
        case 176 /* Constructor */: {
          const ctor = factory2.createConstructorDeclaration(
            /*modifiers*/
            ensureModifiers(input),
            updateParamsList(input, input.parameters, 0 /* None */),
            /*body*/
            void 0
          );
          return cleanup(ctor);
        }
        case 174 /* MethodDeclaration */: {
          if (isPrivateIdentifier(input.name)) {
            return cleanup(
              /*returnValue*/
              void 0
            );
          }
          const sig = factory2.createMethodDeclaration(
            ensureModifiers(input),
            /*asteriskToken*/
            void 0,
            input.name,
            input.questionToken,
            ensureTypeParams(input, input.typeParameters),
            updateParamsList(input, input.parameters),
            ensureType(input, input.type),
            /*body*/
            void 0
          );
          return cleanup(sig);
        }
        case 177 /* GetAccessor */: {
          if (isPrivateIdentifier(input.name)) {
            return cleanup(
              /*returnValue*/
              void 0
            );
          }
          const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, getAllAccessorDeclarations(isObjectLiteralExpression(input.parent) ? input.parent.properties : input.parent.members, input));
          return cleanup(factory2.updateGetAccessorDeclaration(
            input,
            ensureModifiers(input),
            input.name,
            updateAccessorParamsList(input, hasEffectiveModifier(input, 2 /* Private */)),
            ensureType(input, accessorType),
            /*body*/
            void 0
          ));
        }
        case 178 /* SetAccessor */: {
          if (isPrivateIdentifier(input.name)) {
            return cleanup(
              /*returnValue*/
              void 0
            );
          }
          return cleanup(factory2.updateSetAccessorDeclaration(
            input,
            ensureModifiers(input),
            input.name,
            updateAccessorParamsList(input, hasEffectiveModifier(input, 2 /* Private */)),
            /*body*/
            void 0
          ));
        }
        case 172 /* PropertyDeclaration */:
          if (isPrivateIdentifier(input.name)) {
            return cleanup(
              /*returnValue*/
              void 0
            );
          }
          return cleanup(factory2.updatePropertyDeclaration(
            input,
            ensureModifiers(input),
            input.name,
            input.questionToken,
            ensureType(input, input.type),
            ensureNoInitializer(input)
          ));
        case 171 /* PropertySignature */:
          if (isPrivateIdentifier(input.name)) {
            return cleanup(
              /*returnValue*/
              void 0
            );
          }
          return cleanup(factory2.updatePropertySignature(
            input,
            ensureModifiers(input),
            input.name,
            input.questionToken,
            ensureType(input, input.type)
          ));
        case 173 /* MethodSignature */: {
          if (isPrivateIdentifier(input.name)) {
            return cleanup(
              /*returnValue*/
              void 0
            );
          }
          return cleanup(factory2.updateMethodSignature(
            input,
            ensureModifiers(input),
            input.name,
            input.questionToken,
            ensureTypeParams(input, input.typeParameters),
            updateParamsList(input, input.parameters),
            ensureType(input, input.type)
          ));
        }
        case 179 /* CallSignature */: {
          return cleanup(
            factory2.updateCallSignature(
              input,
              ensureTypeParams(input, input.typeParameters),
              updateParamsList(input, input.parameters),
              ensureType(input, input.type)
            )
          );
        }
        case 181 /* IndexSignature */: {
          return cleanup(factory2.updateIndexSignature(
            input,
            ensureModifiers(input),
            updateParamsList(input, input.parameters),
            visitNode(input.type, visitDeclarationSubtree, isTypeNode) || factory2.createKeywordTypeNode(133 /* AnyKeyword */)
          ));
        }
        case 260 /* VariableDeclaration */: {
          if (isBindingPattern(input.name)) {
            return recreateBindingPattern(input.name);
          }
          shouldEnterSuppressNewDiagnosticsContextContext = true;
          suppressNewDiagnosticContexts = true;
          return cleanup(factory2.updateVariableDeclaration(
            input,
            input.name,
            /*exclamationToken*/
            void 0,
            ensureType(input, input.type),
            ensureNoInitializer(input)
          ));
        }
        case 168 /* TypeParameter */: {
          if (isPrivateMethodTypeParameter(input) && (input.default || input.constraint)) {
            return cleanup(factory2.updateTypeParameterDeclaration(
              input,
              input.modifiers,
              input.name,
              /*constraint*/
              void 0,
              /*defaultType*/
              void 0
            ));
          }
          return cleanup(visitEachChild(input, visitDeclarationSubtree, context));
        }
        case 194 /* ConditionalType */: {
          const checkType = visitNode(input.checkType, visitDeclarationSubtree, isTypeNode);
          const extendsType = visitNode(input.extendsType, visitDeclarationSubtree, isTypeNode);
          const oldEnclosingDecl = enclosingDeclaration;
          enclosingDeclaration = input.trueType;
          const trueType = visitNode(input.trueType, visitDeclarationSubtree, isTypeNode);
          enclosingDeclaration = oldEnclosingDecl;
          const falseType = visitNode(input.falseType, visitDeclarationSubtree, isTypeNode);
          Debug.assert(checkType);
          Debug.assert(extendsType);
          Debug.assert(trueType);
          Debug.assert(falseType);
          return cleanup(factory2.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType));
        }
        case 184 /* FunctionType */: {
          return cleanup(factory2.updateFunctionTypeNode(
            input,
            visitNodes2(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration),
            updateParamsList(input, input.parameters),
            Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode))
          ));
        }
        case 185 /* ConstructorType */: {
          return cleanup(factory2.updateConstructorTypeNode(
            input,
            ensureModifiers(input),
            visitNodes2(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration),
            updateParamsList(input, input.parameters),
            Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode))
          ));
        }
        case 205 /* ImportType */: {
          if (!isLiteralImportTypeNode(input)) return cleanup(input);
          return cleanup(factory2.updateImportTypeNode(
            input,
            factory2.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)),
            input.attributes,
            input.qualifier,
            visitNodes2(input.typeArguments, visitDeclarationSubtree, isTypeNode),
            input.isTypeOf
          ));
        }
        default:
          Debug.assertNever(input, `Attempted to process unhandled node kind: ${Debug.formatSyntaxKind(input.kind)}`);
      }
    }
    if (isTupleTypeNode(input) && getLineAndCharacterOfPosition(currentSourceFile, input.pos).line === getLineAndCharacterOfPosition(currentSourceFile, input.end).line) {
      setEmitFlags(input, 1 /* SingleLine */);
    }
    return cleanup(visitEachChild(input, visitDeclarationSubtree, context));
    function cleanup(returnValue) {
      if (returnValue && canProduceDiagnostic && hasDynamicName(input)) {
        checkName(input);
      }
      if (isEnclosingDeclaration(input)) {
        enclosingDeclaration = previousEnclosingDeclaration;
      }
      if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
        getSymbolAccessibilityDiagnostic = oldDiag;
      }
      if (shouldEnterSuppressNewDiagnosticsContextContext) {
        suppressNewDiagnosticContexts = oldWithinObjectLiteralType;
      }
      if (returnValue === input) {
        return returnValue;
      }
      return returnValue && setOriginalNode(preserveJsDoc(returnValue, input), input);
    }
  }
  function isPrivateMethodTypeParameter(node) {
    return node.parent.kind === 174 /* MethodDeclaration */ && hasEffectiveModifier(node.parent, 2 /* Private */);
  }
  function visitDeclarationStatements(input) {
    if (!isPreservedDeclarationStatement(input)) {
      return;
    }
    if (shouldStripInternal(input)) return;
    switch (input.kind) {
      case 278 /* ExportDeclaration */: {
        if (isSourceFile(input.parent)) {
          resultHasExternalModuleIndicator = true;
        }
        resultHasScopeMarker = true;
        return factory2.updateExportDeclaration(
          input,
          input.modifiers,
          input.isTypeOnly,
          input.exportClause,
          rewriteModuleSpecifier(input, input.moduleSpecifier),
          tryGetResolutionModeOverride(input.attributes)
        );
      }
      case 277 /* ExportAssignment */: {
        if (isSourceFile(input.parent)) {
          resultHasExternalModuleIndicator = true;
        }
        resultHasScopeMarker = true;
        if (input.expression.kind === 80 /* Identifier */) {
          return input;
        } else {
          const newId = factory2.createUniqueName("_default", 16 /* Optimistic */);
          getSymbolAccessibilityDiagnostic = () => ({
            diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
            errorNode: input
          });
          errorFallbackNode = input;
          const varDecl = factory2.createVariableDeclaration(
            newId,
            /*exclamationToken*/
            void 0,
            resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker),
            /*initializer*/
            void 0
          );
          errorFallbackNode = void 0;
          const statement = factory2.createVariableStatement(needsDeclare ? [factory2.createModifier(138 /* DeclareKeyword */)] : [], factory2.createVariableDeclarationList([varDecl], 2 /* Const */));
          preserveJsDoc(statement, input);
          removeAllComments(input);
          return [statement, factory2.updateExportAssignment(input, input.modifiers, newId)];
        }
      }
    }
    const result = transformTopLevelDeclaration(input);
    lateStatementReplacementMap.set(getOriginalNodeId(input), result);
    return input;
  }
  function stripExportModifiers(statement) {
    if (isImportEqualsDeclaration(statement) || hasEffectiveModifier(statement, 2048 /* Default */) || !canHaveModifiers(statement)) {
      return statement;
    }
    const modifiers = factory2.createModifiersFromModifierFlags(getEffectiveModifierFlags(statement) & (131071 /* All */ ^ 32 /* Export */));
    return factory2.replaceModifiers(statement, modifiers);
  }
  function updateModuleDeclarationAndKeyword(node, modifiers, name, body) {
    const updated = factory2.updateModuleDeclaration(node, modifiers, name, body);
    if (isAmbientModule(updated) || updated.flags & 32 /* Namespace */) {
      return updated;
    }
    const fixed = factory2.createModuleDeclaration(
      updated.modifiers,
      updated.name,
      updated.body,
      updated.flags | 32 /* Namespace */
    );
    setOriginalNode(fixed, updated);
    setTextRange(fixed, updated);
    return fixed;
  }
  function transformTopLevelDeclaration(input) {
    if (lateMarkedStatements) {
      while (orderedRemoveItem(lateMarkedStatements, input)) ;
    }
    if (shouldStripInternal(input)) return;
    switch (input.kind) {
      case 271 /* ImportEqualsDeclaration */: {
        return transformImportEqualsDeclaration(input);
      }
      case 272 /* ImportDeclaration */: {
        return transformImportDeclaration(input);
      }
    }
    if (isDeclaration(input) && isDeclarationAndNotVisible(input)) return;
    if (isJSDocImportTag(input)) return;
    if (isFunctionLike(input) && resolver.isImplementationOfOverload(input)) return;
    let previousEnclosingDeclaration;
    if (isEnclosingDeclaration(input)) {
      previousEnclosingDeclaration = enclosingDeclaration;
      enclosingDeclaration = input;
    }
    const canProdiceDiagnostic = canProduceDiagnostics(input);
    const oldDiag = getSymbolAccessibilityDiagnostic;
    if (canProdiceDiagnostic) {
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input);
    }
    const previousNeedsDeclare = needsDeclare;
    switch (input.kind) {
      case 265 /* TypeAliasDeclaration */: {
        needsDeclare = false;
        const clean2 = cleanup(factory2.updateTypeAliasDeclaration(
          input,
          ensureModifiers(input),
          input.name,
          visitNodes2(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration),
          Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode))
        ));
        needsDeclare = previousNeedsDeclare;
        return clean2;
      }
      case 264 /* InterfaceDeclaration */: {
        return cleanup(factory2.updateInterfaceDeclaration(
          input,
          ensureModifiers(input),
          input.name,
          ensureTypeParams(input, input.typeParameters),
          transformHeritageClauses(input.heritageClauses),
          visitNodes2(input.members, visitDeclarationSubtree, isTypeElement)
        ));
      }
      case 262 /* FunctionDeclaration */: {
        const clean2 = cleanup(factory2.updateFunctionDeclaration(
          input,
          ensureModifiers(input),
          /*asteriskToken*/
          void 0,
          input.name,
          ensureTypeParams(input, input.typeParameters),
          updateParamsList(input, input.parameters),
          ensureType(input, input.type),
          /*body*/
          void 0
        ));
        if (clean2 && resolver.isExpandoFunctionDeclaration(input) && shouldEmitFunctionProperties(input)) {
          const props = resolver.getPropertiesOfContainerFunction(input);
          if (isolatedDeclarations) {
            reportExpandoFunctionErrors(input);
          }
          const fakespace = parseNodeFactory.createModuleDeclaration(
            /*modifiers*/
            void 0,
            clean2.name || factory2.createIdentifier("_default"),
            factory2.createModuleBlock([]),
            32 /* Namespace */
          );
          setParent(fakespace, enclosingDeclaration);
          fakespace.locals = createSymbolTable(props);
          fakespace.symbol = props[0].parent;
          const exportMappings = [];
          let declarations = mapDefined(props, (p) => {
            if (!isExpandoPropertyDeclaration(p.valueDeclaration)) {
              return void 0;
            }
            const nameStr = unescapeLeadingUnderscores(p.escapedName);
            if (!isIdentifierText(nameStr, 99 /* ESNext */)) {
              return void 0;
            }
            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
            const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags | -2147483648 /* NoSyntacticPrinter */, symbolTracker);
            getSymbolAccessibilityDiagnostic = oldDiag;
            const isNonContextualKeywordName = isStringANonContextualKeyword(nameStr);
            const name = isNonContextualKeywordName ? factory2.getGeneratedNameForNode(p.valueDeclaration) : factory2.createIdentifier(nameStr);
            if (isNonContextualKeywordName) {
              exportMappings.push([name, nameStr]);
            }
            const varDecl = factory2.createVariableDeclaration(
              name,
              /*exclamationToken*/
              void 0,
              type,
              /*initializer*/
              void 0
            );
            return factory2.createVariableStatement(isNonContextualKeywordName ? void 0 : [factory2.createToken(95 /* ExportKeyword */)], factory2.createVariableDeclarationList([varDecl]));
          });
          if (!exportMappings.length) {
            declarations = mapDefined(declarations, (declaration) => factory2.replaceModifiers(declaration, 0 /* None */));
          } else {
            declarations.push(factory2.createExportDeclaration(
              /*modifiers*/
              void 0,
              /*isTypeOnly*/
              false,
              factory2.createNamedExports(map(exportMappings, ([gen, exp]) => {
                return factory2.createExportSpecifier(
                  /*isTypeOnly*/
                  false,
                  gen,
                  exp
                );
              }))
            ));
          }
          const namespaceDecl = factory2.createModuleDeclaration(ensureModifiers(input), input.name, factory2.createModuleBlock(declarations), 32 /* Namespace */);
          if (!hasEffectiveModifier(clean2, 2048 /* Default */)) {
            return [clean2, namespaceDecl];
          }
          const modifiers = factory2.createModifiersFromModifierFlags(getEffectiveModifierFlags(clean2) & ~2080 /* ExportDefault */ | 128 /* Ambient */);
          const cleanDeclaration = factory2.updateFunctionDeclaration(
            clean2,
            modifiers,
            /*asteriskToken*/
            void 0,
            clean2.name,
            clean2.typeParameters,
            clean2.parameters,
            clean2.type,
            /*body*/
            void 0
          );
          const namespaceDeclaration = factory2.updateModuleDeclaration(
            namespaceDecl,
            modifiers,
            namespaceDecl.name,
            namespaceDecl.body
          );
          const exportDefaultDeclaration = factory2.createExportAssignment(
            /*modifiers*/
            void 0,
            /*isExportEquals*/
            false,
            namespaceDecl.name
          );
          if (isSourceFile(input.parent)) {
            resultHasExternalModuleIndicator = true;
          }
          resultHasScopeMarker = true;
          return [cleanDeclaration, namespaceDeclaration, exportDefaultDeclaration];
        } else {
          return clean2;
        }
      }
      case 267 /* ModuleDeclaration */: {
        needsDeclare = false;
        const inner = input.body;
        if (inner && inner.kind === 268 /* ModuleBlock */) {
          const oldNeedsScopeFix = needsScopeFixMarker;
          const oldHasScopeFix = resultHasScopeMarker;
          resultHasScopeMarker = false;
          needsScopeFixMarker = false;
          const statements = visitNodes2(inner.statements, visitDeclarationStatements, isStatement);
          let lateStatements = transformAndReplaceLatePaintedStatements(statements);
          if (input.flags & 33554432 /* Ambient */) {
            needsScopeFixMarker = false;
          }
          if (!isGlobalScopeAugmentation(input) && !hasScopeMarker2(lateStatements) && !resultHasScopeMarker) {
            if (needsScopeFixMarker) {
              lateStatements = factory2.createNodeArray([...lateStatements, createEmptyExports(factory2)]);
            } else {
              lateStatements = visitNodes2(lateStatements, stripExportModifiers, isStatement);
            }
          }
          const body = factory2.updateModuleBlock(inner, lateStatements);
          needsDeclare = previousNeedsDeclare;
          needsScopeFixMarker = oldNeedsScopeFix;
          resultHasScopeMarker = oldHasScopeFix;
          const mods = ensureModifiers(input);
          return cleanup(updateModuleDeclarationAndKeyword(
            input,
            mods,
            isExternalModuleAugmentation(input) ? rewriteModuleSpecifier(input, input.name) : input.name,
            body
          ));
        } else {
          needsDeclare = previousNeedsDeclare;
          const mods = ensureModifiers(input);
          needsDeclare = false;
          visitNode(inner, visitDeclarationStatements);
          const id = getOriginalNodeId(inner);
          const body = lateStatementReplacementMap.get(id);
          lateStatementReplacementMap.delete(id);
          return cleanup(updateModuleDeclarationAndKeyword(
            input,
            mods,
            input.name,
            body
          ));
        }
      }
      case 263 /* ClassDeclaration */: {
        errorNameNode = input.name;
        errorFallbackNode = input;
        const modifiers = factory2.createNodeArray(ensureModifiers(input));
        const typeParameters = ensureTypeParams(input, input.typeParameters);
        const ctor = getFirstConstructorWithBody(input);
        let parameterProperties;
        if (ctor) {
          const oldDiag2 = getSymbolAccessibilityDiagnostic;
          parameterProperties = compact(flatMap(ctor.parameters, (param) => {
            if (!hasSyntacticModifier(param, 31 /* ParameterPropertyModifier */) || shouldStripInternal(param)) return;
            getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(param);
            if (param.name.kind === 80 /* Identifier */) {
              return preserveJsDoc(
                factory2.createPropertyDeclaration(
                  ensureModifiers(param),
                  param.name,
                  param.questionToken,
                  ensureType(param, param.type),
                  ensureNoInitializer(param)
                ),
                param
              );
            } else {
              return walkBindingPattern(param.name);
            }
            function walkBindingPattern(pattern) {
              let elems;
              for (const elem of pattern.elements) {
                if (isOmittedExpression(elem)) continue;
                if (isBindingPattern(elem.name)) {
                  elems = concatenate(elems, walkBindingPattern(elem.name));
                }
                elems = elems || [];
                elems.push(factory2.createPropertyDeclaration(
                  ensureModifiers(param),
                  elem.name,
                  /*questionOrExclamationToken*/
                  void 0,
                  ensureType(
                    elem,
                    /*type*/
                    void 0
                  ),
                  /*initializer*/
                  void 0
                ));
              }
              return elems;
            }
          }));
          getSymbolAccessibilityDiagnostic = oldDiag2;
        }
        const hasPrivateIdentifier = some(input.members, (member) => !!member.name && isPrivateIdentifier(member.name));
        const privateIdentifier = hasPrivateIdentifier ? [
          factory2.createPropertyDeclaration(
            /*modifiers*/
            void 0,
            factory2.createPrivateIdentifier("#private"),
            /*questionOrExclamationToken*/
            void 0,
            /*type*/
            void 0,
            /*initializer*/
            void 0
          )
        ] : void 0;
        const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes2(input.members, visitDeclarationSubtree, isClassElement));
        const members = factory2.createNodeArray(memberNodes);
        const extendsClause = getEffectiveBaseTypeNode(input);
        if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== 106 /* NullKeyword */) {
          const oldId = input.name ? unescapeLeadingUnderscores(input.name.escapedText) : "default";
          const newId = factory2.createUniqueName(`${oldId}_base`, 16 /* Optimistic */);
          getSymbolAccessibilityDiagnostic = () => ({
            diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
            errorNode: extendsClause,
            typeName: input.name
          });
          const varDecl = factory2.createVariableDeclaration(
            newId,
            /*exclamationToken*/
            void 0,
            resolver.createTypeOfExpression(extendsClause.expression, input, declarationEmitNodeBuilderFlags, symbolTracker),
            /*initializer*/
            void 0
          );
          const statement = factory2.createVariableStatement(needsDeclare ? [factory2.createModifier(138 /* DeclareKeyword */)] : [], factory2.createVariableDeclarationList([varDecl], 2 /* Const */));
          const heritageClauses = factory2.createNodeArray(map(input.heritageClauses, (clause) => {
            if (clause.token === 96 /* ExtendsKeyword */) {
              const oldDiag2 = getSymbolAccessibilityDiagnostic;
              getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]);
              const newClause = factory2.updateHeritageClause(clause, map(clause.types, (t) => factory2.updateExpressionWithTypeArguments(t, newId, visitNodes2(t.typeArguments, visitDeclarationSubtree, isTypeNode))));
              getSymbolAccessibilityDiagnostic = oldDiag2;
              return newClause;
            }
            return factory2.updateHeritageClause(clause, visitNodes2(factory2.createNodeArray(filter(clause.types, (t) => isEntityNameExpression(t.expression) || t.expression.kind === 106 /* NullKeyword */)), visitDeclarationSubtree, isExpressionWithTypeArguments));
          }));
          return [
            statement,
            cleanup(factory2.updateClassDeclaration(
              input,
              modifiers,
              input.name,
              typeParameters,
              heritageClauses,
              members
            ))
          ];
        } else {
          const heritageClauses = transformHeritageClauses(input.heritageClauses);
          return cleanup(factory2.updateClassDeclaration(
            input,
            modifiers,
            input.name,
            typeParameters,
            heritageClauses,
            members
          ));
        }
      }
      case 243 /* VariableStatement */: {
        return cleanup(transformVariableStatement(input));
      }
      case 266 /* EnumDeclaration */: {
        return cleanup(factory2.updateEnumDeclaration(
          input,
          factory2.createNodeArray(ensureModifiers(input)),
          input.name,
          factory2.createNodeArray(mapDefined(input.members, (m) => {
            if (shouldStripInternal(m)) return;
            const enumValue = resolver.getEnumMemberValue(m);
            const constValue = enumValue == null ? void 0 : enumValue.value;
            if (isolatedDeclarations && m.initializer && (enumValue == null ? void 0 : enumValue.hasExternalReferences) && // This will be its own compiler error instead, so don't report.
            !isComputedPropertyName(m.name)) {
              context.addDiagnostic(createDiagnosticForNode(m, Diagnostics.Enum_member_initializers_must_be_computable_without_references_to_external_symbols_with_isolatedDeclarations));
            }
            const newInitializer = constValue === void 0 ? void 0 : typeof constValue === "string" ? factory2.createStringLiteral(constValue) : constValue < 0 ? factory2.createPrefixUnaryExpression(41 /* MinusToken */, factory2.createNumericLiteral(-constValue)) : factory2.createNumericLiteral(constValue);
            return preserveJsDoc(factory2.updateEnumMember(m, m.name, newInitializer), m);
          }))
        ));
      }
    }
    return Debug.assertNever(input, `Unhandled top-level node in declaration emit: ${Debug.formatSyntaxKind(input.kind)}`);
    function cleanup(node) {
      if (isEnclosingDeclaration(input)) {
        enclosingDeclaration = previousEnclosingDeclaration;
      }
      if (canProdiceDiagnostic) {
        getSymbolAccessibilityDiagnostic = oldDiag;
      }
      if (input.kind === 267 /* ModuleDeclaration */) {
        needsDeclare = previousNeedsDeclare;
      }
      if (node === input) {
        return node;
      }
      errorFallbackNode = void 0;
      errorNameNode = void 0;
      return node && setOriginalNode(preserveJsDoc(node, input), input);
    }
  }
  function transformVariableStatement(input) {
    if (!forEach(input.declarationList.declarations, getBindingNameVisible)) return;
    const nodes = visitNodes2(input.declarationList.declarations, visitDeclarationSubtree, isVariableDeclaration);
    if (!length(nodes)) return;
    const modifiers = factory2.createNodeArray(ensureModifiers(input));
    let declList;
    if (isVarUsing(input.declarationList) || isVarAwaitUsing(input.declarationList)) {
      declList = factory2.createVariableDeclarationList(nodes, 2 /* Const */);
      setOriginalNode(declList, input.declarationList);
      setTextRange(declList, input.declarationList);
      setCommentRange(declList, input.declarationList);
    } else {
      declList = factory2.updateVariableDeclarationList(input.declarationList, nodes);
    }
    return factory2.updateVariableStatement(input, modifiers, declList);
  }
  function recreateBindingPattern(d) {
    return flatten(mapDefined(d.elements, (e) => recreateBindingElement(e)));
  }
  function recreateBindingElement(e) {
    if (e.kind === 232 /* OmittedExpression */) {
      return;
    }
    if (e.name) {
      if (!getBindingNameVisible(e)) return;
      if (isBindingPattern(e.name)) {
        return recreateBindingPattern(e.name);
      } else {
        return factory2.createVariableDeclaration(
          e.name,
          /*exclamationToken*/
          void 0,
          ensureType(
            e,
            /*type*/
            void 0
          ),
          /*initializer*/
          void 0
        );
      }
    }
  }
  function checkName(node) {
    let oldDiag;
    if (!suppressNewDiagnosticContexts) {
      oldDiag = getSymbolAccessibilityDiagnostic;
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNodeName(node);
    }
    errorNameNode = node.name;
    Debug.assert(hasDynamicName(node));
    const decl = node;
    const entityName = decl.name.expression;
    checkEntityNameVisibility(entityName, enclosingDeclaration);
    if (!suppressNewDiagnosticContexts) {
      getSymbolAccessibilityDiagnostic = oldDiag;
    }
    errorNameNode = void 0;
  }
  function shouldStripInternal(node) {
    return !!stripInternal && !!node && isInternalDeclaration(node, currentSourceFile);
  }
  function isScopeMarker2(node) {
    return isExportAssignment(node) || isExportDeclaration(node);
  }
  function hasScopeMarker2(statements) {
    return some(statements, isScopeMarker2);
  }
  function ensureModifiers(node) {
    const currentFlags = getEffectiveModifierFlags(node);
    const newFlags = ensureModifierFlags(node);
    if (currentFlags === newFlags) {
      return visitArray(node.modifiers, (n) => tryCast(n, isModifier), isModifier);
    }
    return factory2.createModifiersFromModifierFlags(newFlags);
  }
  function ensureModifierFlags(node) {
    let mask = 131071 /* All */ ^ (1 /* Public */ | 1024 /* Async */ | 16 /* Override */);
    let additions = needsDeclare && !isAlwaysType(node) ? 128 /* Ambient */ : 0 /* None */;
    const parentIsFile = node.parent.kind === 307 /* SourceFile */;
    if (!parentIsFile || isBundledEmit && parentIsFile && isExternalModule(node.parent)) {
      mask ^= 128 /* Ambient */;
      additions = 0 /* None */;
    }
    return maskModifierFlags(node, mask, additions);
  }
  function getTypeAnnotationFromAllAccessorDeclarations(node, accessors) {
    let accessorType = getTypeAnnotationFromAccessor(node);
    if (!accessorType && node !== accessors.firstAccessor) {
      accessorType = getTypeAnnotationFromAccessor(accessors.firstAccessor);
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(accessors.firstAccessor);
    }
    if (!accessorType && accessors.secondAccessor && node !== accessors.secondAccessor) {
      accessorType = getTypeAnnotationFromAccessor(accessors.secondAccessor);
      getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(accessors.secondAccessor);
    }
    return accessorType;
  }
  function transformHeritageClauses(nodes) {
    return factory2.createNodeArray(filter(
      map(nodes, (clause) => factory2.updateHeritageClause(
        clause,
        visitNodes2(
          factory2.createNodeArray(filter(clause.types, (t) => {
            return isEntityNameExpression(t.expression) || clause.token === 96 /* ExtendsKeyword */ && t.expression.kind === 106 /* NullKeyword */;
          })),
          visitDeclarationSubtree,
          isExpressionWithTypeArguments
        )
      )),
      (clause) => clause.types && !!clause.types.length
    ));
  }
}
function isAlwaysType(node) {
  if (node.kind === 264 /* InterfaceDeclaration */) {
    return true;
  }
  return false;
}
function maskModifiers(factory2, node, modifierMask, modifierAdditions) {
  return factory2.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions));
}
function maskModifierFlags(node, modifierMask = 131071 /* All */ ^ 1 /* Public */, modifierAdditions = 0 /* None */) {
  let flags = getEffectiveModifierFlags(node) & modifierMask | modifierAdditions;
  if (flags & 2048 /* Default */ && !(flags & 32 /* Export */)) {
    flags ^= 32 /* Export */;
  }
  if (flags & 2048 /* Default */ && flags & 128 /* Ambient */) {
    flags ^= 128 /* Ambient */;
  }
  return flags;
}
function getTypeAnnotationFromAccessor(accessor) {
  if (accessor) {
    return accessor.kind === 177 /* GetAccessor */ ? accessor.type : accessor.parameters.length > 0 ? accessor.parameters[0].type : void 0;
  }
}
function canHaveLiteralInitializer(node) {
  switch (node.kind) {
    case 172 /* PropertyDeclaration */:
    case 171 /* PropertySignature */:
      return !hasEffectiveModifier(node, 2 /* Private */);
    case 169 /* Parameter */:
    case 260 /* VariableDeclaration */:
      return true;
  }
  return false;
}
function isPreservedDeclarationStatement(node) {
  switch (node.kind) {
    case 262 /* FunctionDeclaration */:
    case 267 /* ModuleDeclaration */:
    case 271 /* ImportEqualsDeclaration */:
    case 264 /* InterfaceDeclaration */:
    case 263 /* ClassDeclaration */:
    case 265 /* TypeAliasDeclaration */:
    case 266 /* EnumDeclaration */:
    case 243 /* VariableStatement */:
    case 272 /* ImportDeclaration */:
    case 278 /* ExportDeclaration */:
    case 277 /* ExportAssignment */:
      return true;
  }
  return false;
}
function isProcessedComponent(node) {
  switch (node.kind) {
    case 180 /* ConstructSignature */:
    case 176 /* Constructor */:
    case 174 /* MethodDeclaration */:
    case 177 /* GetAccessor */:
    case 178 /* SetAccessor */:
    case 172 /* PropertyDeclaration */:
    case 171 /* PropertySignature */:
    case 173 /* MethodSignature */:
    case 179 /* CallSignature */:
    case 181 /* IndexSignature */:
    case 260 /* VariableDeclaration */:
    case 168 /* TypeParameter */:
    case 233 /* ExpressionWithTypeArguments */:
    case 183 /* TypeReference */:
    case 194 /* ConditionalType */:
    case 184 /* FunctionType */:
    case 185 /* ConstructorType */:
    case 205 /* ImportType */:
      return true;
  }
  return false;
}

// src/compiler/transformer.ts
function getModuleTransformer(moduleKind) {
  switch (moduleKind) {
    case 99 /* ESNext */:
    case 7 /* ES2022 */:
    case 6 /* ES2020 */:
    case 5 /* ES2015 */:
    case 200 /* Preserve */:
      return transformECMAScriptModule;
    case 4 /* System */:
      return transformSystemModule;
    case 100 /* Node16 */:
    case 199 /* NodeNext */:
      return transformNodeModule;
    default:
      return transformModule;
  }
}
var noTransformers = { scriptTransformers: emptyArray, declarationTransformers: emptyArray };
function getTransformers(compilerOptions, customTransformers, emitOnly) {
  return {
    scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnly),
    declarationTransformers: getDeclarationTransformers(customTransformers)
  };
}
function getScriptTransformers(compilerOptions, customTransformers, emitOnly) {
  if (emitOnly) return emptyArray;
  const languageVersion = getEmitScriptTarget(compilerOptions);
  const moduleKind = getEmitModuleKind(compilerOptions);
  const useDefineForClassFields = getUseDefineForClassFields(compilerOptions);
  const transformers = [];
  addRange(transformers, customTransformers && map(customTransformers.before, wrapScriptTransformerFactory));
  transformers.push(transformTypeScript);
  if (compilerOptions.experimentalDecorators) {
    transformers.push(transformLegacyDecorators);
  }
  if (getJSXTransformEnabled(compilerOptions)) {
    transformers.push(transformJsx);
  }
  if (languageVersion < 99 /* ESNext */) {
    transformers.push(transformESNext);
  }
  if (!compilerOptions.experimentalDecorators && (languageVersion < 99 /* ESNext */ || !useDefineForClassFields)) {
    transformers.push(transformESDecorators);
  }
  transformers.push(transformClassFields);
  if (languageVersion < 8 /* ES2021 */) {
    transformers.push(transformES2021);
  }
  if (languageVersion < 7 /* ES2020 */) {
    transformers.push(transformES2020);
  }
  if (languageVersion < 6 /* ES2019 */) {
    transformers.push(transformES2019);
  }
  if (languageVersion < 5 /* ES2018 */) {
    transformers.push(transformES2018);
  }
  if (languageVersion < 4 /* ES2017 */) {
    transformers.push(transformES2017);
  }
  if (languageVersion < 3 /* ES2016 */) {
    transformers.push(transformES2016);
  }
  if (languageVersion < 2 /* ES2015 */) {
    transformers.push(transformES2015);
    transformers.push(transformGenerators);
  }
  transformers.push(getModuleTransformer(moduleKind));
  addRange(transformers, customTransformers && map(customTransformers.after, wrapScriptTransformerFactory));
  return transformers;
}
function getDeclarationTransformers(customTransformers) {
  const transformers = [];
  transformers.push(transformDeclarations);
  addRange(transformers, customTransformers && map(customTransformers.afterDeclarations, wrapDeclarationTransformerFactory));
  return transformers;
}
function wrapCustomTransformer(transformer) {
  return (node) => isBundle(node) ? transformer.transformBundle(node) : transformer.transformSourceFile(node);
}
function wrapCustomTransformerFactory(transformer, handleDefault) {
  return (context) => {
    const customTransformer = transformer(context);
    return typeof customTransformer === "function" ? handleDefault(context, customTransformer) : wrapCustomTransformer(customTransformer);
  };
}
function wrapScriptTransformerFactory(transformer) {
  return wrapCustomTransformerFactory(transformer, chainBundle);
}
function wrapDeclarationTransformerFactory(transformer) {
  return wrapCustomTransformerFactory(transformer, (_, node) => node);
}
function noEmitSubstitution(_hint, node) {
  return node;
}
function noEmitNotification(hint, node, callback) {
  callback(hint, node);
}
function transformNodes(resolver, host, factory2, options, nodes, transformers, allowDtsFiles) {
  var _a, _b;
  const enabledSyntaxKindFeatures = new Array(357 /* Count */);
  let lexicalEnvironmentVariableDeclarations;
  let lexicalEnvironmentFunctionDeclarations;
  let lexicalEnvironmentStatements;
  let lexicalEnvironmentFlags = 0 /* None */;
  let lexicalEnvironmentVariableDeclarationsStack = [];
  let lexicalEnvironmentFunctionDeclarationsStack = [];
  let lexicalEnvironmentStatementsStack = [];
  let lexicalEnvironmentFlagsStack = [];
  let lexicalEnvironmentStackOffset = 0;
  let lexicalEnvironmentSuspended = false;
  let blockScopedVariableDeclarationsStack = [];
  let blockScopeStackOffset = 0;
  let blockScopedVariableDeclarations;
  let emitHelpers;
  let onSubstituteNode = noEmitSubstitution;
  let onEmitNode = noEmitNotification;
  let state = 0 /* Uninitialized */;
  const diagnostics = [];
  const context = {
    factory: factory2,
    getCompilerOptions: () => options,
    getEmitResolver: () => resolver,
    // TODO: GH#18217
    getEmitHost: () => host,
    // TODO: GH#18217
    getEmitHelperFactory: memoize(() => createEmitHelperFactory(context)),
    startLexicalEnvironment,
    suspendLexicalEnvironment,
    resumeLexicalEnvironment,
    endLexicalEnvironment,
    setLexicalEnvironmentFlags,
    getLexicalEnvironmentFlags,
    hoistVariableDeclaration,
    hoistFunctionDeclaration,
    addInitializationStatement,
    startBlockScope,
    endBlockScope,
    addBlockScopedVariable,
    requestEmitHelper,
    readEmitHelpers,
    enableSubstitution,
    enableEmitNotification,
    isSubstitutionEnabled,
    isEmitNotificationEnabled,
    get onSubstituteNode() {
      return onSubstituteNode;
    },
    set onSubstituteNode(value) {
      Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
      Debug.assert(value !== void 0, "Value must not be 'undefined'");
      onSubstituteNode = value;
    },
    get onEmitNode() {
      return onEmitNode;
    },
    set onEmitNode(value) {
      Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
      Debug.assert(value !== void 0, "Value must not be 'undefined'");
      onEmitNode = value;
    },
    addDiagnostic(diag2) {
      diagnostics.push(diag2);
    }
  };
  for (const node of nodes) {
    disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
  }
  mark("beforeTransform");
  const transformersWithContext = transformers.map((t) => t(context));
  const transformation = (node) => {
    for (const transform of transformersWithContext) {
      node = transform(node);
    }
    return node;
  };
  state = 1 /* Initialized */;
  const transformed = [];
  for (const node of nodes) {
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Emit, "transformNodes", node.kind === 307 /* SourceFile */ ? { path: node.path } : { kind: node.kind, pos: node.pos, end: node.end });
    transformed.push((allowDtsFiles ? transformation : transformRoot)(node));
    (_b = tracing) == null ? void 0 : _b.pop();
  }
  state = 2 /* Completed */;
  mark("afterTransform");
  measure("transformTime", "beforeTransform", "afterTransform");
  return {
    transformed,
    substituteNode,
    emitNodeWithNotification,
    isEmitNotificationEnabled,
    dispose,
    diagnostics
  };
  function transformRoot(node) {
    return node && (!isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node;
  }
  function enableSubstitution(kind) {
    Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
    enabledSyntaxKindFeatures[kind] |= 1 /* Substitution */;
  }
  function isSubstitutionEnabled(node) {
    return (enabledSyntaxKindFeatures[node.kind] & 1 /* Substitution */) !== 0 && (getEmitFlags(node) & 8 /* NoSubstitution */) === 0;
  }
  function substituteNode(hint, node) {
    Debug.assert(state < 3 /* Disposed */, "Cannot substitute a node after the result is disposed.");
    return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
  }
  function enableEmitNotification(kind) {
    Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
    enabledSyntaxKindFeatures[kind] |= 2 /* EmitNotifications */;
  }
  function isEmitNotificationEnabled(node) {
    return (enabledSyntaxKindFeatures[node.kind] & 2 /* EmitNotifications */) !== 0 || (getEmitFlags(node) & 4 /* AdviseOnEmitNode */) !== 0;
  }
  function emitNodeWithNotification(hint, node, emitCallback) {
    Debug.assert(state < 3 /* Disposed */, "Cannot invoke TransformationResult callbacks after the result is disposed.");
    if (node) {
      if (isEmitNotificationEnabled(node)) {
        onEmitNode(hint, node, emitCallback);
      } else {
        emitCallback(hint, node);
      }
    }
  }
  function hoistVariableDeclaration(name) {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
    const decl = setEmitFlags(factory2.createVariableDeclaration(name), 128 /* NoNestedSourceMaps */);
    if (!lexicalEnvironmentVariableDeclarations) {
      lexicalEnvironmentVariableDeclarations = [decl];
    } else {
      lexicalEnvironmentVariableDeclarations.push(decl);
    }
    if (lexicalEnvironmentFlags & 1 /* InParameters */) {
      lexicalEnvironmentFlags |= 2 /* VariablesHoistedInParameters */;
    }
  }
  function hoistFunctionDeclaration(func) {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
    setEmitFlags(func, 2097152 /* CustomPrologue */);
    if (!lexicalEnvironmentFunctionDeclarations) {
      lexicalEnvironmentFunctionDeclarations = [func];
    } else {
      lexicalEnvironmentFunctionDeclarations.push(func);
    }
  }
  function addInitializationStatement(node) {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
    setEmitFlags(node, 2097152 /* CustomPrologue */);
    if (!lexicalEnvironmentStatements) {
      lexicalEnvironmentStatements = [node];
    } else {
      lexicalEnvironmentStatements.push(node);
    }
  }
  function startLexicalEnvironment() {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
    Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
    lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
    lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
    lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentStatements;
    lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFlags;
    lexicalEnvironmentStackOffset++;
    lexicalEnvironmentVariableDeclarations = void 0;
    lexicalEnvironmentFunctionDeclarations = void 0;
    lexicalEnvironmentStatements = void 0;
    lexicalEnvironmentFlags = 0 /* None */;
  }
  function suspendLexicalEnvironment() {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
    Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
    lexicalEnvironmentSuspended = true;
  }
  function resumeLexicalEnvironment() {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
    Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
    lexicalEnvironmentSuspended = false;
  }
  function endLexicalEnvironment() {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
    Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
    let statements;
    if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations || lexicalEnvironmentStatements) {
      if (lexicalEnvironmentFunctionDeclarations) {
        statements = [...lexicalEnvironmentFunctionDeclarations];
      }
      if (lexicalEnvironmentVariableDeclarations) {
        const statement = factory2.createVariableStatement(
          /*modifiers*/
          void 0,
          factory2.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations)
        );
        setEmitFlags(statement, 2097152 /* CustomPrologue */);
        if (!statements) {
          statements = [statement];
        } else {
          statements.push(statement);
        }
      }
      if (lexicalEnvironmentStatements) {
        if (!statements) {
          statements = [...lexicalEnvironmentStatements];
        } else {
          statements = [...statements, ...lexicalEnvironmentStatements];
        }
      }
    }
    lexicalEnvironmentStackOffset--;
    lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
    lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
    lexicalEnvironmentStatements = lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset];
    lexicalEnvironmentFlags = lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset];
    if (lexicalEnvironmentStackOffset === 0) {
      lexicalEnvironmentVariableDeclarationsStack = [];
      lexicalEnvironmentFunctionDeclarationsStack = [];
      lexicalEnvironmentStatementsStack = [];
      lexicalEnvironmentFlagsStack = [];
    }
    return statements;
  }
  function setLexicalEnvironmentFlags(flags, value) {
    lexicalEnvironmentFlags = value ? lexicalEnvironmentFlags | flags : lexicalEnvironmentFlags & ~flags;
  }
  function getLexicalEnvironmentFlags() {
    return lexicalEnvironmentFlags;
  }
  function startBlockScope() {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot start a block scope during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot start a block scope after transformation has completed.");
    blockScopedVariableDeclarationsStack[blockScopeStackOffset] = blockScopedVariableDeclarations;
    blockScopeStackOffset++;
    blockScopedVariableDeclarations = void 0;
  }
  function endBlockScope() {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot end a block scope during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot end a block scope after transformation has completed.");
    const statements = some(blockScopedVariableDeclarations) ? [
      factory2.createVariableStatement(
        /*modifiers*/
        void 0,
        factory2.createVariableDeclarationList(
          blockScopedVariableDeclarations.map((identifier) => factory2.createVariableDeclaration(identifier)),
          1 /* Let */
        )
      )
    ] : void 0;
    blockScopeStackOffset--;
    blockScopedVariableDeclarations = blockScopedVariableDeclarationsStack[blockScopeStackOffset];
    if (blockScopeStackOffset === 0) {
      blockScopedVariableDeclarationsStack = [];
    }
    return statements;
  }
  function addBlockScopedVariable(name) {
    Debug.assert(blockScopeStackOffset > 0, "Cannot add a block scoped variable outside of an iteration body.");
    (blockScopedVariableDeclarations || (blockScopedVariableDeclarations = [])).push(name);
  }
  function requestEmitHelper(helper) {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
    Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
    if (helper.dependencies) {
      for (const h of helper.dependencies) {
        requestEmitHelper(h);
      }
    }
    emitHelpers = append(emitHelpers, helper);
  }
  function readEmitHelpers() {
    Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
    Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
    const helpers = emitHelpers;
    emitHelpers = void 0;
    return helpers;
  }
  function dispose() {
    if (state < 3 /* Disposed */) {
      for (const node of nodes) {
        disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
      }
      lexicalEnvironmentVariableDeclarations = void 0;
      lexicalEnvironmentVariableDeclarationsStack = void 0;
      lexicalEnvironmentFunctionDeclarations = void 0;
      lexicalEnvironmentFunctionDeclarationsStack = void 0;
      onSubstituteNode = void 0;
      onEmitNode = void 0;
      emitHelpers = void 0;
      state = 3 /* Disposed */;
    }
  }
}
var nullTransformationContext = {
  factory,
  // eslint-disable-line object-shorthand
  getCompilerOptions: () => ({}),
  getEmitResolver: notImplemented,
  getEmitHost: notImplemented,
  getEmitHelperFactory: notImplemented,
  startLexicalEnvironment: noop,
  resumeLexicalEnvironment: noop,
  suspendLexicalEnvironment: noop,
  endLexicalEnvironment: returnUndefined,
  setLexicalEnvironmentFlags: noop,
  getLexicalEnvironmentFlags: () => 0,
  hoistVariableDeclaration: noop,
  hoistFunctionDeclaration: noop,
  addInitializationStatement: noop,
  startBlockScope: noop,
  endBlockScope: returnUndefined,
  addBlockScopedVariable: noop,
  requestEmitHelper: noop,
  readEmitHelpers: notImplemented,
  enableSubstitution: noop,
  enableEmitNotification: noop,
  isSubstitutionEnabled: notImplemented,
  isEmitNotificationEnabled: notImplemented,
  onSubstituteNode: noEmitSubstitution,
  onEmitNode: noEmitNotification,
  addDiagnostic: noop
};

// src/compiler/emitter.ts
var brackets = createBracketsMap();
function isBuildInfoFile(file) {
  return fileExtensionIs(file, ".tsbuildinfo" /* TsBuildInfo */);
}
function forEachEmittedFile(host, action, sourceFilesOrTargetSourceFile, forceDtsEmit = false, onlyBuildInfo, includeBuildInfo) {
  const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile, forceDtsEmit);
  const options = host.getCompilerOptions();
  if (options.outFile) {
    if (sourceFiles.length) {
      const bundle = factory.createBundle(sourceFiles);
      const result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle);
      if (result) {
        return result;
      }
    }
  } else {
    if (!onlyBuildInfo) {
      for (const sourceFile of sourceFiles) {
        const result = action(getOutputPathsFor(sourceFile, host, forceDtsEmit), sourceFile);
        if (result) {
          return result;
        }
      }
    }
    if (includeBuildInfo) {
      const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
      if (buildInfoPath) return action(
        { buildInfoPath },
        /*sourceFileOrBundle*/
        void 0
      );
    }
  }
}
function getTsBuildInfoEmitOutputFilePath(options) {
  const configFile = options.configFilePath;
  if (!isIncrementalCompilation(options)) return void 0;
  if (options.tsBuildInfoFile) return options.tsBuildInfoFile;
  const outPath = options.outFile;
  let buildInfoExtensionLess;
  if (outPath) {
    buildInfoExtensionLess = removeFileExtension(outPath);
  } else {
    if (!configFile) return void 0;
    const configFileExtensionLess = removeFileExtension(configFile);
    buildInfoExtensionLess = options.outDir ? options.rootDir ? resolvePath(options.outDir, getRelativePathFromDirectory(
      options.rootDir,
      configFileExtensionLess,
      /*ignoreCase*/
      true
    )) : combinePaths(options.outDir, getBaseFileName(configFileExtensionLess)) : configFileExtensionLess;
  }
  return buildInfoExtensionLess + ".tsbuildinfo" /* TsBuildInfo */;
}
function getOutputPathsForBundle(options, forceDtsPaths) {
  const outPath = options.outFile;
  const jsFilePath = options.emitDeclarationOnly ? void 0 : outPath;
  const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
  const declarationFilePath = forceDtsPaths || getEmitDeclarations(options) ? removeFileExtension(outPath) + ".d.ts" /* Dts */ : void 0;
  const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : void 0;
  const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
  return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath };
}
function getOutputPathsFor(sourceFile, host, forceDtsPaths) {
  const options = host.getCompilerOptions();
  if (sourceFile.kind === 308 /* Bundle */) {
    return getOutputPathsForBundle(options, forceDtsPaths);
  } else {
    const ownOutputFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile.fileName, options));
    const isJsonFile = isJsonSourceFile(sourceFile);
    const isJsonEmittedToSameLocation = isJsonFile && comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
    const jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? void 0 : ownOutputFilePath;
    const sourceMapFilePath = !jsFilePath || isJsonSourceFile(sourceFile) ? void 0 : getSourceMapFilePath(jsFilePath, options);
    const declarationFilePath = forceDtsPaths || getEmitDeclarations(options) && !isJsonFile ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : void 0;
    const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : void 0;
    return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath: void 0 };
  }
}
function getSourceMapFilePath(jsFilePath, options) {
  return options.sourceMap && !options.inlineSourceMap ? jsFilePath + ".map" : void 0;
}
function getOutputExtension(fileName, options) {
  return fileExtensionIs(fileName, ".json" /* Json */) ? ".json" /* Json */ : options.jsx === 1 /* Preserve */ && fileExtensionIsOneOf(fileName, [".jsx" /* Jsx */, ".tsx" /* Tsx */]) ? ".jsx" /* Jsx */ : fileExtensionIsOneOf(fileName, [".mts" /* Mts */, ".mjs" /* Mjs */]) ? ".mjs" /* Mjs */ : fileExtensionIsOneOf(fileName, [".cts" /* Cts */, ".cjs" /* Cjs */]) ? ".cjs" /* Cjs */ : ".js" /* Js */;
}
function getOutputPathWithoutChangingExt(inputFileName, ignoreCase, outputDir, getCommonSourceDirectory2) {
  return outputDir ? resolvePath(
    outputDir,
    getRelativePathFromDirectory(getCommonSourceDirectory2(), inputFileName, ignoreCase)
  ) : inputFileName;
}
function getOutputDeclarationFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory2 = () => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)) {
  return getOutputDeclarationFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory2);
}
function getOutputDeclarationFileNameWorker(inputFileName, options, ignoreCase, getCommonSourceDirectory2) {
  return changeExtension(
    getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.declarationDir || options.outDir, getCommonSourceDirectory2),
    getDeclarationEmitExtensionForPath(inputFileName)
  );
}
function getOutputJSFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory2 = () => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)) {
  if (configFile.options.emitDeclarationOnly) return void 0;
  const isJsonFile = fileExtensionIs(inputFileName, ".json" /* Json */);
  const outputFileName = getOutputJSFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory2);
  return !isJsonFile || comparePaths(inputFileName, outputFileName, Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== 0 /* EqualTo */ ? outputFileName : void 0;
}
function getOutputJSFileNameWorker(inputFileName, options, ignoreCase, getCommonSourceDirectory2) {
  return changeExtension(
    getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.outDir, getCommonSourceDirectory2),
    getOutputExtension(inputFileName, options)
  );
}
function createAddOutput() {
  let outputs;
  return { addOutput, getOutputs };
  function addOutput(path) {
    if (path) {
      (outputs || (outputs = [])).push(path);
    }
  }
  function getOutputs() {
    return outputs || emptyArray;
  }
}
function getSingleOutputFileNames(configFile, addOutput) {
  const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(
    configFile.options,
    /*forceDtsPaths*/
    false
  );
  addOutput(jsFilePath);
  addOutput(sourceMapFilePath);
  addOutput(declarationFilePath);
  addOutput(declarationMapPath);
  addOutput(buildInfoPath);
}
function getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput, getCommonSourceDirectory2) {
  if (isDeclarationFileName(inputFileName)) return;
  const js = getOutputJSFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory2);
  addOutput(js);
  if (fileExtensionIs(inputFileName, ".json" /* Json */)) return;
  if (js && configFile.options.sourceMap) {
    addOutput(`${js}.map`);
  }
  if (getEmitDeclarations(configFile.options)) {
    const dts = getOutputDeclarationFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory2);
    addOutput(dts);
    if (configFile.options.declarationMap) {
      addOutput(`${dts}.map`);
    }
  }
}
function getCommonSourceDirectory(options, emittedFiles, currentDirectory, getCanonicalFileName, checkSourceFilesBelongToPath) {
  let commonSourceDirectory;
  if (options.rootDir) {
    commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
    checkSourceFilesBelongToPath == null ? void 0 : checkSourceFilesBelongToPath(options.rootDir);
  } else if (options.composite && options.configFilePath) {
    commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath));
    checkSourceFilesBelongToPath == null ? void 0 : checkSourceFilesBelongToPath(commonSourceDirectory);
  } else {
    commonSourceDirectory = computeCommonSourceDirectoryOfFilenames(emittedFiles(), currentDirectory, getCanonicalFileName);
  }
  if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
    commonSourceDirectory += directorySeparator;
  }
  return commonSourceDirectory;
}
function getCommonSourceDirectoryOfConfig({ options, fileNames }, ignoreCase) {
  return getCommonSourceDirectory(
    options,
    () => filter(fileNames, (file) => !(options.noEmitForJsFiles && fileExtensionIsOneOf(file, supportedJSExtensionsFlat)) && !isDeclarationFileName(file)),
    getDirectoryPath(normalizeSlashes(Debug.checkDefined(options.configFilePath))),
    createGetCanonicalFileName(!ignoreCase)
  );
}
function getAllProjectOutputs(configFile, ignoreCase) {
  const { addOutput, getOutputs } = createAddOutput();
  if (configFile.options.outFile) {
    getSingleOutputFileNames(configFile, addOutput);
  } else {
    const getCommonSourceDirectory2 = memoize(() => getCommonSourceDirectoryOfConfig(configFile, ignoreCase));
    for (const inputFileName of configFile.fileNames) {
      getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput, getCommonSourceDirectory2);
    }
    addOutput(getTsBuildInfoEmitOutputFilePath(configFile.options));
  }
  return getOutputs();
}
function getFirstProjectOutput(configFile, ignoreCase) {
  if (configFile.options.outFile) {
    const { jsFilePath, declarationFilePath } = getOutputPathsForBundle(
      configFile.options,
      /*forceDtsPaths*/
      false
    );
    return Debug.checkDefined(jsFilePath || declarationFilePath, `project ${configFile.options.configFilePath} expected to have at least one output`);
  }
  const getCommonSourceDirectory2 = memoize(() => getCommonSourceDirectoryOfConfig(configFile, ignoreCase));
  for (const inputFileName of configFile.fileNames) {
    if (isDeclarationFileName(inputFileName)) continue;
    const jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory2);
    if (jsFilePath) return jsFilePath;
    if (fileExtensionIs(inputFileName, ".json" /* Json */)) continue;
    if (getEmitDeclarations(configFile.options)) {
      return getOutputDeclarationFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory2);
    }
  }
  const buildInfoPath = getTsBuildInfoEmitOutputFilePath(configFile.options);
  if (buildInfoPath) return buildInfoPath;
  return Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`);
}
function emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit) {
  return !!forceDtsEmit && !!emitOnly;
}
function emitFiles(resolver, host, targetSourceFile, { scriptTransformers, declarationTransformers }, emitOnly, onlyBuildInfo, forceDtsEmit) {
  var compilerOptions = host.getCompilerOptions();
  var sourceMapDataList = compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions) ? [] : void 0;
  var emittedFilesList = compilerOptions.listEmittedFiles ? [] : void 0;
  var emitterDiagnostics = createDiagnosticCollection();
  var newLine = getNewLineCharacter(compilerOptions);
  var writer = createTextWriter(newLine);
  var { enter, exit } = createTimer("printTime", "beforePrint", "afterPrint");
  var emitSkipped = false;
  enter();
  forEachEmittedFile(
    host,
    emitSourceFileOrBundle,
    getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit),
    forceDtsEmit,
    onlyBuildInfo,
    !targetSourceFile
  );
  exit();
  return {
    emitSkipped,
    diagnostics: emitterDiagnostics.getDiagnostics(),
    emittedFiles: emittedFilesList,
    sourceMaps: sourceMapDataList
  };
  function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath }, sourceFileOrBundle) {
    var _a, _b, _c, _d, _e, _f;
    (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Emit, "emitJsFileOrBundle", { jsFilePath });
    emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath);
    (_b = tracing) == null ? void 0 : _b.pop();
    (_c = tracing) == null ? void 0 : _c.push(tracing.Phase.Emit, "emitDeclarationFileOrBundle", { declarationFilePath });
    emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath);
    (_d = tracing) == null ? void 0 : _d.pop();
    (_e = tracing) == null ? void 0 : _e.push(tracing.Phase.Emit, "emitBuildInfo", { buildInfoPath });
    emitBuildInfo(buildInfoPath);
    (_f = tracing) == null ? void 0 : _f.pop();
  }
  function emitBuildInfo(buildInfoPath) {
    if (!buildInfoPath || targetSourceFile || emitSkipped) return;
    if (host.isEmitBlocked(buildInfoPath)) {
      emitSkipped = true;
      return;
    }
    const buildInfo = host.getBuildInfo() || createBuildInfo(
      /*program*/
      void 0
    );
    writeFile(
      host,
      emitterDiagnostics,
      buildInfoPath,
      getBuildInfoText(buildInfo),
      /*writeByteOrderMark*/
      false,
      /*sourceFiles*/
      void 0,
      { buildInfo }
    );
    emittedFilesList == null ? void 0 : emittedFilesList.push(buildInfoPath);
  }
  function emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath) {
    if (!sourceFileOrBundle || emitOnly || !jsFilePath) {
      return;
    }
    if (host.isEmitBlocked(jsFilePath) || compilerOptions.noEmit) {
      emitSkipped = true;
      return;
    }
    (isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(
      (sourceFile) => {
        if (compilerOptions.noCheck || !canIncludeBindAndCheckDiagnsotics(sourceFile, compilerOptions)) markLinkedReferences(sourceFile);
      }
    );
    const transform = transformNodes(
      resolver,
      host,
      factory,
      compilerOptions,
      [sourceFileOrBundle],
      scriptTransformers,
      /*allowDtsFiles*/
      false
    );
    const printerOptions = {
      removeComments: compilerOptions.removeComments,
      newLine: compilerOptions.newLine,
      noEmitHelpers: compilerOptions.noEmitHelpers,
      module: getEmitModuleKind(compilerOptions),
      target: getEmitScriptTarget(compilerOptions),
      sourceMap: compilerOptions.sourceMap,
      inlineSourceMap: compilerOptions.inlineSourceMap,
      inlineSources: compilerOptions.inlineSources,
      extendedDiagnostics: compilerOptions.extendedDiagnostics
    };
    const printer = createPrinter(printerOptions, {
      // resolver hooks
      hasGlobalName: resolver.hasGlobalName,
      // transform hooks
      onEmitNode: transform.emitNodeWithNotification,
      isEmitNotificationEnabled: transform.isEmitNotificationEnabled,
      substituteNode: transform.substituteNode
    });
    Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform");
    printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform, printer, compilerOptions);
    transform.dispose();
    if (emittedFilesList) {
      emittedFilesList.push(jsFilePath);
      if (sourceMapFilePath) {
        emittedFilesList.push(sourceMapFilePath);
      }
    }
  }
  function emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath) {
    if (!sourceFileOrBundle || emitOnly === 0 /* Js */) return;
    if (!declarationFilePath) {
      if (emitOnly || compilerOptions.emitDeclarationOnly) emitSkipped = true;
      return;
    }
    const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
    const filesForEmit = forceDtsEmit ? sourceFiles : filter(sourceFiles, isSourceFileNotJson);
    const inputListOrBundle = compilerOptions.outFile ? [factory.createBundle(filesForEmit)] : filesForEmit;
    filesForEmit.forEach((sourceFile) => {
      if (emitOnly && !getEmitDeclarations(compilerOptions) || compilerOptions.noCheck || emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit) || !canIncludeBindAndCheckDiagnsotics(sourceFile, compilerOptions)) {
        collectLinkedAliases(sourceFile);
      }
    });
    const declarationTransform = transformNodes(
      resolver,
      host,
      factory,
      compilerOptions,
      inputListOrBundle,
      declarationTransformers,
      /*allowDtsFiles*/
      false
    );
    if (length(declarationTransform.diagnostics)) {
      for (const diagnostic of declarationTransform.diagnostics) {
        emitterDiagnostics.add(diagnostic);
      }
    }
    const declBlocked = !!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit;
    emitSkipped = emitSkipped || declBlocked;
    if (!declBlocked || forceDtsEmit) {
      Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
      const printerOptions = {
        removeComments: compilerOptions.removeComments,
        newLine: compilerOptions.newLine,
        noEmitHelpers: true,
        module: compilerOptions.module,
        target: compilerOptions.target,
        sourceMap: emitOnly !== 2 /* BuilderSignature */ && compilerOptions.declarationMap,
        inlineSourceMap: compilerOptions.inlineSourceMap,
        extendedDiagnostics: compilerOptions.extendedDiagnostics,
        onlyPrintJsDocStyle: true,
        omitBraceSourceMapPositions: true
      };
      const declarationPrinter = createPrinter(printerOptions, {
        // resolver hooks
        hasGlobalName: resolver.hasGlobalName,
        // transform hooks
        onEmitNode: declarationTransform.emitNodeWithNotification,
        isEmitNotificationEnabled: declarationTransform.isEmitNotificationEnabled,
        substituteNode: declarationTransform.substituteNode
      });
      printSourceFileOrBundle(
        declarationFilePath,
        declarationMapPath,
        declarationTransform,
        declarationPrinter,
        {
          sourceMap: printerOptions.sourceMap,
          sourceRoot: compilerOptions.sourceRoot,
          mapRoot: compilerOptions.mapRoot,
          extendedDiagnostics: compilerOptions.extendedDiagnostics
          // Explicitly do not passthru either `inline` option
        }
      );
      if (emittedFilesList) {
        emittedFilesList.push(declarationFilePath);
        if (declarationMapPath) {
          emittedFilesList.push(declarationMapPath);
        }
      }
    }
    declarationTransform.dispose();
  }
  function collectLinkedAliases(node) {
    if (isExportAssignment(node)) {
      if (node.expression.kind === 80 /* Identifier */) {
        resolver.collectLinkedAliases(
          node.expression,
          /*setVisibility*/
          true
        );
      }
      return;
    } else if (isExportSpecifier(node)) {
      resolver.collectLinkedAliases(
        node.propertyName || node.name,
        /*setVisibility*/
        true
      );
      return;
    }
    forEachChild(node, collectLinkedAliases);
  }
  function markLinkedReferences(file) {
    forEachChildRecursively(file, (n) => {
      if (isImportEqualsDeclaration(n) && !(getSyntacticModifierFlags(n) & 32 /* Export */)) return "skip";
      if (isImportDeclaration(n)) return "skip";
      resolver.markLinkedReferences(n);
    });
  }
  function printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform, printer, mapOptions) {
    const sourceFileOrBundle = transform.transformed[0];
    const bundle = sourceFileOrBundle.kind === 308 /* Bundle */ ? sourceFileOrBundle : void 0;
    const sourceFile = sourceFileOrBundle.kind === 307 /* SourceFile */ ? sourceFileOrBundle : void 0;
    const sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
    let sourceMapGenerator;
    if (shouldEmitSourceMaps(mapOptions, sourceFileOrBundle)) {
      sourceMapGenerator = createSourceMapGenerator(
        host,
        getBaseFileName(normalizeSlashes(jsFilePath)),
        getSourceRoot(mapOptions),
        getSourceMapDirectory(mapOptions, jsFilePath, sourceFile),
        mapOptions
      );
    }
    if (bundle) {
      printer.writeBundle(bundle, writer, sourceMapGenerator);
    } else {
      printer.writeFile(sourceFile, writer, sourceMapGenerator);
    }
    let sourceMapUrlPos;
    if (sourceMapGenerator) {
      if (sourceMapDataList) {
        sourceMapDataList.push({
          inputSourceFileNames: sourceMapGenerator.getSources(),
          sourceMap: sourceMapGenerator.toJSON()
        });
      }
      const sourceMappingURL = getSourceMappingURL(
        mapOptions,
        sourceMapGenerator,
        jsFilePath,
        sourceMapFilePath,
        sourceFile
      );
      if (sourceMappingURL) {
        if (!writer.isAtStartOfLine()) writer.rawWrite(newLine);
        sourceMapUrlPos = writer.getTextPos();
        writer.writeComment(`//# ${"sourceMappingURL"}=${sourceMappingURL}`);
      }
      if (sourceMapFilePath) {
        const sourceMap = sourceMapGenerator.toString();
        writeFile(
          host,
          emitterDiagnostics,
          sourceMapFilePath,
          sourceMap,
          /*writeByteOrderMark*/
          false,
          sourceFiles
        );
      }
    } else {
      writer.writeLine();
    }
    const text = writer.getText();
    writeFile(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, { sourceMapUrlPos, diagnostics: transform.diagnostics });
    writer.clear();
  }
  function shouldEmitSourceMaps(mapOptions, sourceFileOrBundle) {
    return (mapOptions.sourceMap || mapOptions.inlineSourceMap) && (sourceFileOrBundle.kind !== 307 /* SourceFile */ || !fileExtensionIs(sourceFileOrBundle.fileName, ".json" /* Json */));
  }
  function getSourceRoot(mapOptions) {
    const sourceRoot = normalizeSlashes(mapOptions.sourceRoot || "");
    return sourceRoot ? ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot;
  }
  function getSourceMapDirectory(mapOptions, filePath, sourceFile) {
    if (mapOptions.sourceRoot) return host.getCommonSourceDirectory();
    if (mapOptions.mapRoot) {
      let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
      if (sourceFile) {
        sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
      }
      if (getRootLength(sourceMapDir) === 0) {
        sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
      }
      return sourceMapDir;
    }
    return getDirectoryPath(normalizePath(filePath));
  }
  function getSourceMappingURL(mapOptions, sourceMapGenerator, filePath, sourceMapFilePath, sourceFile) {
    if (mapOptions.inlineSourceMap) {
      const sourceMapText = sourceMapGenerator.toString();
      const base64SourceMapText = base64encode(sys, sourceMapText);
      return `data:application/json;base64,${base64SourceMapText}`;
    }
    const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath)));
    if (mapOptions.mapRoot) {
      let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
      if (sourceFile) {
        sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
      }
      if (getRootLength(sourceMapDir) === 0) {
        sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
        return encodeURI(
          getRelativePathToDirectoryOrUrl(
            getDirectoryPath(normalizePath(filePath)),
            // get the relative sourceMapDir path based on jsFilePath
            combinePaths(sourceMapDir, sourceMapFile),
            // this is where user expects to see sourceMap
            host.getCurrentDirectory(),
            host.getCanonicalFileName,
            /*isAbsolutePathAnUrl*/
            true
          )
        );
      } else {
        return encodeURI(combinePaths(sourceMapDir, sourceMapFile));
      }
    }
    return encodeURI(sourceMapFile);
  }
}
function createBuildInfo(program) {
  return { program, version };
}
function getBuildInfoText(buildInfo) {
  return JSON.stringify(buildInfo);
}
function getBuildInfo(buildInfoFile, buildInfoText) {
  return readJsonOrUndefined(buildInfoFile, buildInfoText);
}
var notImplementedResolver = {
  hasGlobalName: notImplemented,
  getReferencedExportContainer: notImplemented,
  getReferencedImportDeclaration: notImplemented,
  getReferencedDeclarationWithCollidingName: notImplemented,
  isDeclarationWithCollidingName: notImplemented,
  isValueAliasDeclaration: notImplemented,
  isReferencedAliasDeclaration: notImplemented,
  isTopLevelValueImportEqualsWithEntityName: notImplemented,
  hasNodeCheckFlag: notImplemented,
  isDeclarationVisible: notImplemented,
  isLateBound: (_node) => false,
  collectLinkedAliases: notImplemented,
  markLinkedReferences: notImplemented,
  isImplementationOfOverload: notImplemented,
  requiresAddingImplicitUndefined: notImplemented,
  isExpandoFunctionDeclaration: notImplemented,
  getPropertiesOfContainerFunction: notImplemented,
  createTypeOfDeclaration: notImplemented,
  createReturnTypeOfSignatureDeclaration: notImplemented,
  createTypeOfExpression: notImplemented,
  createLiteralConstValue: notImplemented,
  isSymbolAccessible: notImplemented,
  isEntityNameVisible: notImplemented,
  // Returns the constant value this property access resolves to: notImplemented, or 'undefined' for a non-constant
  getConstantValue: notImplemented,
  getEnumMemberValue: notImplemented,
  getReferencedValueDeclaration: notImplemented,
  getReferencedValueDeclarations: notImplemented,
  getTypeReferenceSerializationKind: notImplemented,
  isOptionalParameter: notImplemented,
  isArgumentsLocalBinding: notImplemented,
  getExternalModuleFileFromDeclaration: notImplemented,
  isLiteralConstDeclaration: notImplemented,
  getJsxFactoryEntity: notImplemented,
  getJsxFragmentFactoryEntity: notImplemented,
  isBindingCapturedByNode: notImplemented,
  getDeclarationStatementsForSourceFile: notImplemented,
  isImportRequiredByAugmentation: notImplemented,
  isDefinitelyReferenceToGlobalSymbolObject: notImplemented
};
var createPrinterWithDefaults = /* @__PURE__ */ memoize(() => createPrinter({}));
var createPrinterWithRemoveComments = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true }));
var createPrinterWithRemoveCommentsNeverAsciiEscape = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, neverAsciiEscape: true }));
var createPrinterWithRemoveCommentsOmitTrailingSemicolon = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, omitTrailingSemicolon: true }));
function createPrinter(printerOptions = {}, handlers = {}) {
  var {
    hasGlobalName,
    onEmitNode = noEmitNotification,
    isEmitNotificationEnabled,
    substituteNode = noEmitSubstitution,
    onBeforeEmitNode,
    onAfterEmitNode,
    onBeforeEmitNodeArray,
    onAfterEmitNodeArray,
    onBeforeEmitToken,
    onAfterEmitToken
  } = handlers;
  var extendedDiagnostics = !!printerOptions.extendedDiagnostics;
  var omitBraceSourcePositions = !!printerOptions.omitBraceSourceMapPositions;
  var newLine = getNewLineCharacter(printerOptions);
  var moduleKind = getEmitModuleKind(printerOptions);
  var bundledHelpers = /* @__PURE__ */ new Map();
  var currentSourceFile;
  var nodeIdToGeneratedName;
  var nodeIdToGeneratedPrivateName;
  var autoGeneratedIdToGeneratedName;
  var generatedNames;
  var formattedNameTempFlagsStack;
  var formattedNameTempFlags;
  var privateNameTempFlagsStack;
  var privateNameTempFlags;
  var tempFlagsStack;
  var tempFlags;
  var reservedNamesStack;
  var reservedNames;
  var reservedPrivateNamesStack;
  var reservedPrivateNames;
  var preserveSourceNewlines = printerOptions.preserveSourceNewlines;
  var nextListElementPos;
  var writer;
  var ownWriter;
  var write = writeBase;
  var isOwnFileEmit;
  var sourceMapsDisabled = true;
  var sourceMapGenerator;
  var sourceMapSource;
  var sourceMapSourceIndex = -1;
  var mostRecentlyAddedSourceMapSource;
  var mostRecentlyAddedSourceMapSourceIndex = -1;
  var containerPos = -1;
  var containerEnd = -1;
  var declarationListContainerEnd = -1;
  var currentLineMap;
  var detachedCommentsInfo;
  var hasWrittenComment = false;
  var commentsDisabled = !!printerOptions.removeComments;
  var lastSubstitution;
  var currentParenthesizerRule;
  var { enter: enterComment, exit: exitComment } = createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment");
  var parenthesizer = factory.parenthesizer;
  var typeArgumentParenthesizerRuleSelector = {
    select: (index) => index === 0 ? parenthesizer.parenthesizeLeadingTypeArgument : void 0
  };
  var emitBinaryExpression = createEmitBinaryExpression();
  reset();
  return {
    // public API
    printNode,
    printList,
    printFile,
    printBundle,
    // internal API
    writeNode,
    writeList,
    writeFile: writeFile2,
    writeBundle
  };
  function printNode(hint, node, sourceFile) {
    switch (hint) {
      case 0 /* SourceFile */:
        Debug.assert(isSourceFile(node), "Expected a SourceFile node.");
        break;
      case 2 /* IdentifierName */:
        Debug.assert(isIdentifier(node), "Expected an Identifier node.");
        break;
      case 1 /* Expression */:
        Debug.assert(isExpression(node), "Expected an Expression node.");
        break;
    }
    switch (node.kind) {
      case 307 /* SourceFile */:
        return printFile(node);
      case 308 /* Bundle */:
        return printBundle(node);
    }
    writeNode(hint, node, sourceFile, beginPrint());
    return endPrint();
  }
  function printList(format, nodes, sourceFile) {
    writeList(format, nodes, sourceFile, beginPrint());
    return endPrint();
  }
  function printBundle(bundle) {
    writeBundle(
      bundle,
      beginPrint(),
      /*sourceMapGenerator*/
      void 0
    );
    return endPrint();
  }
  function printFile(sourceFile) {
    writeFile2(
      sourceFile,
      beginPrint(),
      /*sourceMapGenerator*/
      void 0
    );
    return endPrint();
  }
  function writeNode(hint, node, sourceFile, output) {
    const previousWriter = writer;
    setWriter(
      output,
      /*_sourceMapGenerator*/
      void 0
    );
    print(hint, node, sourceFile);
    reset();
    writer = previousWriter;
  }
  function writeList(format, nodes, sourceFile, output) {
    const previousWriter = writer;
    setWriter(
      output,
      /*_sourceMapGenerator*/
      void 0
    );
    if (sourceFile) {
      setSourceFile(sourceFile);
    }
    emitList(
      /*parentNode*/
      void 0,
      nodes,
      format
    );
    reset();
    writer = previousWriter;
  }
  function writeBundle(bundle, output, sourceMapGenerator2) {
    isOwnFileEmit = false;
    const previousWriter = writer;
    setWriter(output, sourceMapGenerator2);
    emitShebangIfNeeded(bundle);
    emitPrologueDirectivesIfNeeded(bundle);
    emitHelpers(bundle);
    emitSyntheticTripleSlashReferencesIfNeeded(bundle);
    for (const sourceFile of bundle.sourceFiles) {
      print(0 /* SourceFile */, sourceFile, sourceFile);
    }
    reset();
    writer = previousWriter;
  }
  function writeFile2(sourceFile, output, sourceMapGenerator2) {
    isOwnFileEmit = true;
    const previousWriter = writer;
    setWriter(output, sourceMapGenerator2);
    emitShebangIfNeeded(sourceFile);
    emitPrologueDirectivesIfNeeded(sourceFile);
    print(0 /* SourceFile */, sourceFile, sourceFile);
    reset();
    writer = previousWriter;
  }
  function beginPrint() {
    return ownWriter || (ownWriter = createTextWriter(newLine));
  }
  function endPrint() {
    const text = ownWriter.getText();
    ownWriter.clear();
    return text;
  }
  function print(hint, node, sourceFile) {
    if (sourceFile) {
      setSourceFile(sourceFile);
    }
    pipelineEmit(
      hint,
      node,
      /*parenthesizerRule*/
      void 0
    );
  }
  function setSourceFile(sourceFile) {
    currentSourceFile = sourceFile;
    currentLineMap = void 0;
    detachedCommentsInfo = void 0;
    if (sourceFile) {
      setSourceMapSource(sourceFile);
    }
  }
  function setWriter(_writer, _sourceMapGenerator) {
    if (_writer && printerOptions.omitTrailingSemicolon) {
      _writer = getTrailingSemicolonDeferringWriter(_writer);
    }
    writer = _writer;
    sourceMapGenerator = _sourceMapGenerator;
    sourceMapsDisabled = !writer || !sourceMapGenerator;
  }
  function reset() {
    nodeIdToGeneratedName = [];
    nodeIdToGeneratedPrivateName = [];
    autoGeneratedIdToGeneratedName = [];
    generatedNames = /* @__PURE__ */ new Set();
    formattedNameTempFlagsStack = [];
    formattedNameTempFlags = /* @__PURE__ */ new Map();
    privateNameTempFlagsStack = [];
    privateNameTempFlags = 0 /* Auto */;
    tempFlagsStack = [];
    tempFlags = 0 /* Auto */;
    reservedNamesStack = [];
    reservedNames = void 0;
    reservedPrivateNamesStack = [];
    reservedPrivateNames = void 0;
    currentSourceFile = void 0;
    currentLineMap = void 0;
    detachedCommentsInfo = void 0;
    setWriter(
      /*output*/
      void 0,
      /*_sourceMapGenerator*/
      void 0
    );
  }
  function getCurrentLineMap() {
    return currentLineMap || (currentLineMap = getLineStarts(Debug.checkDefined(currentSourceFile)));
  }
  function emit(node, parenthesizerRule) {
    if (node === void 0) return;
    pipelineEmit(4 /* Unspecified */, node, parenthesizerRule);
  }
  function emitIdentifierName(node) {
    if (node === void 0) return;
    pipelineEmit(
      2 /* IdentifierName */,
      node,
      /*parenthesizerRule*/
      void 0
    );
  }
  function emitExpression(node, parenthesizerRule) {
    if (node === void 0) return;
    pipelineEmit(1 /* Expression */, node, parenthesizerRule);
  }
  function emitJsxAttributeValue(node) {
    pipelineEmit(isStringLiteral(node) ? 6 /* JsxAttributeValue */ : 4 /* Unspecified */, node);
  }
  function beforeEmitNode(node) {
    if (preserveSourceNewlines && getInternalEmitFlags(node) & 4 /* IgnoreSourceNewlines */) {
      preserveSourceNewlines = false;
    }
  }
  function afterEmitNode(savedPreserveSourceNewlines) {
    preserveSourceNewlines = savedPreserveSourceNewlines;
  }
  function pipelineEmit(emitHint, node, parenthesizerRule) {
    currentParenthesizerRule = parenthesizerRule;
    const pipelinePhase = getPipelinePhase(0 /* Notification */, emitHint, node);
    pipelinePhase(emitHint, node);
    currentParenthesizerRule = void 0;
  }
  function shouldEmitComments(node) {
    return !commentsDisabled && !isSourceFile(node);
  }
  function shouldEmitSourceMaps(node) {
    return !sourceMapsDisabled && !isSourceFile(node) && !isInJsonFile(node);
  }
  function getPipelinePhase(phase, emitHint, node) {
    switch (phase) {
      case 0 /* Notification */:
        if (onEmitNode !== noEmitNotification && (!isEmitNotificationEnabled || isEmitNotificationEnabled(node))) {
          return pipelineEmitWithNotification;
        }
      case 1 /* Substitution */:
        if (substituteNode !== noEmitSubstitution && (lastSubstitution = substituteNode(emitHint, node) || node) !== node) {
          if (currentParenthesizerRule) {
            lastSubstitution = currentParenthesizerRule(lastSubstitution);
          }
          return pipelineEmitWithSubstitution;
        }
      case 2 /* Comments */:
        if (shouldEmitComments(node)) {
          return pipelineEmitWithComments;
        }
      case 3 /* SourceMaps */:
        if (shouldEmitSourceMaps(node)) {
          return pipelineEmitWithSourceMaps;
        }
      case 4 /* Emit */:
        return pipelineEmitWithHint;
      default:
        return Debug.assertNever(phase);
    }
  }
  function getNextPipelinePhase(currentPhase, emitHint, node) {
    return getPipelinePhase(currentPhase + 1, emitHint, node);
  }
  function pipelineEmitWithNotification(hint, node) {
    const pipelinePhase = getNextPipelinePhase(0 /* Notification */, hint, node);
    onEmitNode(hint, node, pipelinePhase);
  }
  function pipelineEmitWithHint(hint, node) {
    onBeforeEmitNode == null ? void 0 : onBeforeEmitNode(node);
    if (preserveSourceNewlines) {
      const savedPreserveSourceNewlines = preserveSourceNewlines;
      beforeEmitNode(node);
      pipelineEmitWithHintWorker(hint, node);
      afterEmitNode(savedPreserveSourceNewlines);
    } else {
      pipelineEmitWithHintWorker(hint, node);
    }
    onAfterEmitNode == null ? void 0 : onAfterEmitNode(node);
    currentParenthesizerRule = void 0;
  }
  function pipelineEmitWithHintWorker(hint, node, allowSnippets = true) {
    if (allowSnippets) {
      const snippet = getSnippetElement(node);
      if (snippet) {
        return emitSnippetNode(hint, node, snippet);
      }
    }
    if (hint === 0 /* SourceFile */) return emitSourceFile(cast(node, isSourceFile));
    if (hint === 2 /* IdentifierName */) return emitIdentifier(cast(node, isIdentifier));
    if (hint === 6 /* JsxAttributeValue */) return emitLiteral(
      cast(node, isStringLiteral),
      /*jsxAttributeEscape*/
      true
    );
    if (hint === 3 /* MappedTypeParameter */) return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration));
    if (hint === 7 /* ImportTypeNodeAttributes */) return emitImportTypeNodeAttributes(cast(node, isImportAttributes));
    if (hint === 5 /* EmbeddedStatement */) {
      Debug.assertNode(node, isEmptyStatement);
      return emitEmptyStatement(
        /*isEmbeddedStatement*/
        true
      );
    }
    if (hint === 4 /* Unspecified */) {
      switch (node.kind) {
        case 16 /* TemplateHead */:
        case 17 /* TemplateMiddle */:
        case 18 /* TemplateTail */:
          return emitLiteral(
            node,
            /*jsxAttributeEscape*/
            false
          );
        case 80 /* Identifier */:
          return emitIdentifier(node);
        case 81 /* PrivateIdentifier */:
          return emitPrivateIdentifier(node);
        case 166 /* QualifiedName */:
          return emitQualifiedName(node);
        case 167 /* ComputedPropertyName */:
          return emitComputedPropertyName(node);
        case 168 /* TypeParameter */:
          return emitTypeParameter(node);
        case 169 /* Parameter */:
          return emitParameter(node);
        case 170 /* Decorator */:
          return emitDecorator(node);
        case 171 /* PropertySignature */:
          return emitPropertySignature(node);
        case 172 /* PropertyDeclaration */:
          return emitPropertyDeclaration(node);
        case 173 /* MethodSignature */:
          return emitMethodSignature(node);
        case 174 /* MethodDeclaration */:
          return emitMethodDeclaration(node);
        case 175 /* ClassStaticBlockDeclaration */:
          return emitClassStaticBlockDeclaration(node);
        case 176 /* Constructor */:
          return emitConstructor(node);
        case 177 /* GetAccessor */:
        case 178 /* SetAccessor */:
          return emitAccessorDeclaration(node);
        case 179 /* CallSignature */:
          return emitCallSignature(node);
        case 180 /* ConstructSignature */:
          return emitConstructSignature(node);
        case 181 /* IndexSignature */:
          return emitIndexSignature(node);
        case 182 /* TypePredicate */:
          return emitTypePredicate(node);
        case 183 /* TypeReference */:
          return emitTypeReference(node);
        case 184 /* FunctionType */:
          return emitFunctionType(node);
        case 185 /* ConstructorType */:
          return emitConstructorType(node);
        case 186 /* TypeQuery */:
          return emitTypeQuery(node);
        case 187 /* TypeLiteral */:
          return emitTypeLiteral(node);
        case 188 /* ArrayType */:
          return emitArrayType(node);
        case 189 /* TupleType */:
          return emitTupleType(node);
        case 190 /* OptionalType */:
          return emitOptionalType(node);
        case 192 /* UnionType */:
          return emitUnionType(node);
        case 193 /* IntersectionType */:
          return emitIntersectionType(node);
        case 194 /* ConditionalType */:
          return emitConditionalType(node);
        case 195 /* InferType */:
          return emitInferType(node);
        case 196 /* ParenthesizedType */:
          return emitParenthesizedType(node);
        case 233 /* ExpressionWithTypeArguments */:
          return emitExpressionWithTypeArguments(node);
        case 197 /* ThisType */:
          return emitThisType();
        case 198 /* TypeOperator */:
          return emitTypeOperator(node);
        case 199 /* IndexedAccessType */:
          return emitIndexedAccessType(node);
        case 200 /* MappedType */:
          return emitMappedType(node);
        case 201 /* LiteralType */:
          return emitLiteralType(node);
        case 202 /* NamedTupleMember */:
          return emitNamedTupleMember(node);
        case 203 /* TemplateLiteralType */:
          return emitTemplateType(node);
        case 204 /* TemplateLiteralTypeSpan */:
          return emitTemplateTypeSpan(node);
        case 205 /* ImportType */:
          return emitImportTypeNode(node);
        case 206 /* ObjectBindingPattern */:
          return emitObjectBindingPattern(node);
        case 207 /* ArrayBindingPattern */:
          return emitArrayBindingPattern(node);
        case 208 /* BindingElement */:
          return emitBindingElement(node);
        case 239 /* TemplateSpan */:
          return emitTemplateSpan(node);
        case 240 /* SemicolonClassElement */:
          return emitSemicolonClassElement();
        case 241 /* Block */:
          return emitBlock(node);
        case 243 /* VariableStatement */:
          return emitVariableStatement(node);
        case 242 /* EmptyStatement */:
          return emitEmptyStatement(
            /*isEmbeddedStatement*/
            false
          );
        case 244 /* ExpressionStatement */:
          return emitExpressionStatement(node);
        case 245 /* IfStatement */:
          return emitIfStatement(node);
        case 246 /* DoStatement */:
          return emitDoStatement(node);
        case 247 /* WhileStatement */:
          return emitWhileStatement(node);
        case 248 /* ForStatement */:
          return emitForStatement(node);
        case 249 /* ForInStatement */:
          return emitForInStatement(node);
        case 250 /* ForOfStatement */:
          return emitForOfStatement(node);
        case 251 /* ContinueStatement */:
          return emitContinueStatement(node);
        case 252 /* BreakStatement */:
          return emitBreakStatement(node);
        case 253 /* ReturnStatement */:
          return emitReturnStatement(node);
        case 254 /* WithStatement */:
          return emitWithStatement(node);
        case 255 /* SwitchStatement */:
          return emitSwitchStatement(node);
        case 256 /* LabeledStatement */:
          return emitLabeledStatement(node);
        case 257 /* ThrowStatement */:
          return emitThrowStatement(node);
        case 258 /* TryStatement */:
          return emitTryStatement(node);
        case 259 /* DebuggerStatement */:
          return emitDebuggerStatement(node);
        case 260 /* VariableDeclaration */:
          return emitVariableDeclaration(node);
        case 261 /* VariableDeclarationList */:
          return emitVariableDeclarationList(node);
        case 262 /* FunctionDeclaration */:
          return emitFunctionDeclaration(node);
        case 263 /* ClassDeclaration */:
          return emitClassDeclaration(node);
        case 264 /* InterfaceDeclaration */:
          return emitInterfaceDeclaration(node);
        case 265 /* TypeAliasDeclaration */:
          return emitTypeAliasDeclaration(node);
        case 266 /* EnumDeclaration */:
          return emitEnumDeclaration(node);
        case 267 /* ModuleDeclaration */:
          return emitModuleDeclaration(node);
        case 268 /* ModuleBlock */:
          return emitModuleBlock(node);
        case 269 /* CaseBlock */:
          return emitCaseBlock(node);
        case 270 /* NamespaceExportDeclaration */:
          return emitNamespaceExportDeclaration(node);
        case 271 /* ImportEqualsDeclaration */:
          return emitImportEqualsDeclaration(node);
        case 272 /* ImportDeclaration */:
          return emitImportDeclaration(node);
        case 273 /* ImportClause */:
          return emitImportClause(node);
        case 274 /* NamespaceImport */:
          return emitNamespaceImport(node);
        case 280 /* NamespaceExport */:
          return emitNamespaceExport(node);
        case 275 /* NamedImports */:
          return emitNamedImports(node);
        case 276 /* ImportSpecifier */:
          return emitImportSpecifier(node);
        case 277 /* ExportAssignment */:
          return emitExportAssignment(node);
        case 278 /* ExportDeclaration */:
          return emitExportDeclaration(node);
        case 279 /* NamedExports */:
          return emitNamedExports(node);
        case 281 /* ExportSpecifier */:
          return emitExportSpecifier(node);
        case 300 /* ImportAttributes */:
          return emitImportAttributes(node);
        case 301 /* ImportAttribute */:
          return emitImportAttribute(node);
        case 282 /* MissingDeclaration */:
          return;
        case 283 /* ExternalModuleReference */:
          return emitExternalModuleReference(node);
        case 12 /* JsxText */:
          return emitJsxText(node);
        case 286 /* JsxOpeningElement */:
        case 289 /* JsxOpeningFragment */:
          return emitJsxOpeningElementOrFragment(node);
        case 287 /* JsxClosingElement */:
        case 290 /* JsxClosingFragment */:
          return emitJsxClosingElementOrFragment(node);
        case 291 /* JsxAttribute */:
          return emitJsxAttribute(node);
        case 292 /* JsxAttributes */:
          return emitJsxAttributes(node);
        case 293 /* JsxSpreadAttribute */:
          return emitJsxSpreadAttribute(node);
        case 294 /* JsxExpression */:
          return emitJsxExpression(node);
        case 295 /* JsxNamespacedName */:
          return emitJsxNamespacedName(node);
        case 296 /* CaseClause */:
          return emitCaseClause(node);
        case 297 /* DefaultClause */:
          return emitDefaultClause(node);
        case 298 /* HeritageClause */:
          return emitHeritageClause(node);
        case 299 /* CatchClause */:
          return emitCatchClause(node);
        case 303 /* PropertyAssignment */:
          return emitPropertyAssignment(node);
        case 304 /* ShorthandPropertyAssignment */:
          return emitShorthandPropertyAssignment(node);
        case 305 /* SpreadAssignment */:
          return emitSpreadAssignment(node);
        case 306 /* EnumMember */:
          return emitEnumMember(node);
        case 307 /* SourceFile */:
          return emitSourceFile(node);
        case 308 /* Bundle */:
          return Debug.fail("Bundles should be printed using printBundle");
        case 309 /* JSDocTypeExpression */:
          return emitJSDocTypeExpression(node);
        case 310 /* JSDocNameReference */:
          return emitJSDocNameReference(node);
        case 312 /* JSDocAllType */:
          return writePunctuation("*");
        case 313 /* JSDocUnknownType */:
          return writePunctuation("?");
        case 314 /* JSDocNullableType */:
          return emitJSDocNullableType(node);
        case 315 /* JSDocNonNullableType */:
          return emitJSDocNonNullableType(node);
        case 316 /* JSDocOptionalType */:
          return emitJSDocOptionalType(node);
        case 317 /* JSDocFunctionType */:
          return emitJSDocFunctionType(node);
        case 191 /* RestType */:
        case 318 /* JSDocVariadicType */:
          return emitRestOrJSDocVariadicType(node);
        case 319 /* JSDocNamepathType */:
          return;
        case 320 /* JSDoc */:
          return emitJSDoc(node);
        case 322 /* JSDocTypeLiteral */:
          return emitJSDocTypeLiteral(node);
        case 323 /* JSDocSignature */:
          return emitJSDocSignature(node);
        case 327 /* JSDocTag */:
        case 332 /* JSDocClassTag */:
        case 337 /* JSDocOverrideTag */:
          return emitJSDocSimpleTag(node);
        case 328 /* JSDocAugmentsTag */:
        case 329 /* JSDocImplementsTag */:
          return emitJSDocHeritageTag(node);
        case 330 /* JSDocAuthorTag */:
        case 331 /* JSDocDeprecatedTag */:
          return;
        case 333 /* JSDocPublicTag */:
        case 334 /* JSDocPrivateTag */:
        case 335 /* JSDocProtectedTag */:
        case 336 /* JSDocReadonlyTag */:
          return;
        case 338 /* JSDocCallbackTag */:
          return emitJSDocCallbackTag(node);
        case 339 /* JSDocOverloadTag */:
          return emitJSDocOverloadTag(node);
        case 341 /* JSDocParameterTag */:
        case 348 /* JSDocPropertyTag */:
          return emitJSDocPropertyLikeTag(node);
        case 340 /* JSDocEnumTag */:
        case 342 /* JSDocReturnTag */:
        case 343 /* JSDocThisTag */:
        case 344 /* JSDocTypeTag */:
        case 349 /* JSDocThrowsTag */:
        case 350 /* JSDocSatisfiesTag */:
          return emitJSDocSimpleTypedTag(node);
        case 345 /* JSDocTemplateTag */:
          return emitJSDocTemplateTag(node);
        case 346 /* JSDocTypedefTag */:
          return emitJSDocTypedefTag(node);
        case 347 /* JSDocSeeTag */:
          return emitJSDocSeeTag(node);
        case 351 /* JSDocImportTag */:
          return emitJSDocImportTag(node);
        case 353 /* NotEmittedStatement */:
          return;
      }
      if (isExpression(node)) {
        hint = 1 /* Expression */;
        if (substituteNode !== noEmitSubstitution) {
          const substitute = substituteNode(hint, node) || node;
          if (substitute !== node) {
            node = substitute;
            if (currentParenthesizerRule) {
              node = currentParenthesizerRule(node);
            }
          }
        }
      }
    }
    if (hint === 1 /* Expression */) {
      switch (node.kind) {
        case 9 /* NumericLiteral */:
        case 10 /* BigIntLiteral */:
          return emitNumericOrBigIntLiteral(node);
        case 11 /* StringLiteral */:
        case 14 /* RegularExpressionLiteral */:
        case 15 /* NoSubstitutionTemplateLiteral */:
          return emitLiteral(
            node,
            /*jsxAttributeEscape*/
            false
          );
        case 80 /* Identifier */:
          return emitIdentifier(node);
        case 81 /* PrivateIdentifier */:
          return emitPrivateIdentifier(node);
        case 209 /* ArrayLiteralExpression */:
          return emitArrayLiteralExpression(node);
        case 210 /* ObjectLiteralExpression */:
          return emitObjectLiteralExpression(node);
        case 211 /* PropertyAccessExpression */:
          return emitPropertyAccessExpression(node);
        case 212 /* ElementAccessExpression */:
          return emitElementAccessExpression(node);
        case 213 /* CallExpression */:
          return emitCallExpression(node);
        case 214 /* NewExpression */:
          return emitNewExpression(node);
        case 215 /* TaggedTemplateExpression */:
          return emitTaggedTemplateExpression(node);
        case 216 /* TypeAssertionExpression */:
          return emitTypeAssertionExpression(node);
        case 217 /* ParenthesizedExpression */:
          return emitParenthesizedExpression(node);
        case 218 /* FunctionExpression */:
          return emitFunctionExpression(node);
        case 219 /* ArrowFunction */:
          return emitArrowFunction(node);
        case 220 /* DeleteExpression */:
          return emitDeleteExpression(node);
        case 221 /* TypeOfExpression */:
          return emitTypeOfExpression(node);
        case 222 /* VoidExpression */:
          return emitVoidExpression(node);
        case 223 /* AwaitExpression */:
          return emitAwaitExpression(node);
        case 224 /* PrefixUnaryExpression */:
          return emitPrefixUnaryExpression(node);
        case 225 /* PostfixUnaryExpression */:
          return emitPostfixUnaryExpression(node);
        case 226 /* BinaryExpression */:
          return emitBinaryExpression(node);
        case 227 /* ConditionalExpression */:
          return emitConditionalExpression(node);
        case 228 /* TemplateExpression */:
          return emitTemplateExpression(node);
        case 229 /* YieldExpression */:
          return emitYieldExpression(node);
        case 230 /* SpreadElement */:
          return emitSpreadElement(node);
        case 231 /* ClassExpression */:
          return emitClassExpression(node);
        case 232 /* OmittedExpression */:
          return;
        case 234 /* AsExpression */:
          return emitAsExpression(node);
        case 235 /* NonNullExpression */:
          return emitNonNullExpression(node);
        case 233 /* ExpressionWithTypeArguments */:
          return emitExpressionWithTypeArguments(node);
        case 238 /* SatisfiesExpression */:
          return emitSatisfiesExpression(node);
        case 236 /* MetaProperty */:
          return emitMetaProperty(node);
        case 237 /* SyntheticExpression */:
          return Debug.fail("SyntheticExpression should never be printed.");
        case 282 /* MissingDeclaration */:
          return;
        case 284 /* JsxElement */:
          return emitJsxElement(node);
        case 285 /* JsxSelfClosingElement */:
          return emitJsxSelfClosingElement(node);
        case 288 /* JsxFragment */:
          return emitJsxFragment(node);
        case 352 /* SyntaxList */:
          return Debug.fail("SyntaxList should not be printed");
        case 353 /* NotEmittedStatement */:
          return;
        case 354 /* PartiallyEmittedExpression */:
          return emitPartiallyEmittedExpression(node);
        case 355 /* CommaListExpression */:
          return emitCommaList(node);
        case 356 /* SyntheticReferenceExpression */:
          return Debug.fail("SyntheticReferenceExpression should not be printed");
      }
    }
    if (isKeyword(node.kind)) return writeTokenNode(node, writeKeyword);
    if (isTokenKind(node.kind)) return writeTokenNode(node, writePunctuation);
    Debug.fail(`Unhandled SyntaxKind: ${Debug.formatSyntaxKind(node.kind)}.`);
  }
  function emitMappedTypeParameter(node) {
    emit(node.name);
    writeSpace();
    writeKeyword("in");
    writeSpace();
    emit(node.constraint);
  }
  function pipelineEmitWithSubstitution(hint, node) {
    const pipelinePhase = getNextPipelinePhase(1 /* Substitution */, hint, node);
    Debug.assertIsDefined(lastSubstitution);
    node = lastSubstitution;
    lastSubstitution = void 0;
    pipelinePhase(hint, node);
  }
  function emitHelpers(node) {
    let helpersEmitted = false;
    const bundle = node.kind === 308 /* Bundle */ ? node : void 0;
    if (bundle && moduleKind === 0 /* None */) {
      return;
    }
    const numNodes = bundle ? bundle.sourceFiles.length : 1;
    for (let i = 0; i < numNodes; i++) {
      const currentNode = bundle ? bundle.sourceFiles[i] : node;
      const sourceFile = isSourceFile(currentNode) ? currentNode : currentSourceFile;
      const shouldSkip = printerOptions.noEmitHelpers || !!sourceFile && hasRecordedExternalHelpers(sourceFile);
      const shouldBundle = isSourceFile(currentNode) && !isOwnFileEmit;
      const helpers = getSortedEmitHelpers(currentNode);
      if (helpers) {
        for (const helper of helpers) {
          if (!helper.scoped) {
            if (shouldSkip) continue;
            if (shouldBundle) {
              if (bundledHelpers.get(helper.name)) {
                continue;
              }
              bundledHelpers.set(helper.name, true);
            }
          } else if (bundle) {
            continue;
          }
          if (typeof helper.text === "string") {
            writeLines(helper.text);
          } else {
            writeLines(helper.text(makeFileLevelOptimisticUniqueName));
          }
          helpersEmitted = true;
        }
      }
    }
    return helpersEmitted;
  }
  function getSortedEmitHelpers(node) {
    const helpers = getEmitHelpers(node);
    return helpers && stableSort(helpers, compareEmitHelpers);
  }
  function emitNumericOrBigIntLiteral(node) {
    emitLiteral(
      node,
      /*jsxAttributeEscape*/
      false
    );
  }
  function emitLiteral(node, jsxAttributeEscape) {
    const text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape);
    if ((printerOptions.sourceMap || printerOptions.inlineSourceMap) && (node.kind === 11 /* StringLiteral */ || isTemplateLiteralKind(node.kind))) {
      writeLiteral(text);
    } else {
      writeStringLiteral(text);
    }
  }
  function emitSnippetNode(hint, node, snippet) {
    switch (snippet.kind) {
      case 1 /* Placeholder */:
        emitPlaceholder(hint, node, snippet);
        break;
      case 0 /* TabStop */:
        emitTabStop(hint, node, snippet);
        break;
    }
  }
  function emitPlaceholder(hint, node, snippet) {
    nonEscapingWrite(`\${${snippet.order}:`);
    pipelineEmitWithHintWorker(
      hint,
      node,
      /*allowSnippets*/
      false
    );
    nonEscapingWrite(`}`);
  }
  function emitTabStop(hint, node, snippet) {
    Debug.assert(node.kind === 242 /* EmptyStatement */, `A tab stop cannot be attached to a node of kind ${Debug.formatSyntaxKind(node.kind)}.`);
    Debug.assert(hint !== 5 /* EmbeddedStatement */, `A tab stop cannot be attached to an embedded statement.`);
    nonEscapingWrite(`$${snippet.order}`);
  }
  function emitIdentifier(node) {
    const writeText = node.symbol ? writeSymbol : write;
    writeText(getTextOfNode2(
      node,
      /*includeTrivia*/
      false
    ), node.symbol);
    emitList(node, getIdentifierTypeArguments(node), 53776 /* TypeParameters */);
  }
  function emitPrivateIdentifier(node) {
    write(getTextOfNode2(
      node,
      /*includeTrivia*/
      false
    ));
  }
  function emitQualifiedName(node) {
    emitEntityName(node.left);
    writePunctuation(".");
    emit(node.right);
  }
  function emitEntityName(node) {
    if (node.kind === 80 /* Identifier */) {
      emitExpression(node);
    } else {
      emit(node);
    }
  }
  function emitComputedPropertyName(node) {
    writePunctuation("[");
    emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfComputedPropertyName);
    writePunctuation("]");
  }
  function emitTypeParameter(node) {
    emitModifierList(node, node.modifiers);
    emit(node.name);
    if (node.constraint) {
      writeSpace();
      writeKeyword("extends");
      writeSpace();
      emit(node.constraint);
    }
    if (node.default) {
      writeSpace();
      writeOperator("=");
      writeSpace();
      emit(node.default);
    }
  }
  function emitParameter(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      true
    );
    emit(node.dotDotDotToken);
    emitNodeWithWriter(node.name, writeParameter);
    emit(node.questionToken);
    if (node.parent && node.parent.kind === 317 /* JSDocFunctionType */ && !node.name) {
      emit(node.type);
    } else {
      emitTypeAnnotation(node.type);
    }
    emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name ? node.name.end : node.modifiers ? node.modifiers.end : node.pos, node, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitDecorator(decorator) {
    writePunctuation("@");
    emitExpression(decorator.expression, parenthesizer.parenthesizeLeftSideOfAccess);
  }
  function emitPropertySignature(node) {
    emitModifierList(node, node.modifiers);
    emitNodeWithWriter(node.name, writeProperty);
    emit(node.questionToken);
    emitTypeAnnotation(node.type);
    writeTrailingSemicolon();
  }
  function emitPropertyDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      true
    );
    emit(node.name);
    emit(node.questionToken);
    emit(node.exclamationToken);
    emitTypeAnnotation(node.type);
    emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name.end, node);
    writeTrailingSemicolon();
  }
  function emitMethodSignature(node) {
    emitModifierList(node, node.modifiers);
    emit(node.name);
    emit(node.questionToken);
    emitSignatureAndBody(node, emitSignatureHead, emitEmptyFunctionBody);
  }
  function emitMethodDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      true
    );
    emit(node.asteriskToken);
    emit(node.name);
    emit(node.questionToken);
    emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
  }
  function emitClassStaticBlockDeclaration(node) {
    writeKeyword("static");
    pushNameGenerationScope(node);
    emitBlockFunctionBody(node.body);
    popNameGenerationScope(node);
  }
  function emitConstructor(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    writeKeyword("constructor");
    emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
  }
  function emitAccessorDeclaration(node) {
    const pos = emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      true
    );
    const token = node.kind === 177 /* GetAccessor */ ? 139 /* GetKeyword */ : 153 /* SetKeyword */;
    emitTokenWithComment(token, pos, writeKeyword, node);
    writeSpace();
    emit(node.name);
    emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
  }
  function emitCallSignature(node) {
    emitSignatureAndBody(node, emitSignatureHead, emitEmptyFunctionBody);
  }
  function emitConstructSignature(node) {
    writeKeyword("new");
    writeSpace();
    emitSignatureAndBody(node, emitSignatureHead, emitEmptyFunctionBody);
  }
  function emitIndexSignature(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    emitParametersForIndexSignature(node, node.parameters);
    emitTypeAnnotation(node.type);
    writeTrailingSemicolon();
  }
  function emitTemplateTypeSpan(node) {
    emit(node.type);
    emit(node.literal);
  }
  function emitSemicolonClassElement() {
    writeTrailingSemicolon();
  }
  function emitTypePredicate(node) {
    if (node.assertsModifier) {
      emit(node.assertsModifier);
      writeSpace();
    }
    emit(node.parameterName);
    if (node.type) {
      writeSpace();
      writeKeyword("is");
      writeSpace();
      emit(node.type);
    }
  }
  function emitTypeReference(node) {
    emit(node.typeName);
    emitTypeArguments(node, node.typeArguments);
  }
  function emitFunctionType(node) {
    emitSignatureAndBody(node, emitFunctionTypeHead, emitFunctionTypeBody);
  }
  function emitFunctionTypeHead(node) {
    emitTypeParameters(node, node.typeParameters);
    emitParametersForArrow(node, node.parameters);
    writeSpace();
    writePunctuation("=>");
  }
  function emitFunctionTypeBody(node) {
    writeSpace();
    emit(node.type);
  }
  function emitJSDocFunctionType(node) {
    writeKeyword("function");
    emitParameters(node, node.parameters);
    writePunctuation(":");
    emit(node.type);
  }
  function emitJSDocNullableType(node) {
    writePunctuation("?");
    emit(node.type);
  }
  function emitJSDocNonNullableType(node) {
    writePunctuation("!");
    emit(node.type);
  }
  function emitJSDocOptionalType(node) {
    emit(node.type);
    writePunctuation("=");
  }
  function emitConstructorType(node) {
    emitModifierList(node, node.modifiers);
    writeKeyword("new");
    writeSpace();
    emitSignatureAndBody(node, emitFunctionTypeHead, emitFunctionTypeBody);
  }
  function emitTypeQuery(node) {
    writeKeyword("typeof");
    writeSpace();
    emit(node.exprName);
    emitTypeArguments(node, node.typeArguments);
  }
  function emitTypeLiteral(node) {
    pushNameGenerationScope(node);
    forEach(node.members, generateMemberNames);
    writePunctuation("{");
    const flags = getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineTypeLiteralMembers */ : 32897 /* MultiLineTypeLiteralMembers */;
    emitList(node, node.members, flags | 524288 /* NoSpaceIfEmpty */);
    writePunctuation("}");
    popNameGenerationScope(node);
  }
  function emitArrayType(node) {
    emit(node.elementType, parenthesizer.parenthesizeNonArrayTypeOfPostfixType);
    writePunctuation("[");
    writePunctuation("]");
  }
  function emitRestOrJSDocVariadicType(node) {
    writePunctuation("...");
    emit(node.type);
  }
  function emitTupleType(node) {
    emitTokenWithComment(23 /* OpenBracketToken */, node.pos, writePunctuation, node);
    const flags = getEmitFlags(node) & 1 /* SingleLine */ ? 528 /* SingleLineTupleTypeElements */ : 657 /* MultiLineTupleTypeElements */;
    emitList(node, node.elements, flags | 524288 /* NoSpaceIfEmpty */, parenthesizer.parenthesizeElementTypeOfTupleType);
    emitTokenWithComment(24 /* CloseBracketToken */, node.elements.end, writePunctuation, node);
  }
  function emitNamedTupleMember(node) {
    emit(node.dotDotDotToken);
    emit(node.name);
    emit(node.questionToken);
    emitTokenWithComment(59 /* ColonToken */, node.name.end, writePunctuation, node);
    writeSpace();
    emit(node.type);
  }
  function emitOptionalType(node) {
    emit(node.type, parenthesizer.parenthesizeTypeOfOptionalType);
    writePunctuation("?");
  }
  function emitUnionType(node) {
    emitList(node, node.types, 516 /* UnionTypeConstituents */, parenthesizer.parenthesizeConstituentTypeOfUnionType);
  }
  function emitIntersectionType(node) {
    emitList(node, node.types, 520 /* IntersectionTypeConstituents */, parenthesizer.parenthesizeConstituentTypeOfIntersectionType);
  }
  function emitConditionalType(node) {
    emit(node.checkType, parenthesizer.parenthesizeCheckTypeOfConditionalType);
    writeSpace();
    writeKeyword("extends");
    writeSpace();
    emit(node.extendsType, parenthesizer.parenthesizeExtendsTypeOfConditionalType);
    writeSpace();
    writePunctuation("?");
    writeSpace();
    emit(node.trueType);
    writeSpace();
    writePunctuation(":");
    writeSpace();
    emit(node.falseType);
  }
  function emitInferType(node) {
    writeKeyword("infer");
    writeSpace();
    emit(node.typeParameter);
  }
  function emitParenthesizedType(node) {
    writePunctuation("(");
    emit(node.type);
    writePunctuation(")");
  }
  function emitThisType() {
    writeKeyword("this");
  }
  function emitTypeOperator(node) {
    writeTokenText(node.operator, writeKeyword);
    writeSpace();
    const parenthesizerRule = node.operator === 148 /* ReadonlyKeyword */ ? parenthesizer.parenthesizeOperandOfReadonlyTypeOperator : parenthesizer.parenthesizeOperandOfTypeOperator;
    emit(node.type, parenthesizerRule);
  }
  function emitIndexedAccessType(node) {
    emit(node.objectType, parenthesizer.parenthesizeNonArrayTypeOfPostfixType);
    writePunctuation("[");
    emit(node.indexType);
    writePunctuation("]");
  }
  function emitMappedType(node) {
    const emitFlags = getEmitFlags(node);
    writePunctuation("{");
    if (emitFlags & 1 /* SingleLine */) {
      writeSpace();
    } else {
      writeLine();
      increaseIndent();
    }
    if (node.readonlyToken) {
      emit(node.readonlyToken);
      if (node.readonlyToken.kind !== 148 /* ReadonlyKeyword */) {
        writeKeyword("readonly");
      }
      writeSpace();
    }
    writePunctuation("[");
    pipelineEmit(3 /* MappedTypeParameter */, node.typeParameter);
    if (node.nameType) {
      writeSpace();
      writeKeyword("as");
      writeSpace();
      emit(node.nameType);
    }
    writePunctuation("]");
    if (node.questionToken) {
      emit(node.questionToken);
      if (node.questionToken.kind !== 58 /* QuestionToken */) {
        writePunctuation("?");
      }
    }
    writePunctuation(":");
    writeSpace();
    emit(node.type);
    writeTrailingSemicolon();
    if (emitFlags & 1 /* SingleLine */) {
      writeSpace();
    } else {
      writeLine();
      decreaseIndent();
    }
    emitList(node, node.members, 2 /* PreserveLines */);
    writePunctuation("}");
  }
  function emitLiteralType(node) {
    emitExpression(node.literal);
  }
  function emitTemplateType(node) {
    emit(node.head);
    emitList(node, node.templateSpans, 262144 /* TemplateExpressionSpans */);
  }
  function emitImportTypeNode(node) {
    if (node.isTypeOf) {
      writeKeyword("typeof");
      writeSpace();
    }
    writeKeyword("import");
    writePunctuation("(");
    emit(node.argument);
    if (node.attributes) {
      writePunctuation(",");
      writeSpace();
      pipelineEmit(7 /* ImportTypeNodeAttributes */, node.attributes);
    }
    writePunctuation(")");
    if (node.qualifier) {
      writePunctuation(".");
      emit(node.qualifier);
    }
    emitTypeArguments(node, node.typeArguments);
  }
  function emitObjectBindingPattern(node) {
    writePunctuation("{");
    emitList(node, node.elements, 525136 /* ObjectBindingPatternElements */);
    writePunctuation("}");
  }
  function emitArrayBindingPattern(node) {
    writePunctuation("[");
    emitList(node, node.elements, 524880 /* ArrayBindingPatternElements */);
    writePunctuation("]");
  }
  function emitBindingElement(node) {
    emit(node.dotDotDotToken);
    if (node.propertyName) {
      emit(node.propertyName);
      writePunctuation(":");
      writeSpace();
    }
    emit(node.name);
    emitInitializer(node.initializer, node.name.end, node, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitArrayLiteralExpression(node) {
    const elements = node.elements;
    const preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
    emitExpressionList(node, elements, 8914 /* ArrayLiteralExpressionElements */ | preferNewLine, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitObjectLiteralExpression(node) {
    pushNameGenerationScope(node);
    forEach(node.properties, generateMemberNames);
    const indentedFlag = getEmitFlags(node) & 131072 /* Indented */;
    if (indentedFlag) {
      increaseIndent();
    }
    const preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
    const allowTrailingComma = currentSourceFile && currentSourceFile.languageVersion >= 1 /* ES5 */ && !isJsonSourceFile(currentSourceFile) ? 64 /* AllowTrailingComma */ : 0 /* None */;
    emitList(node, node.properties, 526226 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine);
    if (indentedFlag) {
      decreaseIndent();
    }
    popNameGenerationScope(node);
  }
  function emitPropertyAccessExpression(node) {
    emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess);
    const token = node.questionDotToken || setTextRangePosEnd(factory.createToken(25 /* DotToken */), node.expression.end, node.name.pos);
    const linesBeforeDot = getLinesBetweenNodes(node, node.expression, token);
    const linesAfterDot = getLinesBetweenNodes(node, token, node.name);
    writeLinesAndIndent(
      linesBeforeDot,
      /*writeSpaceIfNotIndenting*/
      false
    );
    const shouldEmitDotDot = token.kind !== 29 /* QuestionDotToken */ && mayNeedDotDotForPropertyAccess(node.expression) && !writer.hasTrailingComment() && !writer.hasTrailingWhitespace();
    if (shouldEmitDotDot) {
      writePunctuation(".");
    }
    if (node.questionDotToken) {
      emit(token);
    } else {
      emitTokenWithComment(token.kind, node.expression.end, writePunctuation, node);
    }
    writeLinesAndIndent(
      linesAfterDot,
      /*writeSpaceIfNotIndenting*/
      false
    );
    emit(node.name);
    decreaseIndentIf(linesBeforeDot, linesAfterDot);
  }
  function mayNeedDotDotForPropertyAccess(expression) {
    expression = skipPartiallyEmittedExpressions(expression);
    if (isNumericLiteral(expression)) {
      const text = getLiteralTextOfNode(
        expression,
        /*neverAsciiEscape*/
        true,
        /*jsxAttributeEscape*/
        false
      );
      return !(expression.numericLiteralFlags & 448 /* WithSpecifier */) && !text.includes(tokenToString(25 /* DotToken */)) && !text.includes(String.fromCharCode(69 /* E */)) && !text.includes(String.fromCharCode(101 /* e */));
    } else if (isAccessExpression(expression)) {
      const constantValue = getConstantValue(expression);
      return typeof constantValue === "number" && isFinite(constantValue) && constantValue >= 0 && Math.floor(constantValue) === constantValue;
    }
  }
  function emitElementAccessExpression(node) {
    emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess);
    emit(node.questionDotToken);
    emitTokenWithComment(23 /* OpenBracketToken */, node.expression.end, writePunctuation, node);
    emitExpression(node.argumentExpression);
    emitTokenWithComment(24 /* CloseBracketToken */, node.argumentExpression.end, writePunctuation, node);
  }
  function emitCallExpression(node) {
    const indirectCall = getInternalEmitFlags(node) & 16 /* IndirectCall */;
    if (indirectCall) {
      writePunctuation("(");
      writeLiteral("0");
      writePunctuation(",");
      writeSpace();
    }
    emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess);
    if (indirectCall) {
      writePunctuation(")");
    }
    emit(node.questionDotToken);
    emitTypeArguments(node, node.typeArguments);
    emitExpressionList(node, node.arguments, 2576 /* CallExpressionArguments */, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitNewExpression(node) {
    emitTokenWithComment(105 /* NewKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfNew);
    emitTypeArguments(node, node.typeArguments);
    emitExpressionList(node, node.arguments, 18960 /* NewExpressionArguments */, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitTaggedTemplateExpression(node) {
    const indirectCall = getInternalEmitFlags(node) & 16 /* IndirectCall */;
    if (indirectCall) {
      writePunctuation("(");
      writeLiteral("0");
      writePunctuation(",");
      writeSpace();
    }
    emitExpression(node.tag, parenthesizer.parenthesizeLeftSideOfAccess);
    if (indirectCall) {
      writePunctuation(")");
    }
    emitTypeArguments(node, node.typeArguments);
    writeSpace();
    emitExpression(node.template);
  }
  function emitTypeAssertionExpression(node) {
    writePunctuation("<");
    emit(node.type);
    writePunctuation(">");
    emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary);
  }
  function emitParenthesizedExpression(node) {
    const openParenPos = emitTokenWithComment(21 /* OpenParenToken */, node.pos, writePunctuation, node);
    const indented = writeLineSeparatorsAndIndentBefore(node.expression, node);
    emitExpression(
      node.expression,
      /*parenthesizerRule*/
      void 0
    );
    writeLineSeparatorsAfter(node.expression, node);
    decreaseIndentIf(indented);
    emitTokenWithComment(22 /* CloseParenToken */, node.expression ? node.expression.end : openParenPos, writePunctuation, node);
  }
  function emitFunctionExpression(node) {
    generateNameIfNeeded(node.name);
    emitFunctionDeclarationOrExpression(node);
  }
  function emitArrowFunction(node) {
    emitModifierList(node, node.modifiers);
    emitSignatureAndBody(node, emitArrowFunctionHead, emitArrowFunctionBody);
  }
  function emitArrowFunctionHead(node) {
    emitTypeParameters(node, node.typeParameters);
    emitParametersForArrow(node, node.parameters);
    emitTypeAnnotation(node.type);
    writeSpace();
    emit(node.equalsGreaterThanToken);
  }
  function emitArrowFunctionBody(node) {
    if (isBlock(node.body)) {
      emitBlockFunctionBody(node.body);
    } else {
      writeSpace();
      emitExpression(node.body, parenthesizer.parenthesizeConciseBodyOfArrowFunction);
    }
  }
  function emitDeleteExpression(node) {
    emitTokenWithComment(91 /* DeleteKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary);
  }
  function emitTypeOfExpression(node) {
    emitTokenWithComment(114 /* TypeOfKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary);
  }
  function emitVoidExpression(node) {
    emitTokenWithComment(116 /* VoidKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary);
  }
  function emitAwaitExpression(node) {
    emitTokenWithComment(135 /* AwaitKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary);
  }
  function emitPrefixUnaryExpression(node) {
    writeTokenText(node.operator, writeOperator);
    if (shouldEmitWhitespaceBeforeOperand(node)) {
      writeSpace();
    }
    emitExpression(node.operand, parenthesizer.parenthesizeOperandOfPrefixUnary);
  }
  function shouldEmitWhitespaceBeforeOperand(node) {
    const operand = node.operand;
    return operand.kind === 224 /* PrefixUnaryExpression */ && (node.operator === 40 /* PlusToken */ && (operand.operator === 40 /* PlusToken */ || operand.operator === 46 /* PlusPlusToken */) || node.operator === 41 /* MinusToken */ && (operand.operator === 41 /* MinusToken */ || operand.operator === 47 /* MinusMinusToken */));
  }
  function emitPostfixUnaryExpression(node) {
    emitExpression(node.operand, parenthesizer.parenthesizeOperandOfPostfixUnary);
    writeTokenText(node.operator, writeOperator);
  }
  function createEmitBinaryExpression() {
    return createBinaryExpressionTrampoline(
      onEnter,
      onLeft,
      onOperator,
      onRight,
      onExit,
      /*foldState*/
      void 0
    );
    function onEnter(node, state) {
      if (state) {
        state.stackIndex++;
        state.preserveSourceNewlinesStack[state.stackIndex] = preserveSourceNewlines;
        state.containerPosStack[state.stackIndex] = containerPos;
        state.containerEndStack[state.stackIndex] = containerEnd;
        state.declarationListContainerEndStack[state.stackIndex] = declarationListContainerEnd;
        const emitComments2 = state.shouldEmitCommentsStack[state.stackIndex] = shouldEmitComments(node);
        const emitSourceMaps = state.shouldEmitSourceMapsStack[state.stackIndex] = shouldEmitSourceMaps(node);
        onBeforeEmitNode == null ? void 0 : onBeforeEmitNode(node);
        if (emitComments2) emitCommentsBeforeNode(node);
        if (emitSourceMaps) emitSourceMapsBeforeNode(node);
        beforeEmitNode(node);
      } else {
        state = {
          stackIndex: 0,
          preserveSourceNewlinesStack: [void 0],
          containerPosStack: [-1],
          containerEndStack: [-1],
          declarationListContainerEndStack: [-1],
          shouldEmitCommentsStack: [false],
          shouldEmitSourceMapsStack: [false]
        };
      }
      return state;
    }
    function onLeft(next, _workArea, parent) {
      return maybeEmitExpression(next, parent, "left");
    }
    function onOperator(operatorToken, _state, node) {
      const isCommaOperator = operatorToken.kind !== 28 /* CommaToken */;
      const linesBeforeOperator = getLinesBetweenNodes(node, node.left, operatorToken);
      const linesAfterOperator = getLinesBetweenNodes(node, operatorToken, node.right);
      writeLinesAndIndent(linesBeforeOperator, isCommaOperator);
      emitLeadingCommentsOfPosition(operatorToken.pos);
      writeTokenNode(operatorToken, operatorToken.kind === 103 /* InKeyword */ ? writeKeyword : writeOperator);
      emitTrailingCommentsOfPosition(
        operatorToken.end,
        /*prefixSpace*/
        true
      );
      writeLinesAndIndent(
        linesAfterOperator,
        /*writeSpaceIfNotIndenting*/
        true
      );
    }
    function onRight(next, _workArea, parent) {
      return maybeEmitExpression(next, parent, "right");
    }
    function onExit(node, state) {
      const linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken);
      const linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right);
      decreaseIndentIf(linesBeforeOperator, linesAfterOperator);
      if (state.stackIndex > 0) {
        const savedPreserveSourceNewlines = state.preserveSourceNewlinesStack[state.stackIndex];
        const savedContainerPos = state.containerPosStack[state.stackIndex];
        const savedContainerEnd = state.containerEndStack[state.stackIndex];
        const savedDeclarationListContainerEnd = state.declarationListContainerEndStack[state.stackIndex];
        const shouldEmitComments2 = state.shouldEmitCommentsStack[state.stackIndex];
        const shouldEmitSourceMaps2 = state.shouldEmitSourceMapsStack[state.stackIndex];
        afterEmitNode(savedPreserveSourceNewlines);
        if (shouldEmitSourceMaps2) emitSourceMapsAfterNode(node);
        if (shouldEmitComments2) emitCommentsAfterNode(node, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd);
        onAfterEmitNode == null ? void 0 : onAfterEmitNode(node);
        state.stackIndex--;
      }
    }
    function maybeEmitExpression(next, parent, side) {
      const parenthesizerRule = side === "left" ? parenthesizer.getParenthesizeLeftSideOfBinaryForOperator(parent.operatorToken.kind) : parenthesizer.getParenthesizeRightSideOfBinaryForOperator(parent.operatorToken.kind);
      let pipelinePhase = getPipelinePhase(0 /* Notification */, 1 /* Expression */, next);
      if (pipelinePhase === pipelineEmitWithSubstitution) {
        Debug.assertIsDefined(lastSubstitution);
        next = parenthesizerRule(cast(lastSubstitution, isExpression));
        pipelinePhase = getNextPipelinePhase(1 /* Substitution */, 1 /* Expression */, next);
        lastSubstitution = void 0;
      }
      if (pipelinePhase === pipelineEmitWithComments || pipelinePhase === pipelineEmitWithSourceMaps || pipelinePhase === pipelineEmitWithHint) {
        if (isBinaryExpression(next)) {
          return next;
        }
      }
      currentParenthesizerRule = parenthesizerRule;
      pipelinePhase(1 /* Expression */, next);
    }
  }
  function emitConditionalExpression(node) {
    const linesBeforeQuestion = getLinesBetweenNodes(node, node.condition, node.questionToken);
    const linesAfterQuestion = getLinesBetweenNodes(node, node.questionToken, node.whenTrue);
    const linesBeforeColon = getLinesBetweenNodes(node, node.whenTrue, node.colonToken);
    const linesAfterColon = getLinesBetweenNodes(node, node.colonToken, node.whenFalse);
    emitExpression(node.condition, parenthesizer.parenthesizeConditionOfConditionalExpression);
    writeLinesAndIndent(
      linesBeforeQuestion,
      /*writeSpaceIfNotIndenting*/
      true
    );
    emit(node.questionToken);
    writeLinesAndIndent(
      linesAfterQuestion,
      /*writeSpaceIfNotIndenting*/
      true
    );
    emitExpression(node.whenTrue, parenthesizer.parenthesizeBranchOfConditionalExpression);
    decreaseIndentIf(linesBeforeQuestion, linesAfterQuestion);
    writeLinesAndIndent(
      linesBeforeColon,
      /*writeSpaceIfNotIndenting*/
      true
    );
    emit(node.colonToken);
    writeLinesAndIndent(
      linesAfterColon,
      /*writeSpaceIfNotIndenting*/
      true
    );
    emitExpression(node.whenFalse, parenthesizer.parenthesizeBranchOfConditionalExpression);
    decreaseIndentIf(linesBeforeColon, linesAfterColon);
  }
  function emitTemplateExpression(node) {
    emit(node.head);
    emitList(node, node.templateSpans, 262144 /* TemplateExpressionSpans */);
  }
  function emitYieldExpression(node) {
    emitTokenWithComment(127 /* YieldKeyword */, node.pos, writeKeyword, node);
    emit(node.asteriskToken);
    emitExpressionWithLeadingSpace(node.expression && parenthesizeExpressionForNoAsi(node.expression), parenthesizeExpressionForNoAsiAndDisallowedComma);
  }
  function emitSpreadElement(node) {
    emitTokenWithComment(26 /* DotDotDotToken */, node.pos, writePunctuation, node);
    emitExpression(node.expression, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitClassExpression(node) {
    generateNameIfNeeded(node.name);
    emitClassDeclarationOrExpression(node);
  }
  function emitExpressionWithTypeArguments(node) {
    emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess);
    emitTypeArguments(node, node.typeArguments);
  }
  function emitAsExpression(node) {
    emitExpression(
      node.expression,
      /*parenthesizerRule*/
      void 0
    );
    if (node.type) {
      writeSpace();
      writeKeyword("as");
      writeSpace();
      emit(node.type);
    }
  }
  function emitNonNullExpression(node) {
    emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess);
    writeOperator("!");
  }
  function emitSatisfiesExpression(node) {
    emitExpression(
      node.expression,
      /*parenthesizerRule*/
      void 0
    );
    if (node.type) {
      writeSpace();
      writeKeyword("satisfies");
      writeSpace();
      emit(node.type);
    }
  }
  function emitMetaProperty(node) {
    writeToken(node.keywordToken, node.pos, writePunctuation);
    writePunctuation(".");
    emit(node.name);
  }
  function emitTemplateSpan(node) {
    emitExpression(node.expression);
    emit(node.literal);
  }
  function emitBlock(node) {
    emitBlockStatements(
      node,
      /*forceSingleLine*/
      !node.multiLine && isEmptyBlock(node)
    );
  }
  function emitBlockStatements(node, forceSingleLine) {
    emitTokenWithComment(
      19 /* OpenBraceToken */,
      node.pos,
      writePunctuation,
      /*contextNode*/
      node
    );
    const format = forceSingleLine || getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineBlockStatements */ : 129 /* MultiLineBlockStatements */;
    emitList(node, node.statements, format);
    emitTokenWithComment(
      20 /* CloseBraceToken */,
      node.statements.end,
      writePunctuation,
      /*contextNode*/
      node,
      /*indentLeading*/
      !!(format & 1 /* MultiLine */)
    );
  }
  function emitVariableStatement(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    emit(node.declarationList);
    writeTrailingSemicolon();
  }
  function emitEmptyStatement(isEmbeddedStatement) {
    if (isEmbeddedStatement) {
      writePunctuation(";");
    } else {
      writeTrailingSemicolon();
    }
  }
  function emitExpressionStatement(node) {
    emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfExpressionStatement);
    if (!currentSourceFile || !isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) {
      writeTrailingSemicolon();
    }
  }
  function emitIfStatement(node) {
    const openParenPos = emitTokenWithComment(101 /* IfKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitTokenWithComment(21 /* OpenParenToken */, openParenPos, writePunctuation, node);
    emitExpression(node.expression);
    emitTokenWithComment(22 /* CloseParenToken */, node.expression.end, writePunctuation, node);
    emitEmbeddedStatement(node, node.thenStatement);
    if (node.elseStatement) {
      writeLineOrSpace(node, node.thenStatement, node.elseStatement);
      emitTokenWithComment(93 /* ElseKeyword */, node.thenStatement.end, writeKeyword, node);
      if (node.elseStatement.kind === 245 /* IfStatement */) {
        writeSpace();
        emit(node.elseStatement);
      } else {
        emitEmbeddedStatement(node, node.elseStatement);
      }
    }
  }
  function emitWhileClause(node, startPos) {
    const openParenPos = emitTokenWithComment(117 /* WhileKeyword */, startPos, writeKeyword, node);
    writeSpace();
    emitTokenWithComment(21 /* OpenParenToken */, openParenPos, writePunctuation, node);
    emitExpression(node.expression);
    emitTokenWithComment(22 /* CloseParenToken */, node.expression.end, writePunctuation, node);
  }
  function emitDoStatement(node) {
    emitTokenWithComment(92 /* DoKeyword */, node.pos, writeKeyword, node);
    emitEmbeddedStatement(node, node.statement);
    if (isBlock(node.statement) && !preserveSourceNewlines) {
      writeSpace();
    } else {
      writeLineOrSpace(node, node.statement, node.expression);
    }
    emitWhileClause(node, node.statement.end);
    writeTrailingSemicolon();
  }
  function emitWhileStatement(node) {
    emitWhileClause(node, node.pos);
    emitEmbeddedStatement(node, node.statement);
  }
  function emitForStatement(node) {
    const openParenPos = emitTokenWithComment(99 /* ForKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    let pos = emitTokenWithComment(
      21 /* OpenParenToken */,
      openParenPos,
      writePunctuation,
      /*contextNode*/
      node
    );
    emitForBinding(node.initializer);
    pos = emitTokenWithComment(27 /* SemicolonToken */, node.initializer ? node.initializer.end : pos, writePunctuation, node);
    emitExpressionWithLeadingSpace(node.condition);
    pos = emitTokenWithComment(27 /* SemicolonToken */, node.condition ? node.condition.end : pos, writePunctuation, node);
    emitExpressionWithLeadingSpace(node.incrementor);
    emitTokenWithComment(22 /* CloseParenToken */, node.incrementor ? node.incrementor.end : pos, writePunctuation, node);
    emitEmbeddedStatement(node, node.statement);
  }
  function emitForInStatement(node) {
    const openParenPos = emitTokenWithComment(99 /* ForKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitTokenWithComment(21 /* OpenParenToken */, openParenPos, writePunctuation, node);
    emitForBinding(node.initializer);
    writeSpace();
    emitTokenWithComment(103 /* InKeyword */, node.initializer.end, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression);
    emitTokenWithComment(22 /* CloseParenToken */, node.expression.end, writePunctuation, node);
    emitEmbeddedStatement(node, node.statement);
  }
  function emitForOfStatement(node) {
    const openParenPos = emitTokenWithComment(99 /* ForKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitWithTrailingSpace(node.awaitModifier);
    emitTokenWithComment(21 /* OpenParenToken */, openParenPos, writePunctuation, node);
    emitForBinding(node.initializer);
    writeSpace();
    emitTokenWithComment(165 /* OfKeyword */, node.initializer.end, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression);
    emitTokenWithComment(22 /* CloseParenToken */, node.expression.end, writePunctuation, node);
    emitEmbeddedStatement(node, node.statement);
  }
  function emitForBinding(node) {
    if (node !== void 0) {
      if (node.kind === 261 /* VariableDeclarationList */) {
        emit(node);
      } else {
        emitExpression(node);
      }
    }
  }
  function emitContinueStatement(node) {
    emitTokenWithComment(88 /* ContinueKeyword */, node.pos, writeKeyword, node);
    emitWithLeadingSpace(node.label);
    writeTrailingSemicolon();
  }
  function emitBreakStatement(node) {
    emitTokenWithComment(83 /* BreakKeyword */, node.pos, writeKeyword, node);
    emitWithLeadingSpace(node.label);
    writeTrailingSemicolon();
  }
  function emitTokenWithComment(token, pos, writer2, contextNode, indentLeading) {
    const node = getParseTreeNode(contextNode);
    const isSimilarNode = node && node.kind === contextNode.kind;
    const startPos = pos;
    if (isSimilarNode && currentSourceFile) {
      pos = skipTrivia(currentSourceFile.text, pos);
    }
    if (isSimilarNode && contextNode.pos !== startPos) {
      const needsIndent = indentLeading && currentSourceFile && !positionsAreOnSameLine(startPos, pos, currentSourceFile);
      if (needsIndent) {
        increaseIndent();
      }
      emitLeadingCommentsOfPosition(startPos);
      if (needsIndent) {
        decreaseIndent();
      }
    }
    if (!omitBraceSourcePositions && (token === 19 /* OpenBraceToken */ || token === 20 /* CloseBraceToken */)) {
      pos = writeToken(token, pos, writer2, contextNode);
    } else {
      pos = writeTokenText(token, writer2, pos);
    }
    if (isSimilarNode && contextNode.end !== pos) {
      const isJsxExprContext = contextNode.kind === 294 /* JsxExpression */;
      emitTrailingCommentsOfPosition(
        pos,
        /*prefixSpace*/
        !isJsxExprContext,
        /*forceNoNewline*/
        isJsxExprContext
      );
    }
    return pos;
  }
  function commentWillEmitNewLine(node) {
    return node.kind === 2 /* SingleLineCommentTrivia */ || !!node.hasTrailingNewLine;
  }
  function willEmitLeadingNewLine(node) {
    if (!currentSourceFile) return false;
    const leadingCommentRanges = getLeadingCommentRanges(currentSourceFile.text, node.pos);
    if (leadingCommentRanges) {
      const parseNode = getParseTreeNode(node);
      if (parseNode && isParenthesizedExpression(parseNode.parent)) {
        return true;
      }
    }
    if (some(leadingCommentRanges, commentWillEmitNewLine)) return true;
    if (some(getSyntheticLeadingComments(node), commentWillEmitNewLine)) return true;
    if (isPartiallyEmittedExpression(node)) {
      if (node.pos !== node.expression.pos) {
        if (some(getTrailingCommentRanges(currentSourceFile.text, node.expression.pos), commentWillEmitNewLine)) return true;
      }
      return willEmitLeadingNewLine(node.expression);
    }
    return false;
  }
  function parenthesizeExpressionForNoAsi(node) {
    if (!commentsDisabled && isPartiallyEmittedExpression(node) && willEmitLeadingNewLine(node)) {
      const parseNode = getParseTreeNode(node);
      if (parseNode && isParenthesizedExpression(parseNode)) {
        const parens = factory.createParenthesizedExpression(node.expression);
        setOriginalNode(parens, node);
        setTextRange(parens, parseNode);
        return parens;
      }
      return factory.createParenthesizedExpression(node);
    }
    return node;
  }
  function parenthesizeExpressionForNoAsiAndDisallowedComma(node) {
    return parenthesizeExpressionForNoAsi(parenthesizer.parenthesizeExpressionForDisallowedComma(node));
  }
  function emitReturnStatement(node) {
    emitTokenWithComment(
      107 /* ReturnKeyword */,
      node.pos,
      writeKeyword,
      /*contextNode*/
      node
    );
    emitExpressionWithLeadingSpace(node.expression && parenthesizeExpressionForNoAsi(node.expression), parenthesizeExpressionForNoAsi);
    writeTrailingSemicolon();
  }
  function emitWithStatement(node) {
    const openParenPos = emitTokenWithComment(118 /* WithKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitTokenWithComment(21 /* OpenParenToken */, openParenPos, writePunctuation, node);
    emitExpression(node.expression);
    emitTokenWithComment(22 /* CloseParenToken */, node.expression.end, writePunctuation, node);
    emitEmbeddedStatement(node, node.statement);
  }
  function emitSwitchStatement(node) {
    const openParenPos = emitTokenWithComment(109 /* SwitchKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitTokenWithComment(21 /* OpenParenToken */, openParenPos, writePunctuation, node);
    emitExpression(node.expression);
    emitTokenWithComment(22 /* CloseParenToken */, node.expression.end, writePunctuation, node);
    writeSpace();
    emit(node.caseBlock);
  }
  function emitLabeledStatement(node) {
    emit(node.label);
    emitTokenWithComment(59 /* ColonToken */, node.label.end, writePunctuation, node);
    writeSpace();
    emit(node.statement);
  }
  function emitThrowStatement(node) {
    emitTokenWithComment(111 /* ThrowKeyword */, node.pos, writeKeyword, node);
    emitExpressionWithLeadingSpace(parenthesizeExpressionForNoAsi(node.expression), parenthesizeExpressionForNoAsi);
    writeTrailingSemicolon();
  }
  function emitTryStatement(node) {
    emitTokenWithComment(113 /* TryKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emit(node.tryBlock);
    if (node.catchClause) {
      writeLineOrSpace(node, node.tryBlock, node.catchClause);
      emit(node.catchClause);
    }
    if (node.finallyBlock) {
      writeLineOrSpace(node, node.catchClause || node.tryBlock, node.finallyBlock);
      emitTokenWithComment(98 /* FinallyKeyword */, (node.catchClause || node.tryBlock).end, writeKeyword, node);
      writeSpace();
      emit(node.finallyBlock);
    }
  }
  function emitDebuggerStatement(node) {
    writeToken(89 /* DebuggerKeyword */, node.pos, writeKeyword);
    writeTrailingSemicolon();
  }
  function emitVariableDeclaration(node) {
    var _a, _b, _c;
    emit(node.name);
    emit(node.exclamationToken);
    emitTypeAnnotation(node.type);
    emitInitializer(node.initializer, ((_a = node.type) == null ? void 0 : _a.end) ?? ((_c = (_b = node.name.emitNode) == null ? void 0 : _b.typeNode) == null ? void 0 : _c.end) ?? node.name.end, node, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitVariableDeclarationList(node) {
    if (isVarAwaitUsing(node)) {
      writeKeyword("await");
      writeSpace();
      writeKeyword("using");
    } else {
      const head = isLet(node) ? "let" : isVarConst(node) ? "const" : isVarUsing(node) ? "using" : "var";
      writeKeyword(head);
    }
    writeSpace();
    emitList(node, node.declarations, 528 /* VariableDeclarationList */);
  }
  function emitFunctionDeclaration(node) {
    emitFunctionDeclarationOrExpression(node);
  }
  function emitFunctionDeclarationOrExpression(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    writeKeyword("function");
    emit(node.asteriskToken);
    writeSpace();
    emitIdentifierName(node.name);
    emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
  }
  function emitSignatureAndBody(node, emitSignatureHead2, emitBody) {
    const indentedFlag = getEmitFlags(node) & 131072 /* Indented */;
    if (indentedFlag) {
      increaseIndent();
    }
    pushNameGenerationScope(node);
    forEach(node.parameters, generateNames);
    emitSignatureHead2(node);
    emitBody(node);
    popNameGenerationScope(node);
    if (indentedFlag) {
      decreaseIndent();
    }
  }
  function emitFunctionBody(node) {
    const body = node.body;
    if (body) {
      emitBlockFunctionBody(body);
    } else {
      writeTrailingSemicolon();
    }
  }
  function emitEmptyFunctionBody(_node) {
    writeTrailingSemicolon();
  }
  function emitSignatureHead(node) {
    emitTypeParameters(node, node.typeParameters);
    emitParameters(node, node.parameters);
    emitTypeAnnotation(node.type);
  }
  function shouldEmitBlockFunctionBodyOnSingleLine(body) {
    if (getEmitFlags(body) & 1 /* SingleLine */) {
      return true;
    }
    if (body.multiLine) {
      return false;
    }
    if (!nodeIsSynthesized(body) && currentSourceFile && !rangeIsOnSingleLine(body, currentSourceFile)) {
      return false;
    }
    if (getLeadingLineTerminatorCount(body, firstOrUndefined(body.statements), 2 /* PreserveLines */) || getClosingLineTerminatorCount(body, lastOrUndefined(body.statements), 2 /* PreserveLines */, body.statements)) {
      return false;
    }
    let previousStatement;
    for (const statement of body.statements) {
      if (getSeparatingLineTerminatorCount(previousStatement, statement, 2 /* PreserveLines */) > 0) {
        return false;
      }
      previousStatement = statement;
    }
    return true;
  }
  function emitBlockFunctionBody(body) {
    generateNames(body);
    onBeforeEmitNode == null ? void 0 : onBeforeEmitNode(body);
    writeSpace();
    writePunctuation("{");
    increaseIndent();
    const emitBlockFunctionBody2 = shouldEmitBlockFunctionBodyOnSingleLine(body) ? emitBlockFunctionBodyOnSingleLine : emitBlockFunctionBodyWorker;
    emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody2);
    decreaseIndent();
    writeToken(20 /* CloseBraceToken */, body.statements.end, writePunctuation, body);
    onAfterEmitNode == null ? void 0 : onAfterEmitNode(body);
  }
  function emitBlockFunctionBodyOnSingleLine(body) {
    emitBlockFunctionBodyWorker(
      body,
      /*emitBlockFunctionBodyOnSingleLine*/
      true
    );
  }
  function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine2) {
    const statementOffset = emitPrologueDirectives(body.statements);
    const pos = writer.getTextPos();
    emitHelpers(body);
    if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine2) {
      decreaseIndent();
      emitList(body, body.statements, 768 /* SingleLineFunctionBodyStatements */);
      increaseIndent();
    } else {
      emitList(
        body,
        body.statements,
        1 /* MultiLineFunctionBodyStatements */,
        /*parenthesizerRule*/
        void 0,
        statementOffset
      );
    }
  }
  function emitClassDeclaration(node) {
    emitClassDeclarationOrExpression(node);
  }
  function emitClassDeclarationOrExpression(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      true
    );
    emitTokenWithComment(86 /* ClassKeyword */, moveRangePastModifiers(node).pos, writeKeyword, node);
    if (node.name) {
      writeSpace();
      emitIdentifierName(node.name);
    }
    const indentedFlag = getEmitFlags(node) & 131072 /* Indented */;
    if (indentedFlag) {
      increaseIndent();
    }
    emitTypeParameters(node, node.typeParameters);
    emitList(node, node.heritageClauses, 0 /* ClassHeritageClauses */);
    writeSpace();
    writePunctuation("{");
    pushNameGenerationScope(node);
    forEach(node.members, generateMemberNames);
    emitList(node, node.members, 129 /* ClassMembers */);
    popNameGenerationScope(node);
    writePunctuation("}");
    if (indentedFlag) {
      decreaseIndent();
    }
  }
  function emitInterfaceDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    writeKeyword("interface");
    writeSpace();
    emit(node.name);
    emitTypeParameters(node, node.typeParameters);
    emitList(node, node.heritageClauses, 512 /* HeritageClauses */);
    writeSpace();
    writePunctuation("{");
    pushNameGenerationScope(node);
    forEach(node.members, generateMemberNames);
    emitList(node, node.members, 129 /* InterfaceMembers */);
    popNameGenerationScope(node);
    writePunctuation("}");
  }
  function emitTypeAliasDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    writeKeyword("type");
    writeSpace();
    emit(node.name);
    emitTypeParameters(node, node.typeParameters);
    writeSpace();
    writePunctuation("=");
    writeSpace();
    emit(node.type);
    writeTrailingSemicolon();
  }
  function emitEnumDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    writeKeyword("enum");
    writeSpace();
    emit(node.name);
    writeSpace();
    writePunctuation("{");
    emitList(node, node.members, 145 /* EnumMembers */);
    writePunctuation("}");
  }
  function emitModuleDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    if (~node.flags & 2048 /* GlobalAugmentation */) {
      writeKeyword(node.flags & 32 /* Namespace */ ? "namespace" : "module");
      writeSpace();
    }
    emit(node.name);
    let body = node.body;
    if (!body) return writeTrailingSemicolon();
    while (body && isModuleDeclaration(body)) {
      writePunctuation(".");
      emit(body.name);
      body = body.body;
    }
    writeSpace();
    emit(body);
  }
  function emitModuleBlock(node) {
    pushNameGenerationScope(node);
    forEach(node.statements, generateNames);
    emitBlockStatements(
      node,
      /*forceSingleLine*/
      isEmptyBlock(node)
    );
    popNameGenerationScope(node);
  }
  function emitCaseBlock(node) {
    emitTokenWithComment(19 /* OpenBraceToken */, node.pos, writePunctuation, node);
    emitList(node, node.clauses, 129 /* CaseBlockClauses */);
    emitTokenWithComment(
      20 /* CloseBraceToken */,
      node.clauses.end,
      writePunctuation,
      node,
      /*indentLeading*/
      true
    );
  }
  function emitImportEqualsDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    emitTokenWithComment(102 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
    writeSpace();
    if (node.isTypeOnly) {
      emitTokenWithComment(156 /* TypeKeyword */, node.pos, writeKeyword, node);
      writeSpace();
    }
    emit(node.name);
    writeSpace();
    emitTokenWithComment(64 /* EqualsToken */, node.name.end, writePunctuation, node);
    writeSpace();
    emitModuleReference(node.moduleReference);
    writeTrailingSemicolon();
  }
  function emitModuleReference(node) {
    if (node.kind === 80 /* Identifier */) {
      emitExpression(node);
    } else {
      emit(node);
    }
  }
  function emitImportDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    emitTokenWithComment(102 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
    writeSpace();
    if (node.importClause) {
      emit(node.importClause);
      writeSpace();
      emitTokenWithComment(161 /* FromKeyword */, node.importClause.end, writeKeyword, node);
      writeSpace();
    }
    emitExpression(node.moduleSpecifier);
    if (node.attributes) {
      emitWithLeadingSpace(node.attributes);
    }
    writeTrailingSemicolon();
  }
  function emitImportClause(node) {
    if (node.isTypeOnly) {
      emitTokenWithComment(156 /* TypeKeyword */, node.pos, writeKeyword, node);
      writeSpace();
    }
    emit(node.name);
    if (node.name && node.namedBindings) {
      emitTokenWithComment(28 /* CommaToken */, node.name.end, writePunctuation, node);
      writeSpace();
    }
    emit(node.namedBindings);
  }
  function emitNamespaceImport(node) {
    const asPos = emitTokenWithComment(42 /* AsteriskToken */, node.pos, writePunctuation, node);
    writeSpace();
    emitTokenWithComment(130 /* AsKeyword */, asPos, writeKeyword, node);
    writeSpace();
    emit(node.name);
  }
  function emitNamedImports(node) {
    emitNamedImportsOrExports(node);
  }
  function emitImportSpecifier(node) {
    emitImportOrExportSpecifier(node);
  }
  function emitExportAssignment(node) {
    const nextPos = emitTokenWithComment(95 /* ExportKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    if (node.isExportEquals) {
      emitTokenWithComment(64 /* EqualsToken */, nextPos, writeOperator, node);
    } else {
      emitTokenWithComment(90 /* DefaultKeyword */, nextPos, writeKeyword, node);
    }
    writeSpace();
    emitExpression(
      node.expression,
      node.isExportEquals ? parenthesizer.getParenthesizeRightSideOfBinaryForOperator(64 /* EqualsToken */) : parenthesizer.parenthesizeExpressionOfExportDefault
    );
    writeTrailingSemicolon();
  }
  function emitExportDeclaration(node) {
    emitDecoratorsAndModifiers(
      node,
      node.modifiers,
      /*allowDecorators*/
      false
    );
    let nextPos = emitTokenWithComment(95 /* ExportKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    if (node.isTypeOnly) {
      nextPos = emitTokenWithComment(156 /* TypeKeyword */, nextPos, writeKeyword, node);
      writeSpace();
    }
    if (node.exportClause) {
      emit(node.exportClause);
    } else {
      nextPos = emitTokenWithComment(42 /* AsteriskToken */, nextPos, writePunctuation, node);
    }
    if (node.moduleSpecifier) {
      writeSpace();
      const fromPos = node.exportClause ? node.exportClause.end : nextPos;
      emitTokenWithComment(161 /* FromKeyword */, fromPos, writeKeyword, node);
      writeSpace();
      emitExpression(node.moduleSpecifier);
    }
    if (node.attributes) {
      emitWithLeadingSpace(node.attributes);
    }
    writeTrailingSemicolon();
  }
  function emitImportTypeNodeAttributes(node) {
    writePunctuation("{");
    writeSpace();
    writeKeyword(node.token === 132 /* AssertKeyword */ ? "assert" : "with");
    writePunctuation(":");
    writeSpace();
    const elements = node.elements;
    emitList(node, elements, 526226 /* ImportAttributes */);
    writeSpace();
    writePunctuation("}");
  }
  function emitImportAttributes(node) {
    emitTokenWithComment(node.token, node.pos, writeKeyword, node);
    writeSpace();
    const elements = node.elements;
    emitList(node, elements, 526226 /* ImportAttributes */);
  }
  function emitImportAttribute(node) {
    emit(node.name);
    writePunctuation(":");
    writeSpace();
    const value = node.value;
    if ((getEmitFlags(value) & 1024 /* NoLeadingComments */) === 0) {
      const commentRange = getCommentRange(value);
      emitTrailingCommentsOfPosition(commentRange.pos);
    }
    emit(value);
  }
  function emitNamespaceExportDeclaration(node) {
    let nextPos = emitTokenWithComment(95 /* ExportKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    nextPos = emitTokenWithComment(130 /* AsKeyword */, nextPos, writeKeyword, node);
    writeSpace();
    nextPos = emitTokenWithComment(145 /* NamespaceKeyword */, nextPos, writeKeyword, node);
    writeSpace();
    emit(node.name);
    writeTrailingSemicolon();
  }
  function emitNamespaceExport(node) {
    const asPos = emitTokenWithComment(42 /* AsteriskToken */, node.pos, writePunctuation, node);
    writeSpace();
    emitTokenWithComment(130 /* AsKeyword */, asPos, writeKeyword, node);
    writeSpace();
    emit(node.name);
  }
  function emitNamedExports(node) {
    emitNamedImportsOrExports(node);
  }
  function emitExportSpecifier(node) {
    emitImportOrExportSpecifier(node);
  }
  function emitNamedImportsOrExports(node) {
    writePunctuation("{");
    emitList(node, node.elements, 525136 /* NamedImportsOrExportsElements */);
    writePunctuation("}");
  }
  function emitImportOrExportSpecifier(node) {
    if (node.isTypeOnly) {
      writeKeyword("type");
      writeSpace();
    }
    if (node.propertyName) {
      emit(node.propertyName);
      writeSpace();
      emitTokenWithComment(130 /* AsKeyword */, node.propertyName.end, writeKeyword, node);
      writeSpace();
    }
    emit(node.name);
  }
  function emitExternalModuleReference(node) {
    writeKeyword("require");
    writePunctuation("(");
    emitExpression(node.expression);
    writePunctuation(")");
  }
  function emitJsxElement(node) {
    emit(node.openingElement);
    emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
    emit(node.closingElement);
  }
  function emitJsxSelfClosingElement(node) {
    writePunctuation("<");
    emitJsxTagName(node.tagName);
    emitTypeArguments(node, node.typeArguments);
    writeSpace();
    emit(node.attributes);
    writePunctuation("/>");
  }
  function emitJsxFragment(node) {
    emit(node.openingFragment);
    emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
    emit(node.closingFragment);
  }
  function emitJsxOpeningElementOrFragment(node) {
    writePunctuation("<");
    if (isJsxOpeningElement(node)) {
      const indented = writeLineSeparatorsAndIndentBefore(node.tagName, node);
      emitJsxTagName(node.tagName);
      emitTypeArguments(node, node.typeArguments);
      if (node.attributes.properties && node.attributes.properties.length > 0) {
        writeSpace();
      }
      emit(node.attributes);
      writeLineSeparatorsAfter(node.attributes, node);
      decreaseIndentIf(indented);
    }
    writePunctuation(">");
  }
  function emitJsxText(node) {
    writer.writeLiteral(node.text);
  }
  function emitJsxClosingElementOrFragment(node) {
    writePunctuation("</");
    if (isJsxClosingElement(node)) {
      emitJsxTagName(node.tagName);
    }
    writePunctuation(">");
  }
  function emitJsxAttributes(node) {
    emitList(node, node.properties, 262656 /* JsxElementAttributes */);
  }
  function emitJsxAttribute(node) {
    emit(node.name);
    emitNodeWithPrefix("=", writePunctuation, node.initializer, emitJsxAttributeValue);
  }
  function emitJsxSpreadAttribute(node) {
    writePunctuation("{...");
    emitExpression(node.expression);
    writePunctuation("}");
  }
  function hasTrailingCommentsAtPosition(pos) {
    let result = false;
    forEachTrailingCommentRange((currentSourceFile == null ? void 0 : currentSourceFile.text) || "", pos + 1, () => result = true);
    return result;
  }
  function hasLeadingCommentsAtPosition(pos) {
    let result = false;
    forEachLeadingCommentRange((currentSourceFile == null ? void 0 : currentSourceFile.text) || "", pos + 1, () => result = true);
    return result;
  }
  function hasCommentsAtPosition(pos) {
    return hasTrailingCommentsAtPosition(pos) || hasLeadingCommentsAtPosition(pos);
  }
  function emitJsxExpression(node) {
    var _a;
    if (node.expression || !commentsDisabled && !nodeIsSynthesized(node) && hasCommentsAtPosition(node.pos)) {
      const isMultiline = currentSourceFile && !nodeIsSynthesized(node) && getLineAndCharacterOfPosition(currentSourceFile, node.pos).line !== getLineAndCharacterOfPosition(currentSourceFile, node.end).line;
      if (isMultiline) {
        writer.increaseIndent();
      }
      const end = emitTokenWithComment(19 /* OpenBraceToken */, node.pos, writePunctuation, node);
      emit(node.dotDotDotToken);
      emitExpression(node.expression);
      emitTokenWithComment(20 /* CloseBraceToken */, ((_a = node.expression) == null ? void 0 : _a.end) || end, writePunctuation, node);
      if (isMultiline) {
        writer.decreaseIndent();
      }
    }
  }
  function emitJsxNamespacedName(node) {
    emitIdentifierName(node.namespace);
    writePunctuation(":");
    emitIdentifierName(node.name);
  }
  function emitJsxTagName(node) {
    if (node.kind === 80 /* Identifier */) {
      emitExpression(node);
    } else {
      emit(node);
    }
  }
  function emitCaseClause(node) {
    emitTokenWithComment(84 /* CaseKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    emitExpression(node.expression, parenthesizer.parenthesizeExpressionForDisallowedComma);
    emitCaseOrDefaultClauseRest(node, node.statements, node.expression.end);
  }
  function emitDefaultClause(node) {
    const pos = emitTokenWithComment(90 /* DefaultKeyword */, node.pos, writeKeyword, node);
    emitCaseOrDefaultClauseRest(node, node.statements, pos);
  }
  function emitCaseOrDefaultClauseRest(parentNode, statements, colonPos) {
    const emitAsSingleStatement = statements.length === 1 && // treat synthesized nodes as located on the same line for emit purposes
    (!currentSourceFile || nodeIsSynthesized(parentNode) || nodeIsSynthesized(statements[0]) || rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile));
    let format = 163969 /* CaseOrDefaultClauseStatements */;
    if (emitAsSingleStatement) {
      writeToken(59 /* ColonToken */, colonPos, writePunctuation, parentNode);
      writeSpace();
      format &= ~(1 /* MultiLine */ | 128 /* Indented */);
    } else {
      emitTokenWithComment(59 /* ColonToken */, colonPos, writePunctuation, parentNode);
    }
    emitList(parentNode, statements, format);
  }
  function emitHeritageClause(node) {
    writeSpace();
    writeTokenText(node.token, writeKeyword);
    writeSpace();
    emitList(node, node.types, 528 /* HeritageClauseTypes */);
  }
  function emitCatchClause(node) {
    const openParenPos = emitTokenWithComment(85 /* CatchKeyword */, node.pos, writeKeyword, node);
    writeSpace();
    if (node.variableDeclaration) {
      emitTokenWithComment(21 /* OpenParenToken */, openParenPos, writePunctuation, node);
      emit(node.variableDeclaration);
      emitTokenWithComment(22 /* CloseParenToken */, node.variableDeclaration.end, writePunctuation, node);
      writeSpace();
    }
    emit(node.block);
  }
  function emitPropertyAssignment(node) {
    emit(node.name);
    writePunctuation(":");
    writeSpace();
    const initializer = node.initializer;
    if ((getEmitFlags(initializer) & 1024 /* NoLeadingComments */) === 0) {
      const commentRange = getCommentRange(initializer);
      emitTrailingCommentsOfPosition(commentRange.pos);
    }
    emitExpression(initializer, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitShorthandPropertyAssignment(node) {
    emit(node.name);
    if (node.objectAssignmentInitializer) {
      writeSpace();
      writePunctuation("=");
      writeSpace();
      emitExpression(node.objectAssignmentInitializer, parenthesizer.parenthesizeExpressionForDisallowedComma);
    }
  }
  function emitSpreadAssignment(node) {
    if (node.expression) {
      emitTokenWithComment(26 /* DotDotDotToken */, node.pos, writePunctuation, node);
      emitExpression(node.expression, parenthesizer.parenthesizeExpressionForDisallowedComma);
    }
  }
  function emitEnumMember(node) {
    emit(node.name);
    emitInitializer(node.initializer, node.name.end, node, parenthesizer.parenthesizeExpressionForDisallowedComma);
  }
  function emitJSDoc(node) {
    write("/**");
    if (node.comment) {
      const text = getTextOfJSDocComment(node.comment);
      if (text) {
        const lines = text.split(/\r\n?|\n/g);
        for (const line of lines) {
          writeLine();
          writeSpace();
          writePunctuation("*");
          writeSpace();
          write(line);
        }
      }
    }
    if (node.tags) {
      if (node.tags.length === 1 && node.tags[0].kind === 344 /* JSDocTypeTag */ && !node.comment) {
        writeSpace();
        emit(node.tags[0]);
      } else {
        emitList(node, node.tags, 33 /* JSDocComment */);
      }
    }
    writeSpace();
    write("*/");
  }
  function emitJSDocSimpleTypedTag(tag) {
    emitJSDocTagName(tag.tagName);
    emitJSDocTypeExpression(tag.typeExpression);
    emitJSDocComment(tag.comment);
  }
  function emitJSDocSeeTag(tag) {
    emitJSDocTagName(tag.tagName);
    emit(tag.name);
    emitJSDocComment(tag.comment);
  }
  function emitJSDocImportTag(tag) {
    emitJSDocTagName(tag.tagName);
    writeSpace();
    if (tag.importClause) {
      emit(tag.importClause);
      writeSpace();
      emitTokenWithComment(161 /* FromKeyword */, tag.importClause.end, writeKeyword, tag);
      writeSpace();
    }
    emitExpression(tag.moduleSpecifier);
    if (tag.attributes) {
      emitWithLeadingSpace(tag.attributes);
    }
    emitJSDocComment(tag.comment);
  }
  function emitJSDocNameReference(node) {
    writeSpace();
    writePunctuation("{");
    emit(node.name);
    writePunctuation("}");
  }
  function emitJSDocHeritageTag(tag) {
    emitJSDocTagName(tag.tagName);
    writeSpace();
    writePunctuation("{");
    emit(tag.class);
    writePunctuation("}");
    emitJSDocComment(tag.comment);
  }
  function emitJSDocTemplateTag(tag) {
    emitJSDocTagName(tag.tagName);
    emitJSDocTypeExpression(tag.constraint);
    writeSpace();
    emitList(tag, tag.typeParameters, 528 /* CommaListElements */);
    emitJSDocComment(tag.comment);
  }
  function emitJSDocTypedefTag(tag) {
    emitJSDocTagName(tag.tagName);
    if (tag.typeExpression) {
      if (tag.typeExpression.kind === 309 /* JSDocTypeExpression */) {
        emitJSDocTypeExpression(tag.typeExpression);
      } else {
        writeSpace();
        writePunctuation("{");
        write("Object");
        if (tag.typeExpression.isArrayType) {
          writePunctuation("[");
          writePunctuation("]");
        }
        writePunctuation("}");
      }
    }
    if (tag.fullName) {
      writeSpace();
      emit(tag.fullName);
    }
    emitJSDocComment(tag.comment);
    if (tag.typeExpression && tag.typeExpression.kind === 322 /* JSDocTypeLiteral */) {
      emitJSDocTypeLiteral(tag.typeExpression);
    }
  }
  function emitJSDocCallbackTag(tag) {
    emitJSDocTagName(tag.tagName);
    if (tag.name) {
      writeSpace();
      emit(tag.name);
    }
    emitJSDocComment(tag.comment);
    emitJSDocSignature(tag.typeExpression);
  }
  function emitJSDocOverloadTag(tag) {
    emitJSDocComment(tag.comment);
    emitJSDocSignature(tag.typeExpression);
  }
  function emitJSDocSimpleTag(tag) {
    emitJSDocTagName(tag.tagName);
    emitJSDocComment(tag.comment);
  }
  function emitJSDocTypeLiteral(lit) {
    emitList(lit, factory.createNodeArray(lit.jsDocPropertyTags), 33 /* JSDocComment */);
  }
  function emitJSDocSignature(sig) {
    if (sig.typeParameters) {
      emitList(sig, factory.createNodeArray(sig.typeParameters), 33 /* JSDocComment */);
    }
    if (sig.parameters) {
      emitList(sig, factory.createNodeArray(sig.parameters), 33 /* JSDocComment */);
    }
    if (sig.type) {
      writeLine();
      writeSpace();
      writePunctuation("*");
      writeSpace();
      emit(sig.type);
    }
  }
  function emitJSDocPropertyLikeTag(param) {
    emitJSDocTagName(param.tagName);
    emitJSDocTypeExpression(param.typeExpression);
    writeSpace();
    if (param.isBracketed) {
      writePunctuation("[");
    }
    emit(param.name);
    if (param.isBracketed) {
      writePunctuation("]");
    }
    emitJSDocComment(param.comment);
  }
  function emitJSDocTagName(tagName) {
    writePunctuation("@");
    emit(tagName);
  }
  function emitJSDocComment(comment) {
    const text = getTextOfJSDocComment(comment);
    if (text) {
      writeSpace();
      write(text);
    }
  }
  function emitJSDocTypeExpression(typeExpression) {
    if (typeExpression) {
      writeSpace();
      writePunctuation("{");
      emit(typeExpression.type);
      writePunctuation("}");
    }
  }
  function emitSourceFile(node) {
    writeLine();
    const statements = node.statements;
    const shouldEmitDetachedComment = statements.length === 0 || !isPrologueDirective(statements[0]) || nodeIsSynthesized(statements[0]);
    if (shouldEmitDetachedComment) {
      emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
      return;
    }
    emitSourceFileWorker(node);
  }
  function emitSyntheticTripleSlashReferencesIfNeeded(node) {
    emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []);
  }
  function emitTripleSlashDirectivesIfNeeded(node) {
    if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives);
  }
  function emitTripleSlashDirectives(hasNoDefaultLib, files, types, libs2) {
    if (hasNoDefaultLib) {
      writeComment(`/// <reference no-default-lib="true"/>`);
      writeLine();
    }
    if (currentSourceFile && currentSourceFile.moduleName) {
      writeComment(`/// <amd-module name="${currentSourceFile.moduleName}" />`);
      writeLine();
    }
    if (currentSourceFile && currentSourceFile.amdDependencies) {
      for (const dep of currentSourceFile.amdDependencies) {
        if (dep.name) {
          writeComment(`/// <amd-dependency name="${dep.name}" path="${dep.path}" />`);
        } else {
          writeComment(`/// <amd-dependency path="${dep.path}" />`);
        }
        writeLine();
      }
    }
    function writeDirectives(kind, directives) {
      for (const directive of directives) {
        const resolutionMode = directive.resolutionMode ? `resolution-mode="${directive.resolutionMode === 99 /* ESNext */ ? "import" : "require"}" ` : "";
        const preserve = directive.preserve ? `preserve="true" ` : "";
        writeComment(`/// <reference ${kind}="${directive.fileName}" ${resolutionMode}${preserve}/>`);
        writeLine();
      }
    }
    writeDirectives("path", files);
    writeDirectives("types", types);
    writeDirectives("lib", libs2);
  }
  function emitSourceFileWorker(node) {
    const statements = node.statements;
    pushNameGenerationScope(node);
    forEach(node.statements, generateNames);
    emitHelpers(node);
    const index = findIndex(statements, (statement) => !isPrologueDirective(statement));
    emitTripleSlashDirectivesIfNeeded(node);
    emitList(
      node,
      statements,
      1 /* MultiLine */,
      /*parenthesizerRule*/
      void 0,
      index === -1 ? statements.length : index
    );
    popNameGenerationScope(node);
  }
  function emitPartiallyEmittedExpression(node) {
    const emitFlags = getEmitFlags(node);
    if (!(emitFlags & 1024 /* NoLeadingComments */) && node.pos !== node.expression.pos) {
      emitTrailingCommentsOfPosition(node.expression.pos);
    }
    emitExpression(node.expression);
    if (!(emitFlags & 2048 /* NoTrailingComments */) && node.end !== node.expression.end) {
      emitLeadingCommentsOfPosition(node.expression.end);
    }
  }
  function emitCommaList(node) {
    emitExpressionList(
      node,
      node.elements,
      528 /* CommaListElements */,
      /*parenthesizerRule*/
      void 0
    );
  }
  function emitPrologueDirectives(statements, sourceFile, seenPrologueDirectives) {
    let needsToSetSourceFile = !!sourceFile;
    for (let i = 0; i < statements.length; i++) {
      const statement = statements[i];
      if (isPrologueDirective(statement)) {
        const shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
        if (shouldEmitPrologueDirective) {
          if (needsToSetSourceFile) {
            needsToSetSourceFile = false;
            setSourceFile(sourceFile);
          }
          writeLine();
          emit(statement);
          if (seenPrologueDirectives) {
            seenPrologueDirectives.add(statement.expression.text);
          }
        }
      } else {
        return i;
      }
    }
    return statements.length;
  }
  function emitPrologueDirectivesIfNeeded(sourceFileOrBundle) {
    if (isSourceFile(sourceFileOrBundle)) {
      emitPrologueDirectives(sourceFileOrBundle.statements, sourceFileOrBundle);
    } else {
      const seenPrologueDirectives = /* @__PURE__ */ new Set();
      for (const sourceFile of sourceFileOrBundle.sourceFiles) {
        emitPrologueDirectives(sourceFile.statements, sourceFile, seenPrologueDirectives);
      }
      setSourceFile(void 0);
    }
  }
  function emitShebangIfNeeded(sourceFileOrBundle) {
    if (isSourceFile(sourceFileOrBundle)) {
      const shebang = getShebang(sourceFileOrBundle.text);
      if (shebang) {
        writeComment(shebang);
        writeLine();
        return true;
      }
    } else {
      for (const sourceFile of sourceFileOrBundle.sourceFiles) {
        if (emitShebangIfNeeded(sourceFile)) {
          return true;
        }
      }
    }
  }
  function emitNodeWithWriter(node, writer2) {
    if (!node) return;
    const savedWrite = write;
    write = writer2;
    emit(node);
    write = savedWrite;
  }
  function emitDecoratorsAndModifiers(node, modifiers, allowDecorators) {
    if (modifiers == null ? void 0 : modifiers.length) {
      if (every(modifiers, isModifier)) {
        return emitModifierList(node, modifiers);
      }
      if (every(modifiers, isDecorator)) {
        if (allowDecorators) {
          return emitDecoratorList(node, modifiers);
        }
        return node.pos;
      }
      onBeforeEmitNodeArray == null ? void 0 : onBeforeEmitNodeArray(modifiers);
      let lastMode;
      let mode;
      let start = 0;
      let pos = 0;
      let lastModifier;
      while (start < modifiers.length) {
        while (pos < modifiers.length) {
          lastModifier = modifiers[pos];
          mode = isDecorator(lastModifier) ? "decorators" : "modifiers";
          if (lastMode === void 0) {
            lastMode = mode;
          } else if (mode !== lastMode) {
            break;
          }
          pos++;
        }
        const textRange = { pos: -1, end: -1 };
        if (start === 0) textRange.pos = modifiers.pos;
        if (pos === modifiers.length - 1) textRange.end = modifiers.end;
        if (lastMode === "modifiers" || allowDecorators) {
          emitNodeListItems(
            emit,
            node,
            modifiers,
            lastMode === "modifiers" ? 2359808 /* Modifiers */ : 2146305 /* Decorators */,
            /*parenthesizerRule*/
            void 0,
            start,
            pos - start,
            /*hasTrailingComma*/
            false,
            textRange
          );
        }
        start = pos;
        lastMode = mode;
        pos++;
      }
      onAfterEmitNodeArray == null ? void 0 : onAfterEmitNodeArray(modifiers);
      if (lastModifier && !positionIsSynthesized(lastModifier.end)) {
        return lastModifier.end;
      }
    }
    return node.pos;
  }
  function emitModifierList(node, modifiers) {
    emitList(node, modifiers, 2359808 /* Modifiers */);
    const lastModifier = lastOrUndefined(modifiers);
    return lastModifier && !positionIsSynthesized(lastModifier.end) ? lastModifier.end : node.pos;
  }
  function emitTypeAnnotation(node) {
    if (node) {
      writePunctuation(":");
      writeSpace();
      emit(node);
    }
  }
  function emitInitializer(node, equalCommentStartPos, container, parenthesizerRule) {
    if (node) {
      writeSpace();
      emitTokenWithComment(64 /* EqualsToken */, equalCommentStartPos, writeOperator, container);
      writeSpace();
      emitExpression(node, parenthesizerRule);
    }
  }
  function emitNodeWithPrefix(prefix, prefixWriter, node, emit2) {
    if (node) {
      prefixWriter(prefix);
      emit2(node);
    }
  }
  function emitWithLeadingSpace(node) {
    if (node) {
      writeSpace();
      emit(node);
    }
  }
  function emitExpressionWithLeadingSpace(node, parenthesizerRule) {
    if (node) {
      writeSpace();
      emitExpression(node, parenthesizerRule);
    }
  }
  function emitWithTrailingSpace(node) {
    if (node) {
      emit(node);
      writeSpace();
    }
  }
  function emitEmbeddedStatement(parent, node) {
    if (isBlock(node) || getEmitFlags(parent) & 1 /* SingleLine */ || preserveSourceNewlines && !getLeadingLineTerminatorCount(parent, node, 0 /* None */)) {
      writeSpace();
      emit(node);
    } else {
      writeLine();
      increaseIndent();
      if (isEmptyStatement(node)) {
        pipelineEmit(5 /* EmbeddedStatement */, node);
      } else {
        emit(node);
      }
      decreaseIndent();
    }
  }
  function emitDecoratorList(parentNode, decorators) {
    emitList(parentNode, decorators, 2146305 /* Decorators */);
    const lastDecorator = lastOrUndefined(decorators);
    return lastDecorator && !positionIsSynthesized(lastDecorator.end) ? lastDecorator.end : parentNode.pos;
  }
  function emitTypeArguments(parentNode, typeArguments) {
    emitList(parentNode, typeArguments, 53776 /* TypeArguments */, typeArgumentParenthesizerRuleSelector);
  }
  function emitTypeParameters(parentNode, typeParameters) {
    if (isFunctionLike(parentNode) && parentNode.typeArguments) {
      return emitTypeArguments(parentNode, parentNode.typeArguments);
    }
    emitList(parentNode, typeParameters, 53776 /* TypeParameters */);
  }
  function emitParameters(parentNode, parameters) {
    emitList(parentNode, parameters, 2576 /* Parameters */);
  }
  function canEmitSimpleArrowHead(parentNode, parameters) {
    const parameter = singleOrUndefined(parameters);
    return parameter && parameter.pos === parentNode.pos && isArrowFunction(parentNode) && !parentNode.type && !some(parentNode.modifiers) && !some(parentNode.typeParameters) && !some(parameter.modifiers) && !parameter.dotDotDotToken && !parameter.questionToken && !parameter.type && !parameter.initializer && isIdentifier(parameter.name);
  }
  function emitParametersForArrow(parentNode, parameters) {
    if (canEmitSimpleArrowHead(parentNode, parameters)) {
      emitList(parentNode, parameters, 2576 /* Parameters */ & ~2048 /* Parenthesis */);
    } else {
      emitParameters(parentNode, parameters);
    }
  }
  function emitParametersForIndexSignature(parentNode, parameters) {
    emitList(parentNode, parameters, 8848 /* IndexSignatureParameters */);
  }
  function writeDelimiter(format) {
    switch (format & 60 /* DelimitersMask */) {
      case 0 /* None */:
        break;
      case 16 /* CommaDelimited */:
        writePunctuation(",");
        break;
      case 4 /* BarDelimited */:
        writeSpace();
        writePunctuation("|");
        break;
      case 32 /* AsteriskDelimited */:
        writeSpace();
        writePunctuation("*");
        writeSpace();
        break;
      case 8 /* AmpersandDelimited */:
        writeSpace();
        writePunctuation("&");
        break;
    }
  }
  function emitList(parentNode, children, format, parenthesizerRule, start, count) {
    emitNodeList(
      emit,
      parentNode,
      children,
      format | (parentNode && getEmitFlags(parentNode) & 2 /* MultiLine */ ? 65536 /* PreferNewLine */ : 0),
      parenthesizerRule,
      start,
      count
    );
  }
  function emitExpressionList(parentNode, children, format, parenthesizerRule, start, count) {
    emitNodeList(emitExpression, parentNode, children, format, parenthesizerRule, start, count);
  }
  function emitNodeList(emit2, parentNode, children, format, parenthesizerRule, start = 0, count = children ? children.length - start : 0) {
    const isUndefined = children === void 0;
    if (isUndefined && format & 16384 /* OptionalIfUndefined */) {
      return;
    }
    const isEmpty = children === void 0 || start >= children.length || count === 0;
    if (isEmpty && format & 32768 /* OptionalIfEmpty */) {
      onBeforeEmitNodeArray == null ? void 0 : onBeforeEmitNodeArray(children);
      onAfterEmitNodeArray == null ? void 0 : onAfterEmitNodeArray(children);
      return;
    }
    if (format & 15360 /* BracketsMask */) {
      writePunctuation(getOpeningBracket(format));
      if (isEmpty && children) {
        emitTrailingCommentsOfPosition(
          children.pos,
          /*prefixSpace*/
          true
        );
      }
    }
    onBeforeEmitNodeArray == null ? void 0 : onBeforeEmitNodeArray(children);
    if (isEmpty) {
      if (format & 1 /* MultiLine */ && !(preserveSourceNewlines && (!parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile)))) {
        writeLine();
      } else if (format & 256 /* SpaceBetweenBraces */ && !(format & 524288 /* NoSpaceIfEmpty */)) {
        writeSpace();
      }
    } else {
      emitNodeListItems(emit2, parentNode, children, format, parenthesizerRule, start, count, children.hasTrailingComma, children);
    }
    onAfterEmitNodeArray == null ? void 0 : onAfterEmitNodeArray(children);
    if (format & 15360 /* BracketsMask */) {
      if (isEmpty && children) {
        emitLeadingCommentsOfPosition(children.end);
      }
      writePunctuation(getClosingBracket(format));
    }
  }
  function emitNodeListItems(emit2, parentNode, children, format, parenthesizerRule, start, count, hasTrailingComma, childrenTextRange) {
    const mayEmitInterveningComments = (format & 262144 /* NoInterveningComments */) === 0;
    let shouldEmitInterveningComments = mayEmitInterveningComments;
    const leadingLineTerminatorCount = getLeadingLineTerminatorCount(parentNode, children[start], format);
    if (leadingLineTerminatorCount) {
      writeLine(leadingLineTerminatorCount);
      shouldEmitInterveningComments = false;
    } else if (format & 256 /* SpaceBetweenBraces */) {
      writeSpace();
    }
    if (format & 128 /* Indented */) {
      increaseIndent();
    }
    const emitListItem = getEmitListItem(emit2, parenthesizerRule);
    let previousSibling;
    let shouldDecreaseIndentAfterEmit = false;
    for (let i = 0; i < count; i++) {
      const child = children[start + i];
      if (format & 32 /* AsteriskDelimited */) {
        writeLine();
        writeDelimiter(format);
      } else if (previousSibling) {
        if (format & 60 /* DelimitersMask */ && previousSibling.end !== (parentNode ? parentNode.end : -1)) {
          const previousSiblingEmitFlags = getEmitFlags(previousSibling);
          if (!(previousSiblingEmitFlags & 2048 /* NoTrailingComments */)) {
            emitLeadingCommentsOfPosition(previousSibling.end);
          }
        }
        writeDelimiter(format);
        const separatingLineTerminatorCount = getSeparatingLineTerminatorCount(previousSibling, child, format);
        if (separatingLineTerminatorCount > 0) {
          if ((format & (3 /* LinesMask */ | 128 /* Indented */)) === 0 /* SingleLine */) {
            increaseIndent();
            shouldDecreaseIndentAfterEmit = true;
          }
          if (shouldEmitInterveningComments && format & 60 /* DelimitersMask */ && !positionIsSynthesized(child.pos)) {
            const commentRange = getCommentRange(child);
            emitTrailingCommentsOfPosition(
              commentRange.pos,
              /*prefixSpace*/
              !!(format & 512 /* SpaceBetweenSiblings */),
              /*forceNoNewline*/
              true
            );
          }
          writeLine(separatingLineTerminatorCount);
          shouldEmitInterveningComments = false;
        } else if (previousSibling && format & 512 /* SpaceBetweenSiblings */) {
          writeSpace();
        }
      }
      if (shouldEmitInterveningComments) {
        const commentRange = getCommentRange(child);
        emitTrailingCommentsOfPosition(commentRange.pos);
      } else {
        shouldEmitInterveningComments = mayEmitInterveningComments;
      }
      nextListElementPos = child.pos;
      emitListItem(child, emit2, parenthesizerRule, i);
      if (shouldDecreaseIndentAfterEmit) {
        decreaseIndent();
        shouldDecreaseIndentAfterEmit = false;
      }
      previousSibling = child;
    }
    const emitFlags = previousSibling ? getEmitFlags(previousSibling) : 0;
    const skipTrailingComments = commentsDisabled || !!(emitFlags & 2048 /* NoTrailingComments */);
    const emitTrailingComma = hasTrailingComma && format & 64 /* AllowTrailingComma */ && format & 16 /* CommaDelimited */;
    if (emitTrailingComma) {
      if (previousSibling && !skipTrailingComments) {
        emitTokenWithComment(28 /* CommaToken */, previousSibling.end, writePunctuation, previousSibling);
      } else {
        writePunctuation(",");
      }
    }
    if (previousSibling && (parentNode ? parentNode.end : -1) !== previousSibling.end && format & 60 /* DelimitersMask */ && !skipTrailingComments) {
      emitLeadingCommentsOfPosition(emitTrailingComma && (childrenTextRange == null ? void 0 : childrenTextRange.end) ? childrenTextRange.end : previousSibling.end);
    }
    if (format & 128 /* Indented */) {
      decreaseIndent();
    }
    const closingLineTerminatorCount = getClosingLineTerminatorCount(parentNode, children[start + count - 1], format, childrenTextRange);
    if (closingLineTerminatorCount) {
      writeLine(closingLineTerminatorCount);
    } else if (format & (2097152 /* SpaceAfterList */ | 256 /* SpaceBetweenBraces */)) {
      writeSpace();
    }
  }
  function writeLiteral(s) {
    writer.writeLiteral(s);
  }
  function writeStringLiteral(s) {
    writer.writeStringLiteral(s);
  }
  function writeBase(s) {
    writer.write(s);
  }
  function writeSymbol(s, sym) {
    writer.writeSymbol(s, sym);
  }
  function writePunctuation(s) {
    writer.writePunctuation(s);
  }
  function writeTrailingSemicolon() {
    writer.writeTrailingSemicolon(";");
  }
  function writeKeyword(s) {
    writer.writeKeyword(s);
  }
  function writeOperator(s) {
    writer.writeOperator(s);
  }
  function writeParameter(s) {
    writer.writeParameter(s);
  }
  function writeComment(s) {
    writer.writeComment(s);
  }
  function writeSpace() {
    writer.writeSpace(" ");
  }
  function writeProperty(s) {
    writer.writeProperty(s);
  }
  function nonEscapingWrite(s) {
    if (writer.nonEscapingWrite) {
      writer.nonEscapingWrite(s);
    } else {
      writer.write(s);
    }
  }
  function writeLine(count = 1) {
    for (let i = 0; i < count; i++) {
      writer.writeLine(i > 0);
    }
  }
  function increaseIndent() {
    writer.increaseIndent();
  }
  function decreaseIndent() {
    writer.decreaseIndent();
  }
  function writeToken(token, pos, writer2, contextNode) {
    return !sourceMapsDisabled ? emitTokenWithSourceMap(contextNode, token, writer2, pos, writeTokenText) : writeTokenText(token, writer2, pos);
  }
  function writeTokenNode(node, writer2) {
    if (onBeforeEmitToken) {
      onBeforeEmitToken(node);
    }
    writer2(tokenToString(node.kind));
    if (onAfterEmitToken) {
      onAfterEmitToken(node);
    }
  }
  function writeTokenText(token, writer2, pos) {
    const tokenString = tokenToString(token);
    writer2(tokenString);
    return pos < 0 ? pos : pos + tokenString.length;
  }
  function writeLineOrSpace(parentNode, prevChildNode, nextChildNode) {
    if (getEmitFlags(parentNode) & 1 /* SingleLine */) {
      writeSpace();
    } else if (preserveSourceNewlines) {
      const lines = getLinesBetweenNodes(parentNode, prevChildNode, nextChildNode);
      if (lines) {
        writeLine(lines);
      } else {
        writeSpace();
      }
    } else {
      writeLine();
    }
  }
  function writeLines(text) {
    const lines = text.split(/\r\n?|\n/g);
    const indentation = guessIndentation(lines);
    for (const lineText of lines) {
      const line = indentation ? lineText.slice(indentation) : lineText;
      if (line.length) {
        writeLine();
        write(line);
      }
    }
  }
  function writeLinesAndIndent(lineCount, writeSpaceIfNotIndenting) {
    if (lineCount) {
      increaseIndent();
      writeLine(lineCount);
    } else if (writeSpaceIfNotIndenting) {
      writeSpace();
    }
  }
  function decreaseIndentIf(value1, value2) {
    if (value1) {
      decreaseIndent();
    }
    if (value2) {
      decreaseIndent();
    }
  }
  function getLeadingLineTerminatorCount(parentNode, firstChild, format) {
    if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
      if (format & 65536 /* PreferNewLine */) {
        return 1;
      }
      if (firstChild === void 0) {
        return !parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
      }
      if (firstChild.pos === nextListElementPos) {
        return 0;
      }
      if (firstChild.kind === 12 /* JsxText */) {
        return 0;
      }
      if (currentSourceFile && parentNode && !positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(firstChild) && (!firstChild.parent || getOriginalNode(firstChild.parent) === getOriginalNode(parentNode))) {
        if (preserveSourceNewlines) {
          return getEffectiveLines(
            (includeComments) => getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(
              firstChild.pos,
              parentNode.pos,
              currentSourceFile,
              includeComments
            )
          );
        }
        return rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile) ? 0 : 1;
      }
      if (synthesizedNodeStartsOnNewLine(firstChild, format)) {
        return 1;
      }
    }
    return format & 1 /* MultiLine */ ? 1 : 0;
  }
  function getSeparatingLineTerminatorCount(previousNode, nextNode, format) {
    if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
      if (previousNode === void 0 || nextNode === void 0) {
        return 0;
      }
      if (nextNode.kind === 12 /* JsxText */) {
        return 0;
      } else if (currentSourceFile && !nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode)) {
        if (preserveSourceNewlines && siblingNodePositionsAreComparable(previousNode, nextNode)) {
          return getEffectiveLines(
            (includeComments) => getLinesBetweenRangeEndAndRangeStart(
              previousNode,
              nextNode,
              currentSourceFile,
              includeComments
            )
          );
        } else if (!preserveSourceNewlines && originalNodesHaveSameParent(previousNode, nextNode)) {
          return rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile) ? 0 : 1;
        }
        return format & 65536 /* PreferNewLine */ ? 1 : 0;
      } else if (synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format)) {
        return 1;
      }
    } else if (getStartsOnNewLine(nextNode)) {
      return 1;
    }
    return format & 1 /* MultiLine */ ? 1 : 0;
  }
  function getClosingLineTerminatorCount(parentNode, lastChild, format, childrenTextRange) {
    if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
      if (format & 65536 /* PreferNewLine */) {
        return 1;
      }
      if (lastChild === void 0) {
        return !parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
      }
      if (currentSourceFile && parentNode && !positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(lastChild) && (!lastChild.parent || lastChild.parent === parentNode)) {
        if (preserveSourceNewlines) {
          const end = childrenTextRange && !positionIsSynthesized(childrenTextRange.end) ? childrenTextRange.end : lastChild.end;
          return getEffectiveLines(
            (includeComments) => getLinesBetweenPositionAndNextNonWhitespaceCharacter(
              end,
              parentNode.end,
              currentSourceFile,
              includeComments
            )
          );
        }
        return rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile) ? 0 : 1;
      }
      if (synthesizedNodeStartsOnNewLine(lastChild, format)) {
        return 1;
      }
    }
    if (format & 1 /* MultiLine */ && !(format & 131072 /* NoTrailingNewLine */)) {
      return 1;
    }
    return 0;
  }
  function getEffectiveLines(getLineDifference) {
    Debug.assert(!!preserveSourceNewlines);
    const lines = getLineDifference(
      /*includeComments*/
      true
    );
    if (lines === 0) {
      return getLineDifference(
        /*includeComments*/
        false
      );
    }
    return lines;
  }
  function writeLineSeparatorsAndIndentBefore(node, parent) {
    const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, node, 0 /* None */);
    if (leadingNewlines) {
      writeLinesAndIndent(
        leadingNewlines,
        /*writeSpaceIfNotIndenting*/
        false
      );
    }
    return !!leadingNewlines;
  }
  function writeLineSeparatorsAfter(node, parent) {
    const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(
      parent,
      node,
      0 /* None */,
      /*childrenTextRange*/
      void 0
    );
    if (trailingNewlines) {
      writeLine(trailingNewlines);
    }
  }
  function synthesizedNodeStartsOnNewLine(node, format) {
    if (nodeIsSynthesized(node)) {
      const startsOnNewLine = getStartsOnNewLine(node);
      if (startsOnNewLine === void 0) {
        return (format & 65536 /* PreferNewLine */) !== 0;
      }
      return startsOnNewLine;
    }
    return (format & 65536 /* PreferNewLine */) !== 0;
  }
  function getLinesBetweenNodes(parent, node1, node2) {
    if (getEmitFlags(parent) & 262144 /* NoIndentation */) {
      return 0;
    }
    parent = skipSynthesizedParentheses(parent);
    node1 = skipSynthesizedParentheses(node1);
    node2 = skipSynthesizedParentheses(node2);
    if (getStartsOnNewLine(node2)) {
      return 1;
    }
    if (currentSourceFile && !nodeIsSynthesized(parent) && !nodeIsSynthesized(node1) && !nodeIsSynthesized(node2)) {
      if (preserveSourceNewlines) {
        return getEffectiveLines(
          (includeComments) => getLinesBetweenRangeEndAndRangeStart(
            node1,
            node2,
            currentSourceFile,
            includeComments
          )
        );
      }
      return rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile) ? 0 : 1;
    }
    return 0;
  }
  function isEmptyBlock(block) {
    return block.statements.length === 0 && (!currentSourceFile || rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile));
  }
  function skipSynthesizedParentheses(node) {
    while (node.kind === 217 /* ParenthesizedExpression */ && nodeIsSynthesized(node)) {
      node = node.expression;
    }
    return node;
  }
  function getTextOfNode2(node, includeTrivia) {
    if (isGeneratedIdentifier(node) || isGeneratedPrivateIdentifier(node)) {
      return generateName(node);
    }
    if (isStringLiteral(node) && node.textSourceNode) {
      return getTextOfNode2(node.textSourceNode, includeTrivia);
    }
    const sourceFile = currentSourceFile;
    const canUseSourceFile = !!sourceFile && !!node.parent && !nodeIsSynthesized(node);
    if (isMemberName(node)) {
      if (!canUseSourceFile || getSourceFileOfNode(node) !== getOriginalNode(sourceFile)) {
        return idText(node);
      }
    } else if (isJsxNamespacedName(node)) {
      if (!canUseSourceFile || getSourceFileOfNode(node) !== getOriginalNode(sourceFile)) {
        return getTextOfJsxNamespacedName(node);
      }
    } else {
      Debug.assertNode(node, isLiteralExpression);
      if (!canUseSourceFile) {
        return node.text;
      }
    }
    return getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia);
  }
  function getLiteralTextOfNode(node, neverAsciiEscape, jsxAttributeEscape) {
    if (node.kind === 11 /* StringLiteral */ && node.textSourceNode) {
      const textSourceNode = node.textSourceNode;
      if (isIdentifier(textSourceNode) || isPrivateIdentifier(textSourceNode) || isNumericLiteral(textSourceNode) || isJsxNamespacedName(textSourceNode)) {
        const text = isNumericLiteral(textSourceNode) ? textSourceNode.text : getTextOfNode2(textSourceNode);
        return jsxAttributeEscape ? `"${escapeJsxAttributeString(text)}"` : neverAsciiEscape || getEmitFlags(node) & 16777216 /* NoAsciiEscaping */ ? `"${escapeString(text)}"` : `"${escapeNonAsciiString(text)}"`;
      } else {
        return getLiteralTextOfNode(textSourceNode, neverAsciiEscape, jsxAttributeEscape);
      }
    }
    const flags = (neverAsciiEscape ? 1 /* NeverAsciiEscape */ : 0) | (jsxAttributeEscape ? 2 /* JsxAttributeEscape */ : 0) | (printerOptions.terminateUnterminatedLiterals ? 4 /* TerminateUnterminatedLiterals */ : 0) | (printerOptions.target && printerOptions.target >= 8 /* ES2021 */ ? 8 /* AllowNumericSeparator */ : 0);
    return getLiteralText(node, currentSourceFile, flags);
  }
  function pushNameGenerationScope(node) {
    privateNameTempFlagsStack.push(privateNameTempFlags);
    privateNameTempFlags = 0 /* Auto */;
    reservedPrivateNamesStack.push(reservedPrivateNames);
    if (node && getEmitFlags(node) & 1048576 /* ReuseTempVariableScope */) {
      return;
    }
    tempFlagsStack.push(tempFlags);
    tempFlags = 0 /* Auto */;
    formattedNameTempFlagsStack.push(formattedNameTempFlags);
    formattedNameTempFlags = void 0;
    reservedNamesStack.push(reservedNames);
  }
  function popNameGenerationScope(node) {
    privateNameTempFlags = privateNameTempFlagsStack.pop();
    reservedPrivateNames = reservedPrivateNamesStack.pop();
    if (node && getEmitFlags(node) & 1048576 /* ReuseTempVariableScope */) {
      return;
    }
    tempFlags = tempFlagsStack.pop();
    formattedNameTempFlags = formattedNameTempFlagsStack.pop();
    reservedNames = reservedNamesStack.pop();
  }
  function reserveNameInNestedScopes(name) {
    if (!reservedNames || reservedNames === lastOrUndefined(reservedNamesStack)) {
      reservedNames = /* @__PURE__ */ new Set();
    }
    reservedNames.add(name);
  }
  function reservePrivateNameInNestedScopes(name) {
    if (!reservedPrivateNames || reservedPrivateNames === lastOrUndefined(reservedPrivateNamesStack)) {
      reservedPrivateNames = /* @__PURE__ */ new Set();
    }
    reservedPrivateNames.add(name);
  }
  function generateNames(node) {
    if (!node) return;
    switch (node.kind) {
      case 241 /* Block */:
        forEach(node.statements, generateNames);
        break;
      case 256 /* LabeledStatement */:
      case 254 /* WithStatement */:
      case 246 /* DoStatement */:
      case 247 /* WhileStatement */:
        generateNames(node.statement);
        break;
      case 245 /* IfStatement */:
        generateNames(node.thenStatement);
        generateNames(node.elseStatement);
        break;
      case 248 /* ForStatement */:
      case 250 /* ForOfStatement */:
      case 249 /* ForInStatement */:
        generateNames(node.initializer);
        generateNames(node.statement);
        break;
      case 255 /* SwitchStatement */:
        generateNames(node.caseBlock);
        break;
      case 269 /* CaseBlock */:
        forEach(node.clauses, generateNames);
        break;
      case 296 /* CaseClause */:
      case 297 /* DefaultClause */:
        forEach(node.statements, generateNames);
        break;
      case 258 /* TryStatement */:
        generateNames(node.tryBlock);
        generateNames(node.catchClause);
        generateNames(node.finallyBlock);
        break;
      case 299 /* CatchClause */:
        generateNames(node.variableDeclaration);
        generateNames(node.block);
        break;
      case 243 /* VariableStatement */:
        generateNames(node.declarationList);
        break;
      case 261 /* VariableDeclarationList */:
        forEach(node.declarations, generateNames);
        break;
      case 260 /* VariableDeclaration */:
      case 169 /* Parameter */:
      case 208 /* BindingElement */:
      case 263 /* ClassDeclaration */:
        generateNameIfNeeded(node.name);
        break;
      case 262 /* FunctionDeclaration */:
        generateNameIfNeeded(node.name);
        if (getEmitFlags(node) & 1048576 /* ReuseTempVariableScope */) {
          forEach(node.parameters, generateNames);
          generateNames(node.body);
        }
        break;
      case 206 /* ObjectBindingPattern */:
      case 207 /* ArrayBindingPattern */:
        forEach(node.elements, generateNames);
        break;
      case 272 /* ImportDeclaration */:
        generateNames(node.importClause);
        break;
      case 273 /* ImportClause */:
        generateNameIfNeeded(node.name);
        generateNames(node.namedBindings);
        break;
      case 274 /* NamespaceImport */:
        generateNameIfNeeded(node.name);
        break;
      case 280 /* NamespaceExport */:
        generateNameIfNeeded(node.name);
        break;
      case 275 /* NamedImports */:
        forEach(node.elements, generateNames);
        break;
      case 276 /* ImportSpecifier */:
        generateNameIfNeeded(node.propertyName || node.name);
        break;
    }
  }
  function generateMemberNames(node) {
    if (!node) return;
    switch (node.kind) {
      case 303 /* PropertyAssignment */:
      case 304 /* ShorthandPropertyAssignment */:
      case 172 /* PropertyDeclaration */:
      case 171 /* PropertySignature */:
      case 174 /* MethodDeclaration */:
      case 173 /* MethodSignature */:
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
        generateNameIfNeeded(node.name);
        break;
    }
  }
  function generateNameIfNeeded(name) {
    if (name) {
      if (isGeneratedIdentifier(name) || isGeneratedPrivateIdentifier(name)) {
        generateName(name);
      } else if (isBindingPattern(name)) {
        generateNames(name);
      }
    }
  }
  function generateName(name) {
    const autoGenerate = name.emitNode.autoGenerate;
    if ((autoGenerate.flags & 7 /* KindMask */) === 4 /* Node */) {
      return generateNameCached(getNodeForGeneratedName(name), isPrivateIdentifier(name), autoGenerate.flags, autoGenerate.prefix, autoGenerate.suffix);
    } else {
      const autoGenerateId = autoGenerate.id;
      return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
    }
  }
  function generateNameCached(node, privateName, flags, prefix, suffix) {
    const nodeId = getNodeId(node);
    const cache = privateName ? nodeIdToGeneratedPrivateName : nodeIdToGeneratedName;
    return cache[nodeId] || (cache[nodeId] = generateNameForNode(node, privateName, flags ?? 0 /* None */, formatGeneratedNamePart(prefix, generateName), formatGeneratedNamePart(suffix)));
  }
  function isUniqueName(name, privateName) {
    return isFileLevelUniqueNameInCurrentFile(name, privateName) && !isReservedName(name, privateName) && !generatedNames.has(name);
  }
  function isReservedName(name, privateName) {
    let set;
    let stack;
    if (privateName) {
      set = reservedPrivateNames;
      stack = reservedPrivateNamesStack;
    } else {
      set = reservedNames;
      stack = reservedNamesStack;
    }
    if (set == null ? void 0 : set.has(name)) {
      return true;
    }
    for (let i = stack.length - 1; i >= 0; i--) {
      if (set === stack[i]) {
        continue;
      }
      set = stack[i];
      if (set == null ? void 0 : set.has(name)) {
        return true;
      }
    }
    return false;
  }
  function isFileLevelUniqueNameInCurrentFile(name, _isPrivate) {
    return currentSourceFile ? isFileLevelUniqueName(currentSourceFile, name, hasGlobalName) : true;
  }
  function isUniqueLocalName(name, container) {
    for (let node = container; node && isNodeDescendantOf(node, container); node = node.nextContainer) {
      if (canHaveLocals(node) && node.locals) {
        const local = node.locals.get(escapeLeadingUnderscores(name));
        if (local && local.flags & (111551 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */)) {
          return false;
        }
      }
    }
    return true;
  }
  function getTempFlags(formattedNameKey) {
    switch (formattedNameKey) {
      case "":
        return tempFlags;
      case "#":
        return privateNameTempFlags;
      default:
        return (formattedNameTempFlags == null ? void 0 : formattedNameTempFlags.get(formattedNameKey)) ?? 0 /* Auto */;
    }
  }
  function setTempFlags(formattedNameKey, flags) {
    switch (formattedNameKey) {
      case "":
        tempFlags = flags;
        break;
      case "#":
        privateNameTempFlags = flags;
        break;
      default:
        formattedNameTempFlags ?? (formattedNameTempFlags = /* @__PURE__ */ new Map());
        formattedNameTempFlags.set(formattedNameKey, flags);
        break;
    }
  }
  function makeTempVariableName(flags, reservedInNestedScopes, privateName, prefix, suffix) {
    if (prefix.length > 0 && prefix.charCodeAt(0) === 35 /* hash */) {
      prefix = prefix.slice(1);
    }
    const key = formatGeneratedName(privateName, prefix, "", suffix);
    let tempFlags2 = getTempFlags(key);
    if (flags && !(tempFlags2 & flags)) {
      const name = flags === 268435456 /* _i */ ? "_i" : "_n";
      const fullName = formatGeneratedName(privateName, prefix, name, suffix);
      if (isUniqueName(fullName, privateName)) {
        tempFlags2 |= flags;
        if (privateName) {
          reservePrivateNameInNestedScopes(fullName);
        } else if (reservedInNestedScopes) {
          reserveNameInNestedScopes(fullName);
        }
        setTempFlags(key, tempFlags2);
        return fullName;
      }
    }
    while (true) {
      const count = tempFlags2 & 268435455 /* CountMask */;
      tempFlags2++;
      if (count !== 8 && count !== 13) {
        const name = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26);
        const fullName = formatGeneratedName(privateName, prefix, name, suffix);
        if (isUniqueName(fullName, privateName)) {
          if (privateName) {
            reservePrivateNameInNestedScopes(fullName);
          } else if (reservedInNestedScopes) {
            reserveNameInNestedScopes(fullName);
          }
          setTempFlags(key, tempFlags2);
          return fullName;
        }
      }
    }
  }
  function makeUniqueName(baseName, checkFn = isUniqueName, optimistic, scoped, privateName, prefix, suffix) {
    if (baseName.length > 0 && baseName.charCodeAt(0) === 35 /* hash */) {
      baseName = baseName.slice(1);
    }
    if (prefix.length > 0 && prefix.charCodeAt(0) === 35 /* hash */) {
      prefix = prefix.slice(1);
    }
    if (optimistic) {
      const fullName = formatGeneratedName(privateName, prefix, baseName, suffix);
      if (checkFn(fullName, privateName)) {
        if (privateName) {
          reservePrivateNameInNestedScopes(fullName);
        } else if (scoped) {
          reserveNameInNestedScopes(fullName);
        } else {
          generatedNames.add(fullName);
        }
        return fullName;
      }
    }
    if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
      baseName += "_";
    }
    let i = 1;
    while (true) {
      const fullName = formatGeneratedName(privateName, prefix, baseName + i, suffix);
      if (checkFn(fullName, privateName)) {
        if (privateName) {
          reservePrivateNameInNestedScopes(fullName);
        } else if (scoped) {
          reserveNameInNestedScopes(fullName);
        } else {
          generatedNames.add(fullName);
        }
        return fullName;
      }
      i++;
    }
  }
  function makeFileLevelOptimisticUniqueName(name) {
    return makeUniqueName(
      name,
      isFileLevelUniqueNameInCurrentFile,
      /*optimistic*/
      true,
      /*scoped*/
      false,
      /*privateName*/
      false,
      /*prefix*/
      "",
      /*suffix*/
      ""
    );
  }
  function generateNameForModuleOrEnum(node) {
    const name = getTextOfNode2(node.name);
    return isUniqueLocalName(name, tryCast(node, canHaveLocals)) ? name : makeUniqueName(
      name,
      isUniqueName,
      /*optimistic*/
      false,
      /*scoped*/
      false,
      /*privateName*/
      false,
      /*prefix*/
      "",
      /*suffix*/
      ""
    );
  }
  function generateNameForImportOrExportDeclaration(node) {
    const expr = getExternalModuleName(node);
    const baseName = isStringLiteral(expr) ? makeIdentifierFromModuleName(expr.text) : "module";
    return makeUniqueName(
      baseName,
      isUniqueName,
      /*optimistic*/
      false,
      /*scoped*/
      false,
      /*privateName*/
      false,
      /*prefix*/
      "",
      /*suffix*/
      ""
    );
  }
  function generateNameForExportDefault() {
    return makeUniqueName(
      "default",
      isUniqueName,
      /*optimistic*/
      false,
      /*scoped*/
      false,
      /*privateName*/
      false,
      /*prefix*/
      "",
      /*suffix*/
      ""
    );
  }
  function generateNameForClassExpression() {
    return makeUniqueName(
      "class",
      isUniqueName,
      /*optimistic*/
      false,
      /*scoped*/
      false,
      /*privateName*/
      false,
      /*prefix*/
      "",
      /*suffix*/
      ""
    );
  }
  function generateNameForMethodOrAccessor(node, privateName, prefix, suffix) {
    if (isIdentifier(node.name)) {
      return generateNameCached(node.name, privateName);
    }
    return makeTempVariableName(
      0 /* Auto */,
      /*reservedInNestedScopes*/
      false,
      privateName,
      prefix,
      suffix
    );
  }
  function generateNameForNode(node, privateName, flags, prefix, suffix) {
    switch (node.kind) {
      case 80 /* Identifier */:
      case 81 /* PrivateIdentifier */:
        return makeUniqueName(
          getTextOfNode2(node),
          isUniqueName,
          !!(flags & 16 /* Optimistic */),
          !!(flags & 8 /* ReservedInNestedScopes */),
          privateName,
          prefix,
          suffix
        );
      case 267 /* ModuleDeclaration */:
      case 266 /* EnumDeclaration */:
        Debug.assert(!prefix && !suffix && !privateName);
        return generateNameForModuleOrEnum(node);
      case 272 /* ImportDeclaration */:
      case 278 /* ExportDeclaration */:
        Debug.assert(!prefix && !suffix && !privateName);
        return generateNameForImportOrExportDeclaration(node);
      case 262 /* FunctionDeclaration */:
      case 263 /* ClassDeclaration */: {
        Debug.assert(!prefix && !suffix && !privateName);
        const name = node.name;
        if (name && !isGeneratedIdentifier(name)) {
          return generateNameForNode(
            name,
            /*privateName*/
            false,
            flags,
            prefix,
            suffix
          );
        }
        return generateNameForExportDefault();
      }
      case 277 /* ExportAssignment */:
        Debug.assert(!prefix && !suffix && !privateName);
        return generateNameForExportDefault();
      case 231 /* ClassExpression */:
        Debug.assert(!prefix && !suffix && !privateName);
        return generateNameForClassExpression();
      case 174 /* MethodDeclaration */:
      case 177 /* GetAccessor */:
      case 178 /* SetAccessor */:
        return generateNameForMethodOrAccessor(node, privateName, prefix, suffix);
      case 167 /* ComputedPropertyName */:
        return makeTempVariableName(
          0 /* Auto */,
          /*reservedInNestedScopes*/
          true,
          privateName,
          prefix,
          suffix
        );
      default:
        return makeTempVariableName(
          0 /* Auto */,
          /*reservedInNestedScopes*/
          false,
          privateName,
          prefix,
          suffix
        );
    }
  }
  function makeName(name) {
    const autoGenerate = name.emitNode.autoGenerate;
    const prefix = formatGeneratedNamePart(autoGenerate.prefix, generateName);
    const suffix = formatGeneratedNamePart(autoGenerate.suffix);
    switch (autoGenerate.flags & 7 /* KindMask */) {
      case 1 /* Auto */:
        return makeTempVariableName(0 /* Auto */, !!(autoGenerate.flags & 8 /* ReservedInNestedScopes */), isPrivateIdentifier(name), prefix, suffix);
      case 2 /* Loop */:
        Debug.assertNode(name, isIdentifier);
        return makeTempVariableName(
          268435456 /* _i */,
          !!(autoGenerate.flags & 8 /* ReservedInNestedScopes */),
          /*privateName*/
          false,
          prefix,
          suffix
        );
      case 3 /* Unique */:
        return makeUniqueName(
          idText(name),
          autoGenerate.flags & 32 /* FileLevel */ ? isFileLevelUniqueNameInCurrentFile : isUniqueName,
          !!(autoGenerate.flags & 16 /* Optimistic */),
          !!(autoGenerate.flags & 8 /* ReservedInNestedScopes */),
          isPrivateIdentifier(name),
          prefix,
          suffix
        );
    }
    return Debug.fail(`Unsupported GeneratedIdentifierKind: ${Debug.formatEnum(
      autoGenerate.flags & 7 /* KindMask */,
      GeneratedIdentifierFlags,
      /*isFlags*/
      true
    )}.`);
  }
  function pipelineEmitWithComments(hint, node) {
    const pipelinePhase = getNextPipelinePhase(2 /* Comments */, hint, node);
    const savedContainerPos = containerPos;
    const savedContainerEnd = containerEnd;
    const savedDeclarationListContainerEnd = declarationListContainerEnd;
    emitCommentsBeforeNode(node);
    pipelinePhase(hint, node);
    emitCommentsAfterNode(node, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd);
  }
  function emitCommentsBeforeNode(node) {
    const emitFlags = getEmitFlags(node);
    const commentRange = getCommentRange(node);
    emitLeadingCommentsOfNode(node, emitFlags, commentRange.pos, commentRange.end);
    if (emitFlags & 4096 /* NoNestedComments */) {
      commentsDisabled = true;
    }
  }
  function emitCommentsAfterNode(node, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd) {
    const emitFlags = getEmitFlags(node);
    const commentRange = getCommentRange(node);
    if (emitFlags & 4096 /* NoNestedComments */) {
      commentsDisabled = false;
    }
    emitTrailingCommentsOfNode(node, emitFlags, commentRange.pos, commentRange.end, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd);
    const typeNode = getTypeNode(node);
    if (typeNode) {
      emitTrailingCommentsOfNode(node, emitFlags, typeNode.pos, typeNode.end, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd);
    }
  }
  function emitLeadingCommentsOfNode(node, emitFlags, pos, end) {
    enterComment();
    hasWrittenComment = false;
    const skipLeadingComments = pos < 0 || (emitFlags & 1024 /* NoLeadingComments */) !== 0 || node.kind === 12 /* JsxText */;
    const skipTrailingComments = end < 0 || (emitFlags & 2048 /* NoTrailingComments */) !== 0 || node.kind === 12 /* JsxText */;
    if ((pos > 0 || end > 0) && pos !== end) {
      if (!skipLeadingComments) {
        emitLeadingComments(
          pos,
          /*isEmittedNode*/
          node.kind !== 353 /* NotEmittedStatement */
        );
      }
      if (!skipLeadingComments || pos >= 0 && (emitFlags & 1024 /* NoLeadingComments */) !== 0) {
        containerPos = pos;
      }
      if (!skipTrailingComments || end >= 0 && (emitFlags & 2048 /* NoTrailingComments */) !== 0) {
        containerEnd = end;
        if (node.kind === 261 /* VariableDeclarationList */) {
          declarationListContainerEnd = end;
        }
      }
    }
    forEach(getSyntheticLeadingComments(node), emitLeadingSynthesizedComment);
    exitComment();
  }
  function emitTrailingCommentsOfNode(node, emitFlags, pos, end, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd) {
    enterComment();
    const skipTrailingComments = end < 0 || (emitFlags & 2048 /* NoTrailingComments */) !== 0 || node.kind === 12 /* JsxText */;
    forEach(getSyntheticTrailingComments(node), emitTrailingSynthesizedComment);
    if ((pos > 0 || end > 0) && pos !== end) {
      containerPos = savedContainerPos;
      containerEnd = savedContainerEnd;
      declarationListContainerEnd = savedDeclarationListContainerEnd;
      if (!skipTrailingComments && node.kind !== 353 /* NotEmittedStatement */) {
        emitTrailingComments(end);
      }
    }
    exitComment();
  }
  function emitLeadingSynthesizedComment(comment) {
    if (comment.hasLeadingNewline || comment.kind === 2 /* SingleLineCommentTrivia */) {
      writer.writeLine();
    }
    writeSynthesizedComment(comment);
    if (comment.hasTrailingNewLine || comment.kind === 2 /* SingleLineCommentTrivia */) {
      writer.writeLine();
    } else {
      writer.writeSpace(" ");
    }
  }
  function emitTrailingSynthesizedComment(comment) {
    if (!writer.isAtStartOfLine()) {
      writer.writeSpace(" ");
    }
    writeSynthesizedComment(comment);
    if (comment.hasTrailingNewLine) {
      writer.writeLine();
    }
  }
  function writeSynthesizedComment(comment) {
    const text = formatSynthesizedComment(comment);
    const lineMap = comment.kind === 3 /* MultiLineCommentTrivia */ ? computeLineStarts(text) : void 0;
    writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
  }
  function formatSynthesizedComment(comment) {
    return comment.kind === 3 /* MultiLineCommentTrivia */ ? `/*${comment.text}*/` : `//${comment.text}`;
  }
  function emitBodyWithDetachedComments(node, detachedRange, emitCallback) {
    enterComment();
    const { pos, end } = detachedRange;
    const emitFlags = getEmitFlags(node);
    const skipLeadingComments = pos < 0 || (emitFlags & 1024 /* NoLeadingComments */) !== 0;
    const skipTrailingComments = commentsDisabled || end < 0 || (emitFlags & 2048 /* NoTrailingComments */) !== 0;
    if (!skipLeadingComments) {
      emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
    }
    exitComment();
    if (emitFlags & 4096 /* NoNestedComments */ && !commentsDisabled) {
      commentsDisabled = true;
      emitCallback(node);
      commentsDisabled = false;
    } else {
      emitCallback(node);
    }
    enterComment();
    if (!skipTrailingComments) {
      emitLeadingComments(
        detachedRange.end,
        /*isEmittedNode*/
        true
      );
      if (hasWrittenComment && !writer.isAtStartOfLine()) {
        writer.writeLine();
      }
    }
    exitComment();
  }
  function originalNodesHaveSameParent(nodeA, nodeB) {
    nodeA = getOriginalNode(nodeA);
    return nodeA.parent && nodeA.parent === getOriginalNode(nodeB).parent;
  }
  function siblingNodePositionsAreComparable(previousNode, nextNode) {
    if (nextNode.pos < previousNode.end) {
      return false;
    }
    previousNode = getOriginalNode(previousNode);
    nextNode = getOriginalNode(nextNode);
    const parent = previousNode.parent;
    if (!parent || parent !== nextNode.parent) {
      return false;
    }
    const parentNodeArray = getContainingNodeArray(previousNode);
    const prevNodeIndex = parentNodeArray == null ? void 0 : parentNodeArray.indexOf(previousNode);
    return prevNodeIndex !== void 0 && prevNodeIndex > -1 && parentNodeArray.indexOf(nextNode) === prevNodeIndex + 1;
  }
  function emitLeadingComments(pos, isEmittedNode) {
    hasWrittenComment = false;
    if (isEmittedNode) {
      if (pos === 0 && (currentSourceFile == null ? void 0 : currentSourceFile.isDeclarationFile)) {
        forEachLeadingCommentToEmit(pos, emitNonTripleSlashLeadingComment);
      } else {
        forEachLeadingCommentToEmit(pos, emitLeadingComment);
      }
    } else if (pos === 0) {
      forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment);
    }
  }
  function emitTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
    if (isTripleSlashComment(commentPos, commentEnd)) {
      emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
    }
  }
  function emitNonTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
    if (!isTripleSlashComment(commentPos, commentEnd)) {
      emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
    }
  }
  function shouldWriteComment(text, pos) {
    if (printerOptions.onlyPrintJsDocStyle) {
      return isJSDocLikeText(text, pos) || isPinnedComment(text, pos);
    }
    return true;
  }
  function emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
    if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return;
    if (!hasWrittenComment) {
      emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos);
      hasWrittenComment = true;
    }
    emitPos(commentPos);
    writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
    emitPos(commentEnd);
    if (hasTrailingNewLine) {
      writer.writeLine();
    } else if (kind === 3 /* MultiLineCommentTrivia */) {
      writer.writeSpace(" ");
    }
  }
  function emitLeadingCommentsOfPosition(pos) {
    if (commentsDisabled || pos === -1) {
      return;
    }
    emitLeadingComments(
      pos,
      /*isEmittedNode*/
      true
    );
  }
  function emitTrailingComments(pos) {
    forEachTrailingCommentToEmit(pos, emitTrailingComment);
  }
  function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) {
    if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return;
    if (!writer.isAtStartOfLine()) {
      writer.writeSpace(" ");
    }
    emitPos(commentPos);
    writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
    emitPos(commentEnd);
    if (hasTrailingNewLine) {
      writer.writeLine();
    }
  }
  function emitTrailingCommentsOfPosition(pos, prefixSpace, forceNoNewline) {
    if (commentsDisabled) {
      return;
    }
    enterComment();
    forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : forceNoNewline ? emitTrailingCommentOfPositionNoNewline : emitTrailingCommentOfPosition);
    exitComment();
  }
  function emitTrailingCommentOfPositionNoNewline(commentPos, commentEnd, kind) {
    if (!currentSourceFile) return;
    emitPos(commentPos);
    writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
    emitPos(commentEnd);
    if (kind === 2 /* SingleLineCommentTrivia */) {
      writer.writeLine();
    }
  }
  function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) {
    if (!currentSourceFile) return;
    emitPos(commentPos);
    writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
    emitPos(commentEnd);
    if (hasTrailingNewLine) {
      writer.writeLine();
    } else {
      writer.writeSpace(" ");
    }
  }
  function forEachLeadingCommentToEmit(pos, cb) {
    if (currentSourceFile && (containerPos === -1 || pos !== containerPos)) {
      if (hasDetachedComments(pos)) {
        forEachLeadingCommentWithoutDetachedComments(cb);
      } else {
        forEachLeadingCommentRange(
          currentSourceFile.text,
          pos,
          cb,
          /*state*/
          pos
        );
      }
    }
  }
  function forEachTrailingCommentToEmit(end, cb) {
    if (currentSourceFile && (containerEnd === -1 || end !== containerEnd && end !== declarationListContainerEnd)) {
      forEachTrailingCommentRange(currentSourceFile.text, end, cb);
    }
  }
  function hasDetachedComments(pos) {
    return detachedCommentsInfo !== void 0 && last(detachedCommentsInfo).nodePos === pos;
  }
  function forEachLeadingCommentWithoutDetachedComments(cb) {
    if (!currentSourceFile) return;
    const pos = last(detachedCommentsInfo).detachedCommentEndPos;
    if (detachedCommentsInfo.length - 1) {
      detachedCommentsInfo.pop();
    } else {
      detachedCommentsInfo = void 0;
    }
    forEachLeadingCommentRange(
      currentSourceFile.text,
      pos,
      cb,
      /*state*/
      pos
    );
  }
  function emitDetachedCommentsAndUpdateCommentsInfo(range) {
    const currentDetachedCommentInfo = currentSourceFile && emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
    if (currentDetachedCommentInfo) {
      if (detachedCommentsInfo) {
        detachedCommentsInfo.push(currentDetachedCommentInfo);
      } else {
        detachedCommentsInfo = [currentDetachedCommentInfo];
      }
    }
  }
  function emitComment(text, lineMap, writer2, commentPos, commentEnd, newLine2) {
    if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return;
    emitPos(commentPos);
    writeCommentRange(text, lineMap, writer2, commentPos, commentEnd, newLine2);
    emitPos(commentEnd);
  }
  function isTripleSlashComment(commentPos, commentEnd) {
    return !!currentSourceFile && isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd);
  }
  function pipelineEmitWithSourceMaps(hint, node) {
    const pipelinePhase = getNextPipelinePhase(3 /* SourceMaps */, hint, node);
    emitSourceMapsBeforeNode(node);
    pipelinePhase(hint, node);
    emitSourceMapsAfterNode(node);
  }
  function emitSourceMapsBeforeNode(node) {
    const emitFlags = getEmitFlags(node);
    const sourceMapRange = getSourceMapRange(node);
    const source = sourceMapRange.source || sourceMapSource;
    if (node.kind !== 353 /* NotEmittedStatement */ && (emitFlags & 32 /* NoLeadingSourceMap */) === 0 && sourceMapRange.pos >= 0) {
      emitSourcePos(sourceMapRange.source || sourceMapSource, skipSourceTrivia(source, sourceMapRange.pos));
    }
    if (emitFlags & 128 /* NoNestedSourceMaps */) {
      sourceMapsDisabled = true;
    }
  }
  function emitSourceMapsAfterNode(node) {
    const emitFlags = getEmitFlags(node);
    const sourceMapRange = getSourceMapRange(node);
    if (emitFlags & 128 /* NoNestedSourceMaps */) {
      sourceMapsDisabled = false;
    }
    if (node.kind !== 353 /* NotEmittedStatement */ && (emitFlags & 64 /* NoTrailingSourceMap */) === 0 && sourceMapRange.end >= 0) {
      emitSourcePos(sourceMapRange.source || sourceMapSource, sourceMapRange.end);
    }
  }
  function skipSourceTrivia(source, pos) {
    return source.skipTrivia ? source.skipTrivia(pos) : skipTrivia(source.text, pos);
  }
  function emitPos(pos) {
    if (sourceMapsDisabled || positionIsSynthesized(pos) || isJsonSourceMapSource(sourceMapSource)) {
      return;
    }
    const { line: sourceLine, character: sourceCharacter } = getLineAndCharacterOfPosition(sourceMapSource, pos);
    sourceMapGenerator.addMapping(
      writer.getLine(),
      writer.getColumn(),
      sourceMapSourceIndex,
      sourceLine,
      sourceCharacter,
      /*nameIndex*/
      void 0
    );
  }
  function emitSourcePos(source, pos) {
    if (source !== sourceMapSource) {
      const savedSourceMapSource = sourceMapSource;
      const savedSourceMapSourceIndex = sourceMapSourceIndex;
      setSourceMapSource(source);
      emitPos(pos);
      resetSourceMapSource(savedSourceMapSource, savedSourceMapSourceIndex);
    } else {
      emitPos(pos);
    }
  }
  function emitTokenWithSourceMap(node, token, writer2, tokenPos, emitCallback) {
    if (sourceMapsDisabled || node && isInJsonFile(node)) {
      return emitCallback(token, writer2, tokenPos);
    }
    const emitNode = node && node.emitNode;
    const emitFlags = emitNode && emitNode.flags || 0 /* None */;
    const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
    const source = range && range.source || sourceMapSource;
    tokenPos = skipSourceTrivia(source, range ? range.pos : tokenPos);
    if ((emitFlags & 256 /* NoTokenLeadingSourceMaps */) === 0 && tokenPos >= 0) {
      emitSourcePos(source, tokenPos);
    }
    tokenPos = emitCallback(token, writer2, tokenPos);
    if (range) tokenPos = range.end;
    if ((emitFlags & 512 /* NoTokenTrailingSourceMaps */) === 0 && tokenPos >= 0) {
      emitSourcePos(source, tokenPos);
    }
    return tokenPos;
  }
  function setSourceMapSource(source) {
    if (sourceMapsDisabled) {
      return;
    }
    sourceMapSource = source;
    if (source === mostRecentlyAddedSourceMapSource) {
      sourceMapSourceIndex = mostRecentlyAddedSourceMapSourceIndex;
      return;
    }
    if (isJsonSourceMapSource(source)) {
      return;
    }
    sourceMapSourceIndex = sourceMapGenerator.addSource(source.fileName);
    if (printerOptions.inlineSources) {
      sourceMapGenerator.setSourceContent(sourceMapSourceIndex, source.text);
    }
    mostRecentlyAddedSourceMapSource = source;
    mostRecentlyAddedSourceMapSourceIndex = sourceMapSourceIndex;
  }
  function resetSourceMapSource(source, sourceIndex) {
    sourceMapSource = source;
    sourceMapSourceIndex = sourceIndex;
  }
  function isJsonSourceMapSource(sourceFile) {
    return fileExtensionIs(sourceFile.fileName, ".json" /* Json */);
  }
}
function createBracketsMap() {
  const brackets2 = [];
  brackets2[1024 /* Braces */] = ["{", "}"];
  brackets2[2048 /* Parenthesis */] = ["(", ")"];
  brackets2[4096 /* AngleBrackets */] = ["<", ">"];
  brackets2[8192 /* SquareBrackets */] = ["[", "]"];
  return brackets2;
}
function getOpeningBracket(format) {
  return brackets[format & 15360 /* BracketsMask */][0];
}
function getClosingBracket(format) {
  return brackets[format & 15360 /* BracketsMask */][1];
}
function emitListItemNoParenthesizer(node, emit, _parenthesizerRule, _index) {
  emit(node);
}
function emitListItemWithParenthesizerRuleSelector(node, emit, parenthesizerRuleSelector, index) {
  emit(node, parenthesizerRuleSelector.select(index));
}
function emitListItemWithParenthesizerRule(node, emit, parenthesizerRule, _index) {
  emit(node, parenthesizerRule);
}
function getEmitListItem(emit, parenthesizerRule) {
  return emit.length === 1 ? emitListItemNoParenthesizer : typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector : emitListItemWithParenthesizerRule;
}

// src/compiler/watchUtilities.ts
function createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames2) {
  if (!host.getDirectories || !host.readDirectory) {
    return void 0;
  }
  const cachedReadDirectoryResult = /* @__PURE__ */ new Map();
  const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames2);
  return {
    useCaseSensitiveFileNames: useCaseSensitiveFileNames2,
    fileExists,
    readFile: (path, encoding) => host.readFile(path, encoding),
    directoryExists: host.directoryExists && directoryExists,
    getDirectories,
    readDirectory,
    createDirectory: host.createDirectory && createDirectory,
    writeFile: host.writeFile && writeFile2,
    addOrDeleteFileOrDirectory,
    addOrDeleteFile,
    clearCache,
    realpath: host.realpath && realpath
  };
  function toPath3(fileName) {
    return toPath(fileName, currentDirectory, getCanonicalFileName);
  }
  function getCachedFileSystemEntries(rootDirPath) {
    return cachedReadDirectoryResult.get(ensureTrailingDirectorySeparator(rootDirPath));
  }
  function getCachedFileSystemEntriesForBaseDir(path) {
    const entries = getCachedFileSystemEntries(getDirectoryPath(path));
    if (!entries) {
      return entries;
    }
    if (!entries.sortedAndCanonicalizedFiles) {
      entries.sortedAndCanonicalizedFiles = entries.files.map(getCanonicalFileName).sort();
      entries.sortedAndCanonicalizedDirectories = entries.directories.map(getCanonicalFileName).sort();
    }
    return entries;
  }
  function getBaseNameOfFileName(fileName) {
    return getBaseFileName(normalizePath(fileName));
  }
  function createCachedFileSystemEntries(rootDir, rootDirPath) {
    var _a;
    if (!host.realpath || ensureTrailingDirectorySeparator(toPath3(host.realpath(rootDir))) === rootDirPath) {
      const resultFromHost = {
        files: map(host.readDirectory(
          rootDir,
          /*extensions*/
          void 0,
          /*exclude*/
          void 0,
          /*include*/
          ["*.*"]
        ), getBaseNameOfFileName) || [],
        directories: host.getDirectories(rootDir) || []
      };
      cachedReadDirectoryResult.set(ensureTrailingDirectorySeparator(rootDirPath), resultFromHost);
      return resultFromHost;
    }
    if ((_a = host.directoryExists) == null ? void 0 : _a.call(host, rootDir)) {
      cachedReadDirectoryResult.set(rootDirPath, false);
      return false;
    }
    return void 0;
  }
  function tryReadDirectory(rootDir, rootDirPath) {
    rootDirPath = ensureTrailingDirectorySeparator(rootDirPath);
    const cachedResult = getCachedFileSystemEntries(rootDirPath);
    if (cachedResult) {
      return cachedResult;
    }
    try {
      return createCachedFileSystemEntries(rootDir, rootDirPath);
    } catch (_e) {
      Debug.assert(!cachedReadDirectoryResult.has(ensureTrailingDirectorySeparator(rootDirPath)));
      return void 0;
    }
  }
  function hasEntry(entries, name) {
    const index = binarySearch(entries, name, identity, compareStringsCaseSensitive);
    return index >= 0;
  }
  function writeFile2(fileName, data, writeByteOrderMark) {
    const path = toPath3(fileName);
    const result = getCachedFileSystemEntriesForBaseDir(path);
    if (result) {
      updateFilesOfFileSystemEntry(
        result,
        getBaseNameOfFileName(fileName),
        /*fileExists*/
        true
      );
    }
    return host.writeFile(fileName, data, writeByteOrderMark);
  }
  function fileExists(fileName) {
    const path = toPath3(fileName);
    const result = getCachedFileSystemEntriesForBaseDir(path);
    return result && hasEntry(result.sortedAndCanonicalizedFiles, getCanonicalFileName(getBaseNameOfFileName(fileName))) || host.fileExists(fileName);
  }
  function directoryExists(dirPath) {
    const path = toPath3(dirPath);
    return cachedReadDirectoryResult.has(ensureTrailingDirectorySeparator(path)) || host.directoryExists(dirPath);
  }
  function createDirectory(dirPath) {
    const path = toPath3(dirPath);
    const result = getCachedFileSystemEntriesForBaseDir(path);
    if (result) {
      const baseName = getBaseNameOfFileName(dirPath);
      const canonicalizedBaseName = getCanonicalFileName(baseName);
      const canonicalizedDirectories = result.sortedAndCanonicalizedDirectories;
      if (insertSorted(canonicalizedDirectories, canonicalizedBaseName, compareStringsCaseSensitive)) {
        result.directories.push(baseName);
      }
    }
    host.createDirectory(dirPath);
  }
  function getDirectories(rootDir) {
    const rootDirPath = toPath3(rootDir);
    const result = tryReadDirectory(rootDir, rootDirPath);
    if (result) {
      return result.directories.slice();
    }
    return host.getDirectories(rootDir);
  }
  function readDirectory(rootDir, extensions, excludes, includes, depth) {
    const rootDirPath = toPath3(rootDir);
    const rootResult = tryReadDirectory(rootDir, rootDirPath);
    let rootSymLinkResult;
    if (rootResult !== void 0) {
      return matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames2, currentDirectory, depth, getFileSystemEntries, realpath);
    }
    return host.readDirectory(rootDir, extensions, excludes, includes, depth);
    function getFileSystemEntries(dir) {
      const path = toPath3(dir);
      if (path === rootDirPath) {
        return rootResult || getFileSystemEntriesFromHost(dir, path);
      }
      const result = tryReadDirectory(dir, path);
      return result !== void 0 ? result || getFileSystemEntriesFromHost(dir, path) : emptyFileSystemEntries;
    }
    function getFileSystemEntriesFromHost(dir, path) {
      if (rootSymLinkResult && path === rootDirPath) return rootSymLinkResult;
      const result = {
        files: map(host.readDirectory(
          dir,
          /*extensions*/
          void 0,
          /*exclude*/
          void 0,
          /*include*/
          ["*.*"]
        ), getBaseNameOfFileName) || emptyArray,
        directories: host.getDirectories(dir) || emptyArray
      };
      if (path === rootDirPath) rootSymLinkResult = result;
      return result;
    }
  }
  function realpath(s) {
    return host.realpath ? host.realpath(s) : s;
  }
  function addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath) {
    const existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
    if (existingResult !== void 0) {
      clearCache();
      return void 0;
    }
    const parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
    if (!parentResult) {
      return void 0;
    }
    if (!host.directoryExists) {
      clearCache();
      return void 0;
    }
    const baseName = getBaseNameOfFileName(fileOrDirectory);
    const fsQueryResult = {
      fileExists: host.fileExists(fileOrDirectory),
      directoryExists: host.directoryExists(fileOrDirectory)
    };
    if (fsQueryResult.directoryExists || hasEntry(parentResult.sortedAndCanonicalizedDirectories, getCanonicalFileName(baseName))) {
      clearCache();
    } else {
      updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
    }
    return fsQueryResult;
  }
  function addOrDeleteFile(fileName, filePath, eventKind) {
    if (eventKind === 1 /* Changed */) {
      return;
    }
    const parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
    if (parentResult) {
      updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === 0 /* Created */);
    }
  }
  function updateFilesOfFileSystemEntry(parentResult, baseName, fileExists2) {
    const canonicalizedFiles = parentResult.sortedAndCanonicalizedFiles;
    const canonicalizedBaseName = getCanonicalFileName(baseName);
    if (fileExists2) {
      if (insertSorted(canonicalizedFiles, canonicalizedBaseName, compareStringsCaseSensitive)) {
        parentResult.files.push(baseName);
      }
    } else {
      const sortedIndex = binarySearch(canonicalizedFiles, canonicalizedBaseName, identity, compareStringsCaseSensitive);
      if (sortedIndex >= 0) {
        canonicalizedFiles.splice(sortedIndex, 1);
        const unsortedIndex = parentResult.files.findIndex((entry) => getCanonicalFileName(entry) === canonicalizedBaseName);
        parentResult.files.splice(unsortedIndex, 1);
      }
    }
  }
  function clearCache() {
    cachedReadDirectoryResult.clear();
  }
}
function updateSharedExtendedConfigFileWatcher(projectPath, options, extendedConfigFilesMap, createExtendedConfigFileWatch, toPath3) {
  var _a;
  const extendedConfigs = arrayToMap(((_a = options == null ? void 0 : options.configFile) == null ? void 0 : _a.extendedSourceFiles) || emptyArray, toPath3);
  extendedConfigFilesMap.forEach((watcher, extendedConfigFilePath) => {
    if (!extendedConfigs.has(extendedConfigFilePath)) {
      watcher.projects.delete(projectPath);
      watcher.close();
    }
  });
  extendedConfigs.forEach((extendedConfigFileName, extendedConfigFilePath) => {
    const existing = extendedConfigFilesMap.get(extendedConfigFilePath);
    if (existing) {
      existing.projects.add(projectPath);
    } else {
      extendedConfigFilesMap.set(extendedConfigFilePath, {
        projects: /* @__PURE__ */ new Set([projectPath]),
        watcher: createExtendedConfigFileWatch(extendedConfigFileName, extendedConfigFilePath),
        close: () => {
          const existing2 = extendedConfigFilesMap.get(extendedConfigFilePath);
          if (!existing2 || existing2.projects.size !== 0) return;
          existing2.watcher.close();
          extendedConfigFilesMap.delete(extendedConfigFilePath);
        }
      });
    }
  });
}
function clearSharedExtendedConfigFileWatcher(projectPath, extendedConfigFilesMap) {
  extendedConfigFilesMap.forEach((watcher) => {
    if (watcher.projects.delete(projectPath)) watcher.close();
  });
}
function cleanExtendedConfigCache(extendedConfigCache, extendedConfigFilePath, toPath3) {
  if (!extendedConfigCache.delete(extendedConfigFilePath)) return;
  extendedConfigCache.forEach(({ extendedResult }, key) => {
    var _a;
    if ((_a = extendedResult.extendedSourceFiles) == null ? void 0 : _a.some((extendedFile) => toPath3(extendedFile) === extendedConfigFilePath)) {
      cleanExtendedConfigCache(extendedConfigCache, key, toPath3);
    }
  });
}
function updateMissingFilePathsWatch(program, missingFileWatches, createMissingFileWatch) {
  mutateMap(
    missingFileWatches,
    program.getMissingFilePaths(),
    {
      // Watch the missing files
      createNewValue: createMissingFileWatch,
      // Files that are no longer missing (e.g. because they are no longer required)
      // should no longer be watched.
      onDeleteValue: closeFileWatcher
    }
  );
}
function updateWatchingWildcardDirectories(existingWatchedForWildcards, wildcardDirectories, watchDirectory) {
  if (wildcardDirectories) {
    mutateMap(
      existingWatchedForWildcards,
      new Map(Object.entries(wildcardDirectories)),
      {
        // Create new watch and recursive info
        createNewValue: createWildcardDirectoryWatcher,
        // Close existing watch thats not needed any more
        onDeleteValue: closeFileWatcherOf,
        // Close existing watch that doesnt match in the flags
        onExistingValue: updateWildcardDirectoryWatcher
      }
    );
  } else {
    clearMap(existingWatchedForWildcards, closeFileWatcherOf);
  }
  function createWildcardDirectoryWatcher(directory, flags) {
    return {
      watcher: watchDirectory(directory, flags),
      flags
    };
  }
  function updateWildcardDirectoryWatcher(existingWatcher, flags, directory) {
    if (existingWatcher.flags === flags) {
      return;
    }
    existingWatcher.watcher.close();
    existingWatchedForWildcards.set(directory, createWildcardDirectoryWatcher(directory, flags));
  }
}
function isIgnoredFileFromWildCardWatching({
  watchedDirPath,
  fileOrDirectory,
  fileOrDirectoryPath,
  configFileName,
  options,
  program,
  extraFileExtensions,
  currentDirectory,
  useCaseSensitiveFileNames: useCaseSensitiveFileNames2,
  writeLog,
  toPath: toPath3,
  getScriptKind
}) {
  const newPath = removeIgnoredPath(fileOrDirectoryPath);
  if (!newPath) {
    writeLog(`Project: ${configFileName} Detected ignored path: ${fileOrDirectory}`);
    return true;
  }
  fileOrDirectoryPath = newPath;
  if (fileOrDirectoryPath === watchedDirPath) return false;
  if (hasExtension(fileOrDirectoryPath) && !(isSupportedSourceFileName(fileOrDirectory, options, extraFileExtensions) || isSupportedScriptKind())) {
    writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
    return true;
  }
  if (isExcludedFile(fileOrDirectory, options.configFile.configFileSpecs, getNormalizedAbsolutePath(getDirectoryPath(configFileName), currentDirectory), useCaseSensitiveFileNames2, currentDirectory)) {
    writeLog(`Project: ${configFileName} Detected excluded file: ${fileOrDirectory}`);
    return true;
  }
  if (!program) return false;
  if (options.outFile || options.outDir) return false;
  if (isDeclarationFileName(fileOrDirectoryPath)) {
    if (options.declarationDir) return false;
  } else if (!fileExtensionIsOneOf(fileOrDirectoryPath, supportedJSExtensionsFlat)) {
    return false;
  }
  const filePathWithoutExtension = removeFileExtension(fileOrDirectoryPath);
  const realProgram = isArray(program) ? void 0 : isBuilderProgram(program) ? program.getProgramOrUndefined() : program;
  const builderProgram = !realProgram && !isArray(program) ? program : void 0;
  if (hasSourceFile(filePathWithoutExtension + ".ts" /* Ts */) || hasSourceFile(filePathWithoutExtension + ".tsx" /* Tsx */)) {
    writeLog(`Project: ${configFileName} Detected output file: ${fileOrDirectory}`);
    return true;
  }
  return false;
  function hasSourceFile(file) {
    return realProgram ? !!realProgram.getSourceFileByPath(file) : builderProgram ? builderProgram.getState().fileInfos.has(file) : !!find(program, (rootFile) => toPath3(rootFile) === file);
  }
  function isSupportedScriptKind() {
    if (!getScriptKind) return false;
    const scriptKind = getScriptKind(fileOrDirectory);
    switch (scriptKind) {
      case 3 /* TS */:
      case 4 /* TSX */:
      case 7 /* Deferred */:
      case 5 /* External */:
        return true;
      case 1 /* JS */:
      case 2 /* JSX */:
        return getAllowJSCompilerOption(options);
      case 6 /* JSON */:
        return getResolveJsonModule(options);
      case 0 /* Unknown */:
        return false;
    }
  }
}
function isBuilderProgram(program) {
  return !!program.getState;
}
function isEmittedFileOfProgram(program, file) {
  if (!program) {
    return false;
  }
  return program.isEmittedFile(file);
}
function getWatchFactory(host, watchLogLevel, log, getDetailWatchInfo) {
  setSysLog(watchLogLevel === 2 /* Verbose */ ? log : noop);
  const plainInvokeFactory = {
    watchFile: (file, callback, pollingInterval, options) => host.watchFile(file, callback, pollingInterval, options),
    watchDirectory: (directory, callback, flags, options) => host.watchDirectory(directory, callback, (flags & 1 /* Recursive */) !== 0, options)
  };
  const triggerInvokingFactory = watchLogLevel !== 0 /* None */ ? {
    watchFile: createTriggerLoggingAddWatch("watchFile"),
    watchDirectory: createTriggerLoggingAddWatch("watchDirectory")
  } : void 0;
  const factory2 = watchLogLevel === 2 /* Verbose */ ? {
    watchFile: createFileWatcherWithLogging,
    watchDirectory: createDirectoryWatcherWithLogging
  } : triggerInvokingFactory || plainInvokeFactory;
  const excludeWatcherFactory = watchLogLevel === 2 /* Verbose */ ? createExcludeWatcherWithLogging : returnNoopFileWatcher;
  return {
    watchFile: createExcludeHandlingAddWatch("watchFile"),
    watchDirectory: createExcludeHandlingAddWatch("watchDirectory")
  };
  function createExcludeHandlingAddWatch(key) {
    return (file, cb, flags, options, detailInfo1, detailInfo2) => {
      var _a;
      return !matchesExclude(file, key === "watchFile" ? options == null ? void 0 : options.excludeFiles : options == null ? void 0 : options.excludeDirectories, useCaseSensitiveFileNames2(), ((_a = host.getCurrentDirectory) == null ? void 0 : _a.call(host)) || "") ? factory2[key].call(
        /*thisArgs*/
        void 0,
        file,
        cb,
        flags,
        options,
        detailInfo1,
        detailInfo2
      ) : excludeWatcherFactory(file, flags, options, detailInfo1, detailInfo2);
    };
  }
  function useCaseSensitiveFileNames2() {
    return typeof host.useCaseSensitiveFileNames === "boolean" ? host.useCaseSensitiveFileNames : host.useCaseSensitiveFileNames();
  }
  function createExcludeWatcherWithLogging(file, flags, options, detailInfo1, detailInfo2) {
    log(`ExcludeWatcher:: Added:: ${getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo)}`);
    return {
      close: () => log(`ExcludeWatcher:: Close:: ${getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo)}`)
    };
  }
  function createFileWatcherWithLogging(file, cb, flags, options, detailInfo1, detailInfo2) {
    log(`FileWatcher:: Added:: ${getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo)}`);
    const watcher = triggerInvokingFactory.watchFile(file, cb, flags, options, detailInfo1, detailInfo2);
    return {
      close: () => {
        log(`FileWatcher:: Close:: ${getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo)}`);
        watcher.close();
      }
    };
  }
  function createDirectoryWatcherWithLogging(file, cb, flags, options, detailInfo1, detailInfo2) {
    const watchInfo = `DirectoryWatcher:: Added:: ${getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
    log(watchInfo);
    const start = timestamp();
    const watcher = triggerInvokingFactory.watchDirectory(file, cb, flags, options, detailInfo1, detailInfo2);
    const elapsed = timestamp() - start;
    log(`Elapsed:: ${elapsed}ms ${watchInfo}`);
    return {
      close: () => {
        const watchInfo2 = `DirectoryWatcher:: Close:: ${getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
        log(watchInfo2);
        const start2 = timestamp();
        watcher.close();
        const elapsed2 = timestamp() - start2;
        log(`Elapsed:: ${elapsed2}ms ${watchInfo2}`);
      }
    };
  }
  function createTriggerLoggingAddWatch(key) {
    return (file, cb, flags, options, detailInfo1, detailInfo2) => plainInvokeFactory[key].call(
      /*thisArgs*/
      void 0,
      file,
      (...args) => {
        const triggerredInfo = `${key === "watchFile" ? "FileWatcher" : "DirectoryWatcher"}:: Triggered with ${args[0]} ${args[1] !== void 0 ? args[1] : ""}:: ${getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
        log(triggerredInfo);
        const start = timestamp();
        cb.call(
          /*thisArg*/
          void 0,
          ...args
        );
        const elapsed = timestamp() - start;
        log(`Elapsed:: ${elapsed}ms ${triggerredInfo}`);
      },
      flags,
      options,
      detailInfo1,
      detailInfo2
    );
  }
  function getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo2) {
    return `WatchInfo: ${file} ${flags} ${JSON.stringify(options)} ${getDetailWatchInfo2 ? getDetailWatchInfo2(detailInfo1, detailInfo2) : detailInfo2 === void 0 ? detailInfo1 : `${detailInfo1} ${detailInfo2}`}`;
  }
}
function getFallbackOptions(options) {
  const fallbackPolling = options == null ? void 0 : options.fallbackPolling;
  return {
    watchFile: fallbackPolling !== void 0 ? fallbackPolling : 1 /* PriorityPollingInterval */
  };
}
function closeFileWatcherOf(objWithWatcher) {
  objWithWatcher.watcher.close();
}

// src/compiler/program.ts
function findConfigFile(searchPath, fileExists, configName = "tsconfig.json") {
  return forEachAncestorDirectory(searchPath, (ancestor) => {
    const fileName = combinePaths(ancestor, configName);
    return fileExists(fileName) ? fileName : void 0;
  });
}
function resolveTripleslashReference(moduleName, containingFile) {
  const basePath = getDirectoryPath(containingFile);
  const referencedFileName = isRootedDiskPath(moduleName) ? moduleName : combinePaths(basePath, moduleName);
  return normalizePath(referencedFileName);
}
function computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName) {
  let commonPathComponents;
  const failed = forEach(fileNames, (sourceFile) => {
    const sourcePathComponents = getNormalizedPathComponents(sourceFile, currentDirectory);
    sourcePathComponents.pop();
    if (!commonPathComponents) {
      commonPathComponents = sourcePathComponents;
      return;
    }
    const n = Math.min(commonPathComponents.length, sourcePathComponents.length);
    for (let i = 0; i < n; i++) {
      if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
        if (i === 0) {
          return true;
        }
        commonPathComponents.length = i;
        break;
      }
    }
    if (sourcePathComponents.length < commonPathComponents.length) {
      commonPathComponents.length = sourcePathComponents.length;
    }
  });
  if (failed) {
    return "";
  }
  if (!commonPathComponents) {
    return currentDirectory;
  }
  return getPathFromPathComponents(commonPathComponents);
}
function createCompilerHost(options, setParentNodes) {
  return createCompilerHostWorker(options, setParentNodes);
}
function createGetSourceFile(readFile, setParentNodes) {
  return (fileName, languageVersionOrOptions, onError) => {
    let text;
    try {
      mark("beforeIORead");
      text = readFile(fileName);
      mark("afterIORead");
      measure("I/O Read", "beforeIORead", "afterIORead");
    } catch (e) {
      if (onError) {
        onError(e.message);
      }
      text = "";
    }
    return text !== void 0 ? createSourceFile(fileName, text, languageVersionOrOptions, setParentNodes) : void 0;
  };
}
function createWriteFileMeasuringIO(actualWriteFile, createDirectory, directoryExists) {
  return (fileName, data, writeByteOrderMark, onError) => {
    try {
      mark("beforeIOWrite");
      writeFileEnsuringDirectories(
        fileName,
        data,
        writeByteOrderMark,
        actualWriteFile,
        createDirectory,
        directoryExists
      );
      mark("afterIOWrite");
      measure("I/O Write", "beforeIOWrite", "afterIOWrite");
    } catch (e) {
      if (onError) {
        onError(e.message);
      }
    }
  };
}
function createCompilerHostWorker(options, setParentNodes, system = sys) {
  const existingDirectories = /* @__PURE__ */ new Map();
  const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames);
  function directoryExists(directoryPath) {
    if (existingDirectories.has(directoryPath)) {
      return true;
    }
    if ((compilerHost.directoryExists || system.directoryExists)(directoryPath)) {
      existingDirectories.set(directoryPath, true);
      return true;
    }
    return false;
  }
  function getDefaultLibLocation() {
    return getDirectoryPath(normalizePath(system.getExecutingFilePath()));
  }
  const newLine = getNewLineCharacter(options);
  const realpath = system.realpath && ((path) => system.realpath(path));
  const compilerHost = {
    getSourceFile: createGetSourceFile((fileName) => compilerHost.readFile(fileName), setParentNodes),
    getDefaultLibLocation,
    getDefaultLibFileName: (options2) => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options2)),
    writeFile: createWriteFileMeasuringIO(
      (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
      (path) => (compilerHost.createDirectory || system.createDirectory)(path),
      (path) => directoryExists(path)
    ),
    getCurrentDirectory: memoize(() => system.getCurrentDirectory()),
    useCaseSensitiveFileNames: () => system.useCaseSensitiveFileNames,
    getCanonicalFileName,
    getNewLine: () => newLine,
    fileExists: (fileName) => system.fileExists(fileName),
    readFile: (fileName) => system.readFile(fileName),
    trace: (s) => system.write(s + newLine),
    directoryExists: (directoryName) => system.directoryExists(directoryName),
    getEnvironmentVariable: (name) => system.getEnvironmentVariable ? system.getEnvironmentVariable(name) : "",
    getDirectories: (path) => system.getDirectories(path),
    realpath,
    readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth),
    createDirectory: (d) => system.createDirectory(d),
    createHash: maybeBind(system, system.createHash)
  };
  return compilerHost;
}
function changeCompilerHostLikeToUseCache(host, toPath3, getSourceFile) {
  const originalReadFile = host.readFile;
  const originalFileExists = host.fileExists;
  const originalDirectoryExists = host.directoryExists;
  const originalCreateDirectory = host.createDirectory;
  const originalWriteFile = host.writeFile;
  const readFileCache = /* @__PURE__ */ new Map();
  const fileExistsCache = /* @__PURE__ */ new Map();
  const directoryExistsCache = /* @__PURE__ */ new Map();
  const sourceFileCache = /* @__PURE__ */ new Map();
  const readFileWithCache = (fileName) => {
    const key = toPath3(fileName);
    const value = readFileCache.get(key);
    if (value !== void 0) return value !== false ? value : void 0;
    return setReadFileCache(key, fileName);
  };
  const setReadFileCache = (key, fileName) => {
    const newValue = originalReadFile.call(host, fileName);
    readFileCache.set(key, newValue !== void 0 ? newValue : false);
    return newValue;
  };
  host.readFile = (fileName) => {
    const key = toPath3(fileName);
    const value = readFileCache.get(key);
    if (value !== void 0) return value !== false ? value : void 0;
    if (!fileExtensionIs(fileName, ".json" /* Json */) && !isBuildInfoFile(fileName)) {
      return originalReadFile.call(host, fileName);
    }
    return setReadFileCache(key, fileName);
  };
  const getSourceFileWithCache = getSourceFile ? (fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile) => {
    const key = toPath3(fileName);
    const impliedNodeFormat = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions.impliedNodeFormat : void 0;
    const forImpliedNodeFormat = sourceFileCache.get(impliedNodeFormat);
    const value = forImpliedNodeFormat == null ? void 0 : forImpliedNodeFormat.get(key);
    if (value) return value;
    const sourceFile = getSourceFile(fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);
    if (sourceFile && (isDeclarationFileName(fileName) || fileExtensionIs(fileName, ".json" /* Json */))) {
      sourceFileCache.set(impliedNodeFormat, (forImpliedNodeFormat || /* @__PURE__ */ new Map()).set(key, sourceFile));
    }
    return sourceFile;
  } : void 0;
  host.fileExists = (fileName) => {
    const key = toPath3(fileName);
    const value = fileExistsCache.get(key);
    if (value !== void 0) return value;
    const newValue = originalFileExists.call(host, fileName);
    fileExistsCache.set(key, !!newValue);
    return newValue;
  };
  if (originalWriteFile) {
    host.writeFile = (fileName, data, ...rest) => {
      const key = toPath3(fileName);
      fileExistsCache.delete(key);
      const value = readFileCache.get(key);
      if (value !== void 0 && value !== data) {
        readFileCache.delete(key);
        sourceFileCache.forEach((map2) => map2.delete(key));
      } else if (getSourceFileWithCache) {
        sourceFileCache.forEach((map2) => {
          const sourceFile = map2.get(key);
          if (sourceFile && sourceFile.text !== data) {
            map2.delete(key);
          }
        });
      }
      originalWriteFile.call(host, fileName, data, ...rest);
    };
  }
  if (originalDirectoryExists) {
    host.directoryExists = (directory) => {
      const key = toPath3(directory);
      const value = directoryExistsCache.get(key);
      if (value !== void 0) return value;
      const newValue = originalDirectoryExists.call(host, directory);
      directoryExistsCache.set(key, !!newValue);
      return newValue;
    };
    if (originalCreateDirectory) {
      host.createDirectory = (directory) => {
        const key = toPath3(directory);
        directoryExistsCache.delete(key);
        originalCreateDirectory.call(host, directory);
      };
    }
  }
  return {
    originalReadFile,
    originalFileExists,
    originalDirectoryExists,
    originalCreateDirectory,
    originalWriteFile,
    getSourceFileWithCache,
    readFileWithCache
  };
}
function formatDiagnostic(diagnostic, host) {
  const errorMessage = `${diagnosticCategoryName(diagnostic)} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
  if (diagnostic.file) {
    const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
    const fileName = diagnostic.file.fileName;
    const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), (fileName2) => host.getCanonicalFileName(fileName2));
    return `${relativeFileName}(${line + 1},${character + 1}): ` + errorMessage;
  }
  return errorMessage;
}
var gutterStyleSequence = "\x1B[7m";
var gutterSeparator = " ";
var resetEscapeSequence = "\x1B[0m";
var ellipsis = "...";
var halfIndent = "  ";
var indent = "    ";
function getCategoryFormat(category) {
  switch (category) {
    case 1 /* Error */:
      return "\x1B[91m" /* Red */;
    case 0 /* Warning */:
      return "\x1B[93m" /* Yellow */;
    case 2 /* Suggestion */:
      return Debug.fail("Should never get an Info diagnostic on the command line.");
    case 3 /* Message */:
      return "\x1B[94m" /* Blue */;
  }
}
function formatColorAndReset(text, formatStyle) {
  return formatStyle + text + resetEscapeSequence;
}
function formatCodeSpan(file, start, length2, indent2, squiggleColor, host) {
  const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start);
  const { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start + length2);
  const lastLineInFile = getLineAndCharacterOfPosition(file, file.text.length).line;
  const hasMoreThanFiveLines = lastLine - firstLine >= 4;
  let gutterWidth = (lastLine + 1 + "").length;
  if (hasMoreThanFiveLines) {
    gutterWidth = Math.max(ellipsis.length, gutterWidth);
  }
  let context = "";
  for (let i = firstLine; i <= lastLine; i++) {
    context += host.getNewLine();
    if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
      context += indent2 + formatColorAndReset(ellipsis.padStart(gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
      i = lastLine - 1;
    }
    const lineStart = getPositionOfLineAndCharacter(file, i, 0);
    const lineEnd = i < lastLineInFile ? getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
    let lineContent = file.text.slice(lineStart, lineEnd);
    lineContent = lineContent.trimEnd();
    lineContent = lineContent.replace(/\t/g, " ");
    context += indent2 + formatColorAndReset((i + 1 + "").padStart(gutterWidth), gutterStyleSequence) + gutterSeparator;
    context += lineContent + host.getNewLine();
    context += indent2 + formatColorAndReset("".padStart(gutterWidth), gutterStyleSequence) + gutterSeparator;
    context += squiggleColor;
    if (i === firstLine) {
      const lastCharForLine = i === lastLine ? lastLineChar : void 0;
      context += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
      context += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
    } else if (i === lastLine) {
      context += lineContent.slice(0, lastLineChar).replace(/./g, "~");
    } else {
      context += lineContent.replace(/./g, "~");
    }
    context += resetEscapeSequence;
  }
  return context;
}
function formatLocation(file, start, host, color = formatColorAndReset) {
  const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start);
  const relativeFileName = host ? convertToRelativePath(file.fileName, host.getCurrentDirectory(), (fileName) => host.getCanonicalFileName(fileName)) : file.fileName;
  let output = "";
  output += color(relativeFileName, "\x1B[96m" /* Cyan */);
  output += ":";
  output += color(`${firstLine + 1}`, "\x1B[93m" /* Yellow */);
  output += ":";
  output += color(`${firstLineChar + 1}`, "\x1B[93m" /* Yellow */);
  return output;
}
function formatDiagnosticsWithColorAndContext(diagnostics, host) {
  let output = "";
  for (const diagnostic of diagnostics) {
    if (diagnostic.file) {
      const { file, start } = diagnostic;
      output += formatLocation(file, start, host);
      output += " - ";
    }
    output += formatColorAndReset(diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category));
    output += formatColorAndReset(` TS${diagnostic.code}: `, "\x1B[90m" /* Grey */);
    output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
    if (diagnostic.file && diagnostic.code !== Diagnostics.File_appears_to_be_binary.code) {
      output += host.getNewLine();
      output += formatCodeSpan(diagnostic.file, diagnostic.start, diagnostic.length, "", getCategoryFormat(diagnostic.category), host);
    }
    if (diagnostic.relatedInformation) {
      output += host.getNewLine();
      for (const { file, start, length: length2, messageText } of diagnostic.relatedInformation) {
        if (file) {
          output += host.getNewLine();
          output += halfIndent + formatLocation(file, start, host);
          output += formatCodeSpan(file, start, length2, indent, "\x1B[96m" /* Cyan */, host);
        }
        output += host.getNewLine();
        output += indent + flattenDiagnosticMessageText(messageText, host.getNewLine());
      }
    }
    output += host.getNewLine();
  }
  return output;
}
function flattenDiagnosticMessageText(diag2, newLine, indent2 = 0) {
  if (isString(diag2)) {
    return diag2;
  } else if (diag2 === void 0) {
    return "";
  }
  let result = "";
  if (indent2) {
    result += newLine;
    for (let i = 0; i < indent2; i++) {
      result += "  ";
    }
  }
  result += diag2.messageText;
  indent2++;
  if (diag2.next) {
    for (const kid of diag2.next) {
      result += flattenDiagnosticMessageText(kid, newLine, indent2);
    }
  }
  return result;
}
function getModeForFileReference(ref, containingFileMode) {
  return (isString(ref) ? containingFileMode : ref.resolutionMode) || containingFileMode;
}
function getModeForResolutionAtIndex(file, index, compilerOptions) {
  return getModeForUsageLocationWorker(file, getModuleNameStringLiteralAt(file, index), compilerOptions);
}
function isExclusivelyTypeOnlyImportOrExport(decl) {
  var _a;
  if (isExportDeclaration(decl)) {
    return decl.isTypeOnly;
  }
  if ((_a = decl.importClause) == null ? void 0 : _a.isTypeOnly) {
    return true;
  }
  return false;
}
function getModeForUsageLocation(file, usage, compilerOptions) {
  return getModeForUsageLocationWorker(file, usage, compilerOptions);
}
function getModeForUsageLocationWorker(file, usage, compilerOptions) {
  var _a;
  if (isImportDeclaration(usage.parent) || isExportDeclaration(usage.parent) || isJSDocImportTag(usage.parent)) {
    const isTypeOnly = isExclusivelyTypeOnlyImportOrExport(usage.parent);
    if (isTypeOnly) {
      const override = getResolutionModeOverride(usage.parent.attributes);
      if (override) {
        return override;
      }
    }
  }
  if (usage.parent.parent && isImportTypeNode(usage.parent.parent)) {
    const override = getResolutionModeOverride(usage.parent.parent.attributes);
    if (override) {
      return override;
    }
  }
  if (compilerOptions && getEmitModuleKind(compilerOptions) === 200 /* Preserve */) {
    return usage.parent.parent && isImportEqualsDeclaration(usage.parent.parent) || isRequireCall(
      usage.parent,
      /*requireStringLiteralLikeArgument*/
      false
    ) ? 1 /* CommonJS */ : 99 /* ESNext */;
  }
  if (file.impliedNodeFormat === void 0) return void 0;
  if (file.impliedNodeFormat !== 99 /* ESNext */) {
    return isImportCall(walkUpParenthesizedExpressions(usage.parent)) ? 99 /* ESNext */ : 1 /* CommonJS */;
  }
  const exprParentParent = (_a = walkUpParenthesizedExpressions(usage.parent)) == null ? void 0 : _a.parent;
  return exprParentParent && isImportEqualsDeclaration(exprParentParent) ? 1 /* CommonJS */ : 99 /* ESNext */;
}
function getResolutionModeOverride(node, grammarErrorOnNode) {
  if (!node) return void 0;
  if (length(node.elements) !== 1) {
    grammarErrorOnNode == null ? void 0 : grammarErrorOnNode(
      node,
      node.token === 118 /* WithKeyword */ ? Diagnostics.Type_import_attributes_should_have_exactly_one_key_resolution_mode_with_value_import_or_require : Diagnostics.Type_import_assertions_should_have_exactly_one_key_resolution_mode_with_value_import_or_require
    );
    return void 0;
  }
  const elem = node.elements[0];
  if (!isStringLiteralLike(elem.name)) return void 0;
  if (elem.name.text !== "resolution-mode") {
    grammarErrorOnNode == null ? void 0 : grammarErrorOnNode(
      elem.name,
      node.token === 118 /* WithKeyword */ ? Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_attributes : Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_assertions
    );
    return void 0;
  }
  if (!isStringLiteralLike(elem.value)) return void 0;
  if (elem.value.text !== "import" && elem.value.text !== "require") {
    grammarErrorOnNode == null ? void 0 : grammarErrorOnNode(elem.value, Diagnostics.resolution_mode_should_be_either_require_or_import);
    return void 0;
  }
  return elem.value.text === "import" ? 99 /* ESNext */ : 1 /* CommonJS */;
}
var emptyResolution = {
  resolvedModule: void 0,
  resolvedTypeReferenceDirective: void 0
};
function getModuleResolutionName(literal) {
  return literal.text;
}
var moduleResolutionNameAndModeGetter = {
  getName: getModuleResolutionName,
  getMode: (entry, file, compilerOptions) => getModeForUsageLocation(file, entry, compilerOptions)
};
function createModuleResolutionLoader(containingFile, redirectedReference, options, host, cache) {
  return {
    nameAndMode: moduleResolutionNameAndModeGetter,
    resolve: (moduleName, resolutionMode) => resolveModuleName(
      moduleName,
      containingFile,
      options,
      host,
      cache,
      redirectedReference,
      resolutionMode
    )
  };
}
function getTypeReferenceResolutionName(entry) {
  return !isString(entry) ? entry.fileName : entry;
}
var typeReferenceResolutionNameAndModeGetter = {
  getName: getTypeReferenceResolutionName,
  getMode: (entry, file) => getModeForFileReference(entry, file == null ? void 0 : file.impliedNodeFormat)
};
function createTypeReferenceResolutionLoader(containingFile, redirectedReference, options, host, cache) {
  return {
    nameAndMode: typeReferenceResolutionNameAndModeGetter,
    resolve: (typeRef, resoluionMode) => resolveTypeReferenceDirective(
      typeRef,
      containingFile,
      options,
      host,
      redirectedReference,
      cache,
      resoluionMode
    )
  };
}
function loadWithModeAwareCache(entries, containingFile, redirectedReference, options, containingSourceFile, host, resolutionCache, createLoader) {
  if (entries.length === 0) return emptyArray;
  const resolutions = [];
  const cache = /* @__PURE__ */ new Map();
  const loader = createLoader(containingFile, redirectedReference, options, host, resolutionCache);
  for (const entry of entries) {
    const name = loader.nameAndMode.getName(entry);
    const mode = loader.nameAndMode.getMode(entry, containingSourceFile, (redirectedReference == null ? void 0 : redirectedReference.commandLine.options) || options);
    const key = createModeAwareCacheKey(name, mode);
    let result = cache.get(key);
    if (!result) {
      cache.set(key, result = loader.resolve(name, mode));
    }
    resolutions.push(result);
  }
  return resolutions;
}
function forEachResolvedProjectReference(resolvedProjectReferences, cb) {
  return forEachProjectReference(
    /*projectReferences*/
    void 0,
    resolvedProjectReferences,
    (resolvedRef, parent) => resolvedRef && cb(resolvedRef, parent)
  );
}
function forEachProjectReference(projectReferences, resolvedProjectReferences, cbResolvedRef, cbRef) {
  let seenResolvedRefs;
  return worker(
    projectReferences,
    resolvedProjectReferences,
    /*parent*/
    void 0
  );
  function worker(projectReferences2, resolvedProjectReferences2, parent) {
    if (cbRef) {
      const result = cbRef(projectReferences2, parent);
      if (result) return result;
    }
    return forEach(resolvedProjectReferences2, (resolvedRef, index) => {
      if (resolvedRef && (seenResolvedRefs == null ? void 0 : seenResolvedRefs.has(resolvedRef.sourceFile.path))) {
        return void 0;
      }
      const result = cbResolvedRef(resolvedRef, parent, index);
      if (result || !resolvedRef) return result;
      (seenResolvedRefs || (seenResolvedRefs = /* @__PURE__ */ new Set())).add(resolvedRef.sourceFile.path);
      return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef);
    });
  }
}
var inferredTypesContainingFile = "__inferred type names__.ts";
function getInferredLibraryNameResolveFrom(options, currentDirectory, libFileName) {
  const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : currentDirectory;
  return combinePaths(containingDirectory, `__lib_node_modules_lookup_${libFileName}__.ts`);
}
function getLibraryNameFromLibFileName(libFileName) {
  const components = libFileName.split(".");
  let path = components[1];
  let i = 2;
  while (components[i] && components[i] !== "d") {
    path += (i === 2 ? "/" : "-") + components[i];
    i++;
  }
  return "@typescript/lib-" + path;
}
function getLibNameFromLibReference(libReference) {
  return toFileNameLowerCase(libReference.fileName);
}
function getLibFileNameFromLibReference(libReference) {
  const libName = getLibNameFromLibReference(libReference);
  return libMap.get(libName);
}
function isReferencedFile(reason) {
  switch (reason == null ? void 0 : reason.kind) {
    case 3 /* Import */:
    case 4 /* ReferenceFile */:
    case 5 /* TypeReferenceDirective */:
    case 7 /* LibReferenceDirective */:
      return true;
    default:
      return false;
  }
}
function isReferenceFileLocation(location) {
  return location.pos !== void 0;
}
function getReferencedFileLocation(program, ref) {
  var _a, _b, _c, _d;
  const file = Debug.checkDefined(program.getSourceFileByPath(ref.file));
  const { kind, index } = ref;
  let pos, end, packageId;
  switch (kind) {
    case 3 /* Import */:
      const importLiteral = getModuleNameStringLiteralAt(file, index);
      packageId = (_b = (_a = program.getResolvedModuleFromModuleSpecifier(importLiteral, file)) == null ? void 0 : _a.resolvedModule) == null ? void 0 : _b.packageId;
      if (importLiteral.pos === -1) return { file, packageId, text: importLiteral.text };
      pos = skipTrivia(file.text, importLiteral.pos);
      end = importLiteral.end;
      break;
    case 4 /* ReferenceFile */:
      ({ pos, end } = file.referencedFiles[index]);
      break;
    case 5 /* TypeReferenceDirective */:
      ({ pos, end } = file.typeReferenceDirectives[index]);
      packageId = (_d = (_c = program.getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(file.typeReferenceDirectives[index], file)) == null ? void 0 : _c.resolvedTypeReferenceDirective) == null ? void 0 : _d.packageId;
      break;
    case 7 /* LibReferenceDirective */:
      ({ pos, end } = file.libReferenceDirectives[index]);
      break;
    default:
      return Debug.assertNever(kind);
  }
  return { file, pos, end, packageId };
}
function isProgramUptoDate(program, rootFileNames, newOptions, getSourceVersion, fileExists, hasInvalidatedResolutions, hasInvalidatedLibResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences) {
  if (!program || (hasChangedAutomaticTypeDirectiveNames == null ? void 0 : hasChangedAutomaticTypeDirectiveNames())) return false;
  if (!arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) return false;
  let seenResolvedRefs;
  if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) return false;
  if (program.getSourceFiles().some(sourceFileNotUptoDate)) return false;
  const missingPaths = program.getMissingFilePaths();
  if (missingPaths && forEachEntry(missingPaths, fileExists)) return false;
  const currentOptions = program.getCompilerOptions();
  if (!compareDataObjects(currentOptions, newOptions)) return false;
  if (program.resolvedLibReferences && forEachEntry(program.resolvedLibReferences, (_value, libFileName) => hasInvalidatedLibResolutions(libFileName))) return false;
  if (currentOptions.configFile && newOptions.configFile) return currentOptions.configFile.text === newOptions.configFile.text;
  return true;
  function sourceFileNotUptoDate(sourceFile) {
    return !sourceFileVersionUptoDate(sourceFile) || hasInvalidatedResolutions(sourceFile.path);
  }
  function sourceFileVersionUptoDate(sourceFile) {
    return sourceFile.version === getSourceVersion(sourceFile.resolvedPath, sourceFile.fileName);
  }
  function projectReferenceUptoDate(oldRef, newRef, index) {
    return projectReferenceIsEqualTo(oldRef, newRef) && resolvedProjectReferenceUptoDate(program.getResolvedProjectReferences()[index], oldRef);
  }
  function resolvedProjectReferenceUptoDate(oldResolvedRef, oldRef) {
    if (oldResolvedRef) {
      if (contains(seenResolvedRefs, oldResolvedRef)) return true;
      const refPath2 = resolveProjectReferencePath(oldRef);
      const newParsedCommandLine = getParsedCommandLine(refPath2);
      if (!newParsedCommandLine) return false;
      if (oldResolvedRef.commandLine.options.configFile !== newParsedCommandLine.options.configFile) return false;
      if (!arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newParsedCommandLine.fileNames)) return false;
      (seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef);
      return !forEach(oldResolvedRef.references, (childResolvedRef, index) => !resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences[index]));
    }
    const refPath = resolveProjectReferencePath(oldRef);
    return !getParsedCommandLine(refPath);
  }
}
function getConfigFileParsingDiagnostics(configFileParseResult) {
  return configFileParseResult.options.configFile ? [...configFileParseResult.options.configFile.parseDiagnostics, ...configFileParseResult.errors] : configFileParseResult.errors;
}
function getImpliedNodeFormatForFileWorker(fileName, packageJsonInfoCache, host, options) {
  switch (getEmitModuleResolutionKind(options)) {
    case 3 /* Node16 */:
    case 99 /* NodeNext */:
      return fileExtensionIsOneOf(fileName, [".d.mts" /* Dmts */, ".mts" /* Mts */, ".mjs" /* Mjs */]) ? 99 /* ESNext */ : fileExtensionIsOneOf(fileName, [".d.cts" /* Dcts */, ".cts" /* Cts */, ".cjs" /* Cjs */]) ? 1 /* CommonJS */ : fileExtensionIsOneOf(fileName, [".d.ts" /* Dts */, ".ts" /* Ts */, ".tsx" /* Tsx */, ".js" /* Js */, ".jsx" /* Jsx */]) ? lookupFromPackageJson() : void 0;
    default:
      return void 0;
  }
  function lookupFromPackageJson() {
    const state = getTemporaryModuleResolutionState(packageJsonInfoCache, host, options);
    const packageJsonLocations = [];
    state.failedLookupLocations = packageJsonLocations;
    state.affectingLocations = packageJsonLocations;
    const packageJsonScope = getPackageScopeForPath(fileName, state);
    const impliedNodeFormat = (packageJsonScope == null ? void 0 : packageJsonScope.contents.packageJsonContent.type) === "module" ? 99 /* ESNext */ : 1 /* CommonJS */;
    return { impliedNodeFormat, packageJsonLocations, packageJsonScope };
  }
}
var plainJSErrors = /* @__PURE__ */ new Set([
  // binder errors
  Diagnostics.Cannot_redeclare_block_scoped_variable_0.code,
  Diagnostics.A_module_cannot_have_multiple_default_exports.code,
  Diagnostics.Another_export_default_is_here.code,
  Diagnostics.The_first_export_default_is_here.code,
  Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module.code,
  Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode.code,
  Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here.code,
  Diagnostics.constructor_is_a_reserved_word.code,
  Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode.code,
  Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode.code,
  Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode.code,
  Diagnostics.Invalid_use_of_0_in_strict_mode.code,
  Diagnostics.A_label_is_not_allowed_here.code,
  Diagnostics.with_statements_are_not_allowed_in_strict_mode.code,
  // grammar errors
  Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement.code,
  Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement.code,
  Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name.code,
  Diagnostics.A_class_member_cannot_have_the_0_keyword.code,
  Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name.code,
  Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement.code,
  Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement.code,
  Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement.code,
  Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement.code,
  Diagnostics.A_default_export_must_be_at_the_top_level_of_a_file_or_module_declaration.code,
  Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context.code,
  Diagnostics.A_destructuring_declaration_must_have_an_initializer.code,
  Diagnostics.A_get_accessor_cannot_have_parameters.code,
  Diagnostics.A_rest_element_cannot_contain_a_binding_pattern.code,
  Diagnostics.A_rest_element_cannot_have_a_property_name.code,
  Diagnostics.A_rest_element_cannot_have_an_initializer.code,
  Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern.code,
  Diagnostics.A_rest_parameter_cannot_have_an_initializer.code,
  Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list.code,
  Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma.code,
  Diagnostics.A_return_statement_cannot_be_used_inside_a_class_static_block.code,
  Diagnostics.A_set_accessor_cannot_have_rest_parameter.code,
  Diagnostics.A_set_accessor_must_have_exactly_one_parameter.code,
  Diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_module.code,
  Diagnostics.An_export_declaration_cannot_have_modifiers.code,
  Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module.code,
  Diagnostics.An_import_declaration_cannot_have_modifiers.code,
  Diagnostics.An_object_member_cannot_be_declared_optional.code,
  Diagnostics.Argument_of_dynamic_import_cannot_be_spread_element.code,
  Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable.code,
  Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause.code,
  Diagnostics.Catch_clause_variable_cannot_have_an_initializer.code,
  Diagnostics.Class_decorators_can_t_be_used_with_static_private_identifier_Consider_removing_the_experimental_decorator.code,
  Diagnostics.Classes_can_only_extend_a_single_class.code,
  Diagnostics.Classes_may_not_have_a_field_named_constructor.code,
  Diagnostics.Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern.code,
  Diagnostics.Duplicate_label_0.code,
  Diagnostics.Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_set_of_attributes_as_arguments.code,
  Diagnostics.for_await_loops_cannot_be_used_inside_a_class_static_block.code,
  Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression.code,
  Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name.code,
  Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array.code,
  Diagnostics.JSX_property_access_expressions_cannot_include_JSX_namespace_names.code,
  Diagnostics.Jump_target_cannot_cross_function_boundary.code,
  Diagnostics.Line_terminator_not_permitted_before_arrow.code,
  Diagnostics.Modifiers_cannot_appear_here.code,
  Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement.code,
  Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement.code,
  Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies.code,
  Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression.code,
  Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier.code,
  Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain.code,
  Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_async.code,
  Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer.code,
  Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer.code,
  Diagnostics.Trailing_comma_not_allowed.code,
  Diagnostics.Variable_declaration_list_cannot_be_empty.code,
  Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses.code,
  Diagnostics._0_expected.code,
  Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2.code,
  Diagnostics._0_list_cannot_be_empty.code,
  Diagnostics._0_modifier_already_seen.code,
  Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration.code,
  Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element.code,
  Diagnostics._0_modifier_cannot_appear_on_a_parameter.code,
  Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind.code,
  Diagnostics._0_modifier_cannot_be_used_here.code,
  Diagnostics._0_modifier_must_precede_1_modifier.code,
  Diagnostics._0_declarations_can_only_be_declared_inside_a_block.code,
  Diagnostics._0_declarations_must_be_initialized.code,
  Diagnostics.extends_clause_already_seen.code,
  Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations.code,
  Diagnostics.Class_constructor_may_not_be_a_generator.code,
  Diagnostics.Class_constructor_may_not_be_an_accessor.code,
  Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code,
  Diagnostics.await_using_statements_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code,
  Diagnostics.Private_field_0_must_be_declared_in_an_enclosing_class.code,
  // Type errors
  Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value.code
]);
function shouldProgramCreateNewSourceFiles(program, newOptions) {
  if (!program) return false;
  return optionsHaveChanges(program.getCompilerOptions(), newOptions, sourceFileAffectingCompilerOptions);
}
function createCreateProgramOptions(rootNames, options, host, oldProgram, configFileParsingDiagnostics, typeScriptVersion2) {
  return {
    rootNames,
    options,
    host,
    oldProgram,
    configFileParsingDiagnostics,
    typeScriptVersion: typeScriptVersion2
  };
}
function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
  const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;
  const { rootNames, options, configFileParsingDiagnostics, projectReferences, typeScriptVersion: typeScriptVersion2 } = createProgramOptions;
  let { oldProgram } = createProgramOptions;
  for (const option of commandLineOptionOfCustomType) {
    if (hasProperty(options, option.name)) {
      if (typeof options[option.name] === "string") {
        throw new Error(`${option.name} is a string value; tsconfig JSON must be parsed with parseJsonSourceFileConfigFileContent or getParsedCommandLineOfConfigFile before passing to createProgram`);
      }
    }
  }
  const reportInvalidIgnoreDeprecations = memoize(() => createOptionValueDiagnostic("ignoreDeprecations", Diagnostics.Invalid_value_for_ignoreDeprecations));
  let processingDefaultLibFiles;
  let processingOtherFiles;
  let files;
  let symlinks;
  let commonSourceDirectory;
  let typeChecker;
  let classifiableNames;
  const ambientModuleNameToUnmodifiedFileName = /* @__PURE__ */ new Map();
  let fileReasons = createMultiMap();
  let filesWithReferencesProcessed;
  let fileReasonsToChain;
  let reasonToRelatedInfo;
  const cachedBindAndCheckDiagnosticsForFile = {};
  const cachedDeclarationDiagnosticsForFile = {};
  let fileProcessingDiagnostics;
  let automaticTypeDirectiveNames;
  let automaticTypeDirectiveResolutions;
  let resolvedLibReferences;
  let resolvedLibProcessing;
  let resolvedModules;
  let resolvedModulesProcessing;
  let resolvedTypeReferenceDirectiveNames;
  let resolvedTypeReferenceDirectiveNamesProcessing;
  let packageMap;
  const maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
  let currentNodeModulesDepth = 0;
  const modulesWithElidedImports = /* @__PURE__ */ new Map();
  const sourceFilesFoundSearchingNodeModules = /* @__PURE__ */ new Map();
  (_a = tracing) == null ? void 0 : _a.push(
    tracing.Phase.Program,
    "createProgram",
    { configFilePath: options.configFilePath, rootDir: options.rootDir },
    /*separateBeginAndEnd*/
    true
  );
  mark("beforeProgram");
  const host = createProgramOptions.host || createCompilerHost(options);
  const configParsingHost = parseConfigHostFromCompilerHostLike(host);
  let skipDefaultLib = options.noLib;
  const getDefaultLibraryFileName = memoize(() => host.getDefaultLibFileName(options));
  const defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : getDirectoryPath(getDefaultLibraryFileName());
  const programDiagnostics = createDiagnosticCollection();
  let lazyProgramDiagnosticExplainingFile = [];
  const currentDirectory = host.getCurrentDirectory();
  const supportedExtensions = getSupportedExtensions(options);
  const supportedExtensionsWithJsonIfResolveJsonModule = getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
  const hasEmitBlockingDiagnostics = /* @__PURE__ */ new Map();
  let _compilerOptionsObjectLiteralSyntax;
  let _compilerOptionsPropertySyntax;
  let moduleResolutionCache;
  let actualResolveModuleNamesWorker;
  const hasInvalidatedResolutions = host.hasInvalidatedResolutions || returnFalse;
  if (host.resolveModuleNameLiterals) {
    actualResolveModuleNamesWorker = host.resolveModuleNameLiterals.bind(host);
    moduleResolutionCache = (_b = host.getModuleResolutionCache) == null ? void 0 : _b.call(host);
  } else if (host.resolveModuleNames) {
    actualResolveModuleNamesWorker = (moduleNames, containingFile, redirectedReference, options2, containingSourceFile, reusedNames) => host.resolveModuleNames(
      moduleNames.map(getModuleResolutionName),
      containingFile,
      reusedNames == null ? void 0 : reusedNames.map(getModuleResolutionName),
      redirectedReference,
      options2,
      containingSourceFile
    ).map(
      (resolved) => resolved ? resolved.extension !== void 0 ? { resolvedModule: resolved } : (
        // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
        { resolvedModule: { ...resolved, extension: extensionFromPath(resolved.resolvedFileName) } }
      ) : emptyResolution
    );
    moduleResolutionCache = (_c = host.getModuleResolutionCache) == null ? void 0 : _c.call(host);
  } else {
    moduleResolutionCache = createModuleResolutionCache(currentDirectory, getCanonicalFileName, options);
    actualResolveModuleNamesWorker = (moduleNames, containingFile, redirectedReference, options2, containingSourceFile) => loadWithModeAwareCache(
      moduleNames,
      containingFile,
      redirectedReference,
      options2,
      containingSourceFile,
      host,
      moduleResolutionCache,
      createModuleResolutionLoader
    );
  }
  let actualResolveTypeReferenceDirectiveNamesWorker;
  if (host.resolveTypeReferenceDirectiveReferences) {
    actualResolveTypeReferenceDirectiveNamesWorker = host.resolveTypeReferenceDirectiveReferences.bind(host);
  } else if (host.resolveTypeReferenceDirectives) {
    actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, options2, containingSourceFile) => host.resolveTypeReferenceDirectives(
      typeDirectiveNames.map(getTypeReferenceResolutionName),
      containingFile,
      redirectedReference,
      options2,
      containingSourceFile == null ? void 0 : containingSourceFile.impliedNodeFormat
    ).map((resolvedTypeReferenceDirective) => ({ resolvedTypeReferenceDirective }));
  } else {
    const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
      currentDirectory,
      getCanonicalFileName,
      /*options*/
      void 0,
      moduleResolutionCache == null ? void 0 : moduleResolutionCache.getPackageJsonInfoCache(),
      moduleResolutionCache == null ? void 0 : moduleResolutionCache.optionsToRedirectsKey
    );
    actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, options2, containingSourceFile) => loadWithModeAwareCache(
      typeDirectiveNames,
      containingFile,
      redirectedReference,
      options2,
      containingSourceFile,
      host,
      typeReferenceDirectiveResolutionCache,
      createTypeReferenceResolutionLoader
    );
  }
  const hasInvalidatedLibResolutions = host.hasInvalidatedLibResolutions || returnFalse;
  let actualResolveLibrary;
  if (host.resolveLibrary) {
    actualResolveLibrary = host.resolveLibrary.bind(host);
  } else {
    const libraryResolutionCache = createModuleResolutionCache(currentDirectory, getCanonicalFileName, options, moduleResolutionCache == null ? void 0 : moduleResolutionCache.getPackageJsonInfoCache());
    actualResolveLibrary = (libraryName, resolveFrom, options2) => resolveLibrary(libraryName, resolveFrom, options2, host, libraryResolutionCache);
  }
  const packageIdToSourceFile = /* @__PURE__ */ new Map();
  let sourceFileToPackageName = /* @__PURE__ */ new Map();
  let redirectTargetsMap = createMultiMap();
  let usesUriStyleNodeCoreModules = false;
  const filesByName = /* @__PURE__ */ new Map();
  let missingFileNames = /* @__PURE__ */ new Map();
  const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? /* @__PURE__ */ new Map() : void 0;
  let resolvedProjectReferences;
  let projectReferenceRedirects;
  let mapFromFileToProjectReferenceRedirects;
  let mapFromToProjectReferenceRedirectSource;
  const useSourceOfProjectReferenceRedirect = !!((_d = host.useSourceOfProjectReferenceRedirect) == null ? void 0 : _d.call(host)) && !options.disableSourceOfProjectReferenceRedirect;
  const { onProgramCreateComplete, fileExists, directoryExists } = updateHostForUseSourceOfProjectReferenceRedirect({
    compilerHost: host,
    getSymlinkCache,
    useSourceOfProjectReferenceRedirect,
    toPath: toPath3,
    getResolvedProjectReferences,
    getSourceOfProjectReferenceRedirect,
    forEachResolvedProjectReference: forEachResolvedProjectReference2
  });
  const readFile = host.readFile.bind(host);
  (_e = tracing) == null ? void 0 : _e.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram });
  const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
  (_f = tracing) == null ? void 0 : _f.pop();
  let structureIsReused;
  (_g = tracing) == null ? void 0 : _g.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {});
  structureIsReused = tryReuseStructureFromOldProgram();
  (_h = tracing) == null ? void 0 : _h.pop();
  if (structureIsReused !== 2 /* Completely */) {
    processingDefaultLibFiles = [];
    processingOtherFiles = [];
    if (projectReferences) {
      if (!resolvedProjectReferences) {
        resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
      }
      if (rootNames.length) {
        resolvedProjectReferences == null ? void 0 : resolvedProjectReferences.forEach((parsedRef, index) => {
          if (!parsedRef) return;
          const out = parsedRef.commandLine.options.outFile;
          if (useSourceOfProjectReferenceRedirect) {
            if (out || getEmitModuleKind(parsedRef.commandLine.options) === 0 /* None */) {
              for (const fileName of parsedRef.commandLine.fileNames) {
                processProjectReferenceFile(fileName, { kind: 1 /* SourceFromProjectReference */, index });
              }
            }
          } else {
            if (out) {
              processProjectReferenceFile(changeExtension(out, ".d.ts"), { kind: 2 /* OutputFromProjectReference */, index });
            } else if (getEmitModuleKind(parsedRef.commandLine.options) === 0 /* None */) {
              const getCommonSourceDirectory3 = memoize(() => getCommonSourceDirectoryOfConfig(parsedRef.commandLine, !host.useCaseSensitiveFileNames()));
              for (const fileName of parsedRef.commandLine.fileNames) {
                if (!isDeclarationFileName(fileName) && !fileExtensionIs(fileName, ".json" /* Json */)) {
                  processProjectReferenceFile(getOutputDeclarationFileName(fileName, parsedRef.commandLine, !host.useCaseSensitiveFileNames(), getCommonSourceDirectory3), { kind: 2 /* OutputFromProjectReference */, index });
                }
              }
            }
          }
        });
      }
    }
    (_i = tracing) == null ? void 0 : _i.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length });
    forEach(rootNames, (name, index) => processRootFile(
      name,
      /*isDefaultLib*/
      false,
      /*ignoreNoDefaultLib*/
      false,
      { kind: 0 /* RootFile */, index }
    ));
    (_j = tracing) == null ? void 0 : _j.pop();
    automaticTypeDirectiveNames ?? (automaticTypeDirectiveNames = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray);
    automaticTypeDirectiveResolutions = createModeAwareCache();
    if (automaticTypeDirectiveNames.length) {
      (_k = tracing) == null ? void 0 : _k.push(tracing.Phase.Program, "processTypeReferences", { count: automaticTypeDirectiveNames.length });
      const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : currentDirectory;
      const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
      const resolutions = resolveTypeReferenceDirectiveNamesReusingOldState(automaticTypeDirectiveNames, containingFilename);
      for (let i = 0; i < automaticTypeDirectiveNames.length; i++) {
        automaticTypeDirectiveResolutions.set(
          automaticTypeDirectiveNames[i],
          /*mode*/
          void 0,
          resolutions[i]
        );
        processTypeReferenceDirective(
          automaticTypeDirectiveNames[i],
          /*mode*/
          void 0,
          resolutions[i],
          {
            kind: 8 /* AutomaticTypeDirectiveFile */,
            typeReference: automaticTypeDirectiveNames[i],
            packageId: (_m = (_l = resolutions[i]) == null ? void 0 : _l.resolvedTypeReferenceDirective) == null ? void 0 : _m.packageId
          }
        );
      }
      (_n = tracing) == null ? void 0 : _n.pop();
    }
    if (rootNames.length && !skipDefaultLib) {
      const defaultLibraryFileName = getDefaultLibraryFileName();
      if (!options.lib && defaultLibraryFileName) {
        processRootFile(
          defaultLibraryFileName,
          /*isDefaultLib*/
          true,
          /*ignoreNoDefaultLib*/
          false,
          { kind: 6 /* LibFile */ }
        );
      } else {
        forEach(options.lib, (libFileName, index) => {
          processRootFile(
            pathForLibFile(libFileName),
            /*isDefaultLib*/
            true,
            /*ignoreNoDefaultLib*/
            false,
            { kind: 6 /* LibFile */, index }
          );
        });
      }
    }
    files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
    processingDefaultLibFiles = void 0;
    processingOtherFiles = void 0;
    filesWithReferencesProcessed = void 0;
  }
  if (oldProgram && host.onReleaseOldSourceFile) {
    const oldSourceFiles = oldProgram.getSourceFiles();
    for (const oldSourceFile of oldSourceFiles) {
      const newFile = getSourceFileByPath(oldSourceFile.resolvedPath);
      if (shouldCreateNewSourceFile || !newFile || newFile.impliedNodeFormat !== oldSourceFile.impliedNodeFormat || // old file wasn't redirect but new file is
      oldSourceFile.resolvedPath === oldSourceFile.path && newFile.resolvedPath !== oldSourceFile.path) {
        host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions(), !!getSourceFileByPath(oldSourceFile.path));
      }
    }
    if (!host.getParsedCommandLine) {
      oldProgram.forEachResolvedProjectReference((resolvedProjectReference) => {
        if (!getResolvedProjectReferenceByPath(resolvedProjectReference.sourceFile.path)) {
          host.onReleaseOldSourceFile(
            resolvedProjectReference.sourceFile,
            oldProgram.getCompilerOptions(),
            /*hasSourceFileByPath*/
            false
          );
        }
      });
    }
  }
  if (oldProgram && host.onReleaseParsedCommandLine) {
    forEachProjectReference(
      oldProgram.getProjectReferences(),
      oldProgram.getResolvedProjectReferences(),
      (oldResolvedRef, parent, index) => {
        const oldReference = (parent == null ? void 0 : parent.commandLine.projectReferences[index]) || oldProgram.getProjectReferences()[index];
        const oldRefPath = resolveProjectReferencePath(oldReference);
        if (!(projectReferenceRedirects == null ? void 0 : projectReferenceRedirects.has(toPath3(oldRefPath)))) {
          host.onReleaseParsedCommandLine(oldRefPath, oldResolvedRef, oldProgram.getCompilerOptions());
        }
      }
    );
  }
  oldProgram = void 0;
  resolvedLibProcessing = void 0;
  resolvedModulesProcessing = void 0;
  resolvedTypeReferenceDirectiveNamesProcessing = void 0;
  const program = {
    getRootFileNames: () => rootNames,
    getSourceFile,
    getSourceFileByPath,
    getSourceFiles: () => files,
    getMissingFilePaths: () => missingFileNames,
    getModuleResolutionCache: () => moduleResolutionCache,
    getFilesByNameMap: () => filesByName,
    getCompilerOptions: () => options,
    getSyntacticDiagnostics,
    getOptionsDiagnostics,
    getGlobalDiagnostics,
    getSemanticDiagnostics,
    getCachedSemanticDiagnostics,
    getSuggestionDiagnostics,
    getDeclarationDiagnostics: getDeclarationDiagnostics2,
    getBindAndCheckDiagnostics,
    getProgramDiagnostics,
    getTypeChecker,
    getClassifiableNames,
    getCommonSourceDirectory: getCommonSourceDirectory2,
    emit,
    getCurrentDirectory: () => currentDirectory,
    getNodeCount: () => getTypeChecker().getNodeCount(),
    getIdentifierCount: () => getTypeChecker().getIdentifierCount(),
    getSymbolCount: () => getTypeChecker().getSymbolCount(),
    getTypeCount: () => getTypeChecker().getTypeCount(),
    getInstantiationCount: () => getTypeChecker().getInstantiationCount(),
    getRelationCacheSizes: () => getTypeChecker().getRelationCacheSizes(),
    getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
    getAutomaticTypeDirectiveNames: () => automaticTypeDirectiveNames,
    getAutomaticTypeDirectiveResolutions: () => automaticTypeDirectiveResolutions,
    isSourceFileFromExternalLibrary,
    isSourceFileDefaultLibrary,
    getModeForUsageLocation: getModeForUsageLocation2,
    getModeForResolutionAtIndex: getModeForResolutionAtIndex2,
    getSourceFileFromReference,
    getLibFileFromReference,
    sourceFileToPackageName,
    redirectTargetsMap,
    usesUriStyleNodeCoreModules,
    resolvedModules,
    resolvedTypeReferenceDirectiveNames,
    resolvedLibReferences,
    getResolvedModule,
    getResolvedModuleFromModuleSpecifier,
    getResolvedTypeReferenceDirective,
    getResolvedTypeReferenceDirectiveFromTypeReferenceDirective,
    forEachResolvedModule,
    forEachResolvedTypeReferenceDirective,
    getCurrentPackagesMap: () => packageMap,
    typesPackageExists,
    packageBundlesTypes,
    isEmittedFile,
    getConfigFileParsingDiagnostics: getConfigFileParsingDiagnostics2,
    getProjectReferences,
    getResolvedProjectReferences,
    getProjectReferenceRedirect,
    getResolvedProjectReferenceToRedirect,
    getResolvedProjectReferenceByPath,
    forEachResolvedProjectReference: forEachResolvedProjectReference2,
    isSourceOfProjectReferenceRedirect,
    getRedirectReferenceForResolutionFromSourceOfProject,
    emitBuildInfo,
    fileExists,
    readFile,
    directoryExists,
    getSymlinkCache,
    realpath: (_o = host.realpath) == null ? void 0 : _o.bind(host),
    useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
    getCanonicalFileName,
    getFileIncludeReasons: () => fileReasons,
    structureIsReused,
    writeFile: writeFile2
  };
  onProgramCreateComplete();
  verifyCompilerOptions();
  mark("afterProgram");
  measure("Program", "beforeProgram", "afterProgram");
  (_p = tracing) == null ? void 0 : _p.pop();
  return program;
  function updateAndGetProgramDiagnostics() {
    if (lazyProgramDiagnosticExplainingFile) {
      fileProcessingDiagnostics == null ? void 0 : fileProcessingDiagnostics.forEach((diagnostic) => {
        switch (diagnostic.kind) {
          case 1 /* FilePreprocessingFileExplainingDiagnostic */:
            return programDiagnostics.add(
              createDiagnosticExplainingFile(
                diagnostic.file && getSourceFileByPath(diagnostic.file),
                diagnostic.fileProcessingReason,
                diagnostic.diagnostic,
                diagnostic.args || emptyArray
              )
            );
          case 0 /* FilePreprocessingLibReferenceDiagnostic */:
            return programDiagnostics.add(filePreprocessingLibreferenceDiagnostic(diagnostic));
          case 2 /* ResolutionDiagnostics */:
            return diagnostic.diagnostics.forEach((d) => programDiagnostics.add(d));
          default:
            Debug.assertNever(diagnostic);
        }
      });
      lazyProgramDiagnosticExplainingFile.forEach(
        ({ file, diagnostic, args }) => programDiagnostics.add(
          createDiagnosticExplainingFile(
            file,
            /*fileProcessingReason*/
            void 0,
            diagnostic,
            args
          )
        )
      );
      lazyProgramDiagnosticExplainingFile = void 0;
      fileReasonsToChain = void 0;
      reasonToRelatedInfo = void 0;
    }
    return programDiagnostics;
  }
  function filePreprocessingLibreferenceDiagnostic({ reason }) {
    const { file, pos, end } = getReferencedFileLocation(program, reason);
    const libReference = file.libReferenceDirectives[reason.index];
    const libName = getLibNameFromLibReference(libReference);
    const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts");
    const suggestion = getSpellingSuggestion(unqualifiedLibName, libs, identity);
    return createFileDiagnostic(
      file,
      Debug.checkDefined(pos),
      Debug.checkDefined(end) - pos,
      suggestion ? Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : Diagnostics.Cannot_find_lib_definition_for_0,
      libName,
      suggestion
    );
  }
  function getResolvedModule(file, moduleName, mode) {
    var _a2;
    return (_a2 = resolvedModules == null ? void 0 : resolvedModules.get(file.path)) == null ? void 0 : _a2.get(moduleName, mode);
  }
  function getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile) {
    sourceFile ?? (sourceFile = getSourceFileOfNode(moduleSpecifier));
    Debug.assertIsDefined(sourceFile, "`moduleSpecifier` must have a `SourceFile` ancestor. Use `program.getResolvedModule` instead to provide the containing file and resolution mode.");
    return getResolvedModule(sourceFile, moduleSpecifier.text, getModeForUsageLocation2(sourceFile, moduleSpecifier));
  }
  function getResolvedTypeReferenceDirective(file, typeDirectiveName, mode) {
    var _a2;
    return (_a2 = resolvedTypeReferenceDirectiveNames == null ? void 0 : resolvedTypeReferenceDirectiveNames.get(file.path)) == null ? void 0 : _a2.get(typeDirectiveName, mode);
  }
  function getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typeRef, sourceFile) {
    return getResolvedTypeReferenceDirective(sourceFile, typeRef.fileName, typeRef.resolutionMode || sourceFile.impliedNodeFormat);
  }
  function forEachResolvedModule(callback, file) {
    forEachResolution(resolvedModules, callback, file);
  }
  function forEachResolvedTypeReferenceDirective(callback, file) {
    forEachResolution(resolvedTypeReferenceDirectiveNames, callback, file);
  }
  function forEachResolution(resolutionCache, callback, file) {
    var _a2;
    if (file) (_a2 = resolutionCache == null ? void 0 : resolutionCache.get(file.path)) == null ? void 0 : _a2.forEach((resolution, name, mode) => callback(resolution, name, mode, file.path));
    else resolutionCache == null ? void 0 : resolutionCache.forEach((resolutions, filePath) => resolutions.forEach((resolution, name, mode) => callback(resolution, name, mode, filePath)));
  }
  function getPackagesMap() {
    if (packageMap) return packageMap;
    packageMap = /* @__PURE__ */ new Map();
    forEachResolvedModule(({ resolvedModule }) => {
      if (resolvedModule == null ? void 0 : resolvedModule.packageId) packageMap.set(resolvedModule.packageId.name, resolvedModule.extension === ".d.ts" /* Dts */ || !!packageMap.get(resolvedModule.packageId.name));
    });
    return packageMap;
  }
  function typesPackageExists(packageName) {
    return getPackagesMap().has(getTypesPackageName(packageName));
  }
  function packageBundlesTypes(packageName) {
    return !!getPackagesMap().get(packageName);
  }
  function addResolutionDiagnostics(resolution) {
    var _a2;
    if (!((_a2 = resolution.resolutionDiagnostics) == null ? void 0 : _a2.length)) return;
    (fileProcessingDiagnostics ?? (fileProcessingDiagnostics = [])).push({
      kind: 2 /* ResolutionDiagnostics */,
      diagnostics: resolution.resolutionDiagnostics
    });
  }
  function addResolutionDiagnosticsFromResolutionOrCache(containingFile, name, resolution, mode) {
    if (host.resolveModuleNameLiterals || !host.resolveModuleNames) return addResolutionDiagnostics(resolution);
    if (!moduleResolutionCache || isExternalModuleNameRelative(name)) return;
    const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory);
    const containingDir = getDirectoryPath(containingFileName);
    const redirectedReference = getRedirectReferenceForResolution(containingFile);
    const fromCache = moduleResolutionCache.getFromNonRelativeNameCache(name, mode, containingDir, redirectedReference);
    if (fromCache) addResolutionDiagnostics(fromCache);
  }
  function resolveModuleNamesWorker(moduleNames, containingFile, reusedNames) {
    var _a2, _b2;
    if (!moduleNames.length) return emptyArray;
    const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory);
    const redirectedReference = getRedirectReferenceForResolution(containingFile);
    (_a2 = tracing) == null ? void 0 : _a2.push(tracing.Phase.Program, "resolveModuleNamesWorker", { containingFileName });
    mark("beforeResolveModule");
    const result = actualResolveModuleNamesWorker(moduleNames, containingFileName, redirectedReference, options, containingFile, reusedNames);
    mark("afterResolveModule");
    measure("ResolveModule", "beforeResolveModule", "afterResolveModule");
    (_b2 = tracing) == null ? void 0 : _b2.pop();
    return result;
  }
  function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFile, reusedNames) {
    var _a2, _b2;
    if (!typeDirectiveNames.length) return [];
    const containingSourceFile = !isString(containingFile) ? containingFile : void 0;
    const containingFileName = !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile;
    const redirectedReference = containingSourceFile && getRedirectReferenceForResolution(containingSourceFile);
    (_a2 = tracing) == null ? void 0 : _a2.push(tracing.Phase.Program, "resolveTypeReferenceDirectiveNamesWorker", { containingFileName });
    mark("beforeResolveTypeReference");
    const result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFileName, redirectedReference, options, containingSourceFile, reusedNames);
    mark("afterResolveTypeReference");
    measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference");
    (_b2 = tracing) == null ? void 0 : _b2.pop();
    return result;
  }
  function getRedirectReferenceForResolution(file) {
    const redirect = getResolvedProjectReferenceToRedirect(file.originalFileName);
    if (redirect || !isDeclarationFileName(file.originalFileName)) return redirect;
    const resultFromDts = getRedirectReferenceForResolutionFromSourceOfProject(file.path);
    if (resultFromDts) return resultFromDts;
    if (!host.realpath || !options.preserveSymlinks || !file.originalFileName.includes(nodeModulesPathPart)) return void 0;
    const realDeclarationPath = toPath3(host.realpath(file.originalFileName));
    return realDeclarationPath === file.path ? void 0 : getRedirectReferenceForResolutionFromSourceOfProject(realDeclarationPath);
  }
  function getRedirectReferenceForResolutionFromSourceOfProject(filePath) {
    const source = getSourceOfProjectReferenceRedirect(filePath);
    if (isString(source)) return getResolvedProjectReferenceToRedirect(source);
    if (!source) return void 0;
    return forEachResolvedProjectReference2((resolvedRef) => {
      const out = resolvedRef.commandLine.options.outFile;
      if (!out) return void 0;
      return toPath3(out) === filePath ? resolvedRef : void 0;
    });
  }
  function compareDefaultLibFiles(a, b) {
    return compareValues(getDefaultLibFilePriority(a), getDefaultLibFilePriority(b));
  }
  function getDefaultLibFilePriority(a) {
    if (containsPath(
      defaultLibraryPath,
      a.fileName,
      /*ignoreCase*/
      false
    )) {
      const basename = getBaseFileName(a.fileName);
      if (basename === "lib.d.ts" || basename === "lib.es6.d.ts") return 0;
      const name = removeSuffix(removePrefix(basename, "lib."), ".d.ts");
      const index = libs.indexOf(name);
      if (index !== -1) return index + 1;
    }
    return libs.length + 2;
  }
  function toPath3(fileName) {
    return toPath(fileName, currentDirectory, getCanonicalFileName);
  }
  function getCommonSourceDirectory2() {
    if (commonSourceDirectory === void 0) {
      const emittedFiles = filter(files, (file) => sourceFileMayBeEmitted(file, program));
      commonSourceDirectory = getCommonSourceDirectory(
        options,
        () => mapDefined(emittedFiles, (file) => file.isDeclarationFile ? void 0 : file.fileName),
        currentDirectory,
        getCanonicalFileName,
        (commonSourceDirectory2) => checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory2)
      );
    }
    return commonSourceDirectory;
  }
  function getClassifiableNames() {
    var _a2;
    if (!classifiableNames) {
      getTypeChecker();
      classifiableNames = /* @__PURE__ */ new Set();
      for (const sourceFile of files) {
        (_a2 = sourceFile.classifiableNames) == null ? void 0 : _a2.forEach((value) => classifiableNames.add(value));
      }
    }
    return classifiableNames;
  }
  function resolveModuleNamesReusingOldState(moduleNames, file) {
    if (structureIsReused === 0 /* Not */ && !file.ambientModuleNames.length) {
      return resolveModuleNamesWorker(
        moduleNames,
        file,
        /*reusedNames*/
        void 0
      );
    }
    let unknownModuleNames;
    let result;
    let reusedNames;
    const predictedToResolveToAmbientModuleMarker = emptyResolution;
    const oldSourceFile = oldProgram && oldProgram.getSourceFile(file.fileName);
    for (let i = 0; i < moduleNames.length; i++) {
      const moduleName = moduleNames[i];
      if (file === oldSourceFile && !hasInvalidatedResolutions(file.path)) {
        const oldResolution = oldProgram == null ? void 0 : oldProgram.getResolvedModule(file, moduleName.text, getModeForUsageLocation2(file, moduleName));
        if (oldResolution == null ? void 0 : oldResolution.resolvedModule) {
          if (isTraceEnabled(options, host)) {
            trace(
              host,
              oldResolution.resolvedModule.packageId ? Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2,
              moduleName.text,
              getNormalizedAbsolutePath(file.originalFileName, currentDirectory),
              oldResolution.resolvedModule.resolvedFileName,
              oldResolution.resolvedModule.packageId && packageIdToString(oldResolution.resolvedModule.packageId)
            );
          }
          (result ?? (result = new Array(moduleNames.length)))[i] = oldResolution;
          (reusedNames ?? (reusedNames = [])).push(moduleName);
          continue;
        }
      }
      let resolvesToAmbientModuleInNonModifiedFile = false;
      if (contains(file.ambientModuleNames, moduleName.text)) {
        resolvesToAmbientModuleInNonModifiedFile = true;
        if (isTraceEnabled(options, host)) {
          trace(host, Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName.text, getNormalizedAbsolutePath(file.originalFileName, currentDirectory));
        }
      } else {
        resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName);
      }
      if (resolvesToAmbientModuleInNonModifiedFile) {
        (result || (result = new Array(moduleNames.length)))[i] = predictedToResolveToAmbientModuleMarker;
      } else {
        (unknownModuleNames ?? (unknownModuleNames = [])).push(moduleName);
      }
    }
    const resolutions = unknownModuleNames && unknownModuleNames.length ? resolveModuleNamesWorker(unknownModuleNames, file, reusedNames) : emptyArray;
    if (!result) {
      Debug.assert(resolutions.length === moduleNames.length);
      return resolutions;
    }
    let j = 0;
    for (let i = 0; i < result.length; i++) {
      if (!result[i]) {
        result[i] = resolutions[j];
        j++;
      }
    }
    Debug.assert(j === resolutions.length);
    return result;
    function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName) {
      var _a2;
      const resolutionToFile = (_a2 = oldProgram == null ? void 0 : oldProgram.getResolvedModule(file, moduleName.text, getModeForUsageLocation2(file, moduleName))) == null ? void 0 : _a2.resolvedModule;
      const resolvedFile = resolutionToFile && oldProgram.getSourceFile(resolutionToFile.resolvedFileName);
      if (resolutionToFile && resolvedFile) {
        return false;
      }
      const unmodifiedFile = ambientModuleNameToUnmodifiedFileName.get(moduleName.text);
      if (!unmodifiedFile) {
        return false;
      }
      if (isTraceEnabled(options, host)) {
        trace(host, Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName.text, unmodifiedFile);
      }
      return true;
    }
  }
  function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames, containingFile) {
    var _a2;
    if (structureIsReused === 0 /* Not */) {
      return resolveTypeReferenceDirectiveNamesWorker(
        typeDirectiveNames,
        containingFile,
        /*reusedNames*/
        void 0
      );
    }
    let unknownTypeReferenceDirectiveNames;
    let result;
    let reusedNames;
    const containingSourceFile = !isString(containingFile) ? containingFile : void 0;
    const oldSourceFile = !isString(containingFile) ? oldProgram && oldProgram.getSourceFile(containingFile.fileName) : void 0;
    const canReuseResolutions = !isString(containingFile) ? containingFile === oldSourceFile && !hasInvalidatedResolutions(containingFile.path) : !hasInvalidatedResolutions(toPath3(containingFile));
    for (let i = 0; i < typeDirectiveNames.length; i++) {
      const entry = typeDirectiveNames[i];
      if (canReuseResolutions) {
        const typeDirectiveName = getTypeReferenceResolutionName(entry);
        const mode = getModeForFileReference(entry, containingSourceFile == null ? void 0 : containingSourceFile.impliedNodeFormat);
        const oldResolution = !isString(containingFile) ? oldProgram == null ? void 0 : oldProgram.getResolvedTypeReferenceDirective(containingFile, typeDirectiveName, mode) : (_a2 = oldProgram == null ? void 0 : oldProgram.getAutomaticTypeDirectiveResolutions()) == null ? void 0 : _a2.get(typeDirectiveName, mode);
        if (oldResolution == null ? void 0 : oldResolution.resolvedTypeReferenceDirective) {
          if (isTraceEnabled(options, host)) {
            trace(
              host,
              oldResolution.resolvedTypeReferenceDirective.packageId ? Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2,
              typeDirectiveName,
              !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile,
              oldResolution.resolvedTypeReferenceDirective.resolvedFileName,
              oldResolution.resolvedTypeReferenceDirective.packageId && packageIdToString(oldResolution.resolvedTypeReferenceDirective.packageId)
            );
          }
          (result ?? (result = new Array(typeDirectiveNames.length)))[i] = oldResolution;
          (reusedNames ?? (reusedNames = [])).push(entry);
          continue;
        }
      }
      (unknownTypeReferenceDirectiveNames ?? (unknownTypeReferenceDirectiveNames = [])).push(entry);
    }
    if (!unknownTypeReferenceDirectiveNames) return result || emptyArray;
    const resolutions = resolveTypeReferenceDirectiveNamesWorker(
      unknownTypeReferenceDirectiveNames,
      containingFile,
      reusedNames
    );
    if (!result) {
      Debug.assert(resolutions.length === typeDirectiveNames.length);
      return resolutions;
    }
    let j = 0;
    for (let i = 0; i < result.length; i++) {
      if (!result[i]) {
        result[i] = resolutions[j];
        j++;
      }
    }
    Debug.assert(j === resolutions.length);
    return result;
  }
  function canReuseProjectReferences() {
    return !forEachProjectReference(
      oldProgram.getProjectReferences(),
      oldProgram.getResolvedProjectReferences(),
      (oldResolvedRef, parent, index) => {
        const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
        const newResolvedRef = parseProjectReferenceConfigFile(newRef);
        if (oldResolvedRef) {
          return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile || !arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames);
        } else {
          return newResolvedRef !== void 0;
        }
      },
      (oldProjectReferences, parent) => {
        const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path).commandLine.projectReferences : projectReferences;
        return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);
      }
    );
  }
  function tryReuseStructureFromOldProgram() {
    var _a2;
    if (!oldProgram) {
      return 0 /* Not */;
    }
    const oldOptions = oldProgram.getCompilerOptions();
    if (changesAffectModuleResolution(oldOptions, options)) {
      return 0 /* Not */;
    }
    const oldRootNames = oldProgram.getRootFileNames();
    if (!arrayIsEqualTo(oldRootNames, rootNames)) {
      return 0 /* Not */;
    }
    if (!canReuseProjectReferences()) {
      return 0 /* Not */;
    }
    if (projectReferences) {
      resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
    }
    const newSourceFiles = [];
    const modifiedSourceFiles = [];
    structureIsReused = 2 /* Completely */;
    if (forEachEntry(oldProgram.getMissingFilePaths(), (missingFileName) => host.fileExists(missingFileName))) {
      return 0 /* Not */;
    }
    const oldSourceFiles = oldProgram.getSourceFiles();
    let SeenPackageName;
    ((SeenPackageName2) => {
      SeenPackageName2[SeenPackageName2["Exists"] = 0] = "Exists";
      SeenPackageName2[SeenPackageName2["Modified"] = 1] = "Modified";
    })(SeenPackageName || (SeenPackageName = {}));
    const seenPackageNames = /* @__PURE__ */ new Map();
    for (const oldSourceFile of oldSourceFiles) {
      const sourceFileOptions = getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options);
      let newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(
        oldSourceFile.fileName,
        oldSourceFile.resolvedPath,
        sourceFileOptions,
        /*onError*/
        void 0,
        shouldCreateNewSourceFile
      ) : host.getSourceFile(
        oldSourceFile.fileName,
        sourceFileOptions,
        /*onError*/
        void 0,
        shouldCreateNewSourceFile
      );
      if (!newSourceFile) {
        return 0 /* Not */;
      }
      newSourceFile.packageJsonLocations = ((_a2 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a2.length) ? sourceFileOptions.packageJsonLocations : void 0;
      newSourceFile.packageJsonScope = sourceFileOptions.packageJsonScope;
      Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`");
      let fileChanged;
      if (oldSourceFile.redirectInfo) {
        if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
          return 0 /* Not */;
        }
        fileChanged = false;
        newSourceFile = oldSourceFile;
      } else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
        if (newSourceFile !== oldSourceFile) {
          return 0 /* Not */;
        }
        fileChanged = false;
      } else {
        fileChanged = newSourceFile !== oldSourceFile;
      }
      newSourceFile.path = oldSourceFile.path;
      newSourceFile.originalFileName = oldSourceFile.originalFileName;
      newSourceFile.resolvedPath = oldSourceFile.resolvedPath;
      newSourceFile.fileName = oldSourceFile.fileName;
      const packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
      if (packageName !== void 0) {
        const prevKind = seenPackageNames.get(packageName);
        const newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
        if (prevKind !== void 0 && newKind === 1 /* Modified */ || prevKind === 1 /* Modified */) {
          return 0 /* Not */;
        }
        seenPackageNames.set(packageName, newKind);
      }
      if (fileChanged) {
        if (oldSourceFile.impliedNodeFormat !== newSourceFile.impliedNodeFormat) {
          structureIsReused = 1 /* SafeModules */;
        } else if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
          structureIsReused = 1 /* SafeModules */;
        } else if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
          structureIsReused = 1 /* SafeModules */;
        } else if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
          structureIsReused = 1 /* SafeModules */;
        } else {
          collectExternalModuleReferences(newSourceFile);
          if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
            structureIsReused = 1 /* SafeModules */;
          } else if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
            structureIsReused = 1 /* SafeModules */;
          } else if ((oldSourceFile.flags & 12582912 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 12582912 /* PermanentlySetIncrementalFlags */)) {
            structureIsReused = 1 /* SafeModules */;
          } else if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
            structureIsReused = 1 /* SafeModules */;
          }
        }
        modifiedSourceFiles.push(newSourceFile);
      } else if (hasInvalidatedResolutions(oldSourceFile.path)) {
        structureIsReused = 1 /* SafeModules */;
        modifiedSourceFiles.push(newSourceFile);
      } else {
        for (const moduleName of oldSourceFile.ambientModuleNames) {
          ambientModuleNameToUnmodifiedFileName.set(moduleName, oldSourceFile.fileName);
        }
      }
      newSourceFiles.push(newSourceFile);
    }
    if (structureIsReused !== 2 /* Completely */) {
      return structureIsReused;
    }
    for (const newSourceFile of modifiedSourceFiles) {
      const moduleNames = getModuleNames(newSourceFile);
      const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);
      (resolvedModulesProcessing ?? (resolvedModulesProcessing = /* @__PURE__ */ new Map())).set(newSourceFile.path, resolutions);
      const resolutionsChanged = hasChangesInResolutions(
        moduleNames,
        resolutions,
        (name) => oldProgram.getResolvedModule(newSourceFile, name.text, getModeForUsageLocation2(newSourceFile, name)),
        moduleResolutionIsEqualTo
      );
      if (resolutionsChanged) structureIsReused = 1 /* SafeModules */;
      const typesReferenceDirectives = newSourceFile.typeReferenceDirectives;
      const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesReusingOldState(typesReferenceDirectives, newSourceFile);
      (resolvedTypeReferenceDirectiveNamesProcessing ?? (resolvedTypeReferenceDirectiveNamesProcessing = /* @__PURE__ */ new Map())).set(newSourceFile.path, typeReferenceResolutions);
      const typeReferenceResolutionsChanged = hasChangesInResolutions(
        typesReferenceDirectives,
        typeReferenceResolutions,
        (name) => oldProgram.getResolvedTypeReferenceDirective(newSourceFile, getTypeReferenceResolutionName(name), getModeForFileReference(name, newSourceFile.impliedNodeFormat)),
        typeDirectiveIsEqualTo
      );
      if (typeReferenceResolutionsChanged) structureIsReused = 1 /* SafeModules */;
    }
    if (structureIsReused !== 2 /* Completely */) {
      return structureIsReused;
    }
    if (changesAffectingProgramStructure(oldOptions, options)) {
      return 1 /* SafeModules */;
    }
    if (oldProgram.resolvedLibReferences && forEachEntry(oldProgram.resolvedLibReferences, (resolution, libFileName) => pathForLibFileWorker(libFileName).actual !== resolution.actual)) {
      return 1 /* SafeModules */;
    }
    if (host.hasChangedAutomaticTypeDirectiveNames) {
      if (host.hasChangedAutomaticTypeDirectiveNames()) return 1 /* SafeModules */;
    } else {
      automaticTypeDirectiveNames = getAutomaticTypeDirectiveNames(options, host);
      if (!arrayIsEqualTo(oldProgram.getAutomaticTypeDirectiveNames(), automaticTypeDirectiveNames)) return 1 /* SafeModules */;
    }
    missingFileNames = oldProgram.getMissingFilePaths();
    Debug.assert(newSourceFiles.length === oldProgram.getSourceFiles().length);
    for (const newSourceFile of newSourceFiles) {
      filesByName.set(newSourceFile.path, newSourceFile);
    }
    const oldFilesByNameMap = oldProgram.getFilesByNameMap();
    oldFilesByNameMap.forEach((oldFile, path) => {
      if (!oldFile) {
        filesByName.set(path, oldFile);
        return;
      }
      if (oldFile.path === path) {
        if (oldProgram.isSourceFileFromExternalLibrary(oldFile)) {
          sourceFilesFoundSearchingNodeModules.set(oldFile.path, true);
        }
        return;
      }
      filesByName.set(path, filesByName.get(oldFile.path));
    });
    files = newSourceFiles;
    fileReasons = oldProgram.getFileIncludeReasons();
    fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
    automaticTypeDirectiveNames = oldProgram.getAutomaticTypeDirectiveNames();
    automaticTypeDirectiveResolutions = oldProgram.getAutomaticTypeDirectiveResolutions();
    sourceFileToPackageName = oldProgram.sourceFileToPackageName;
    redirectTargetsMap = oldProgram.redirectTargetsMap;
    usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
    resolvedModules = oldProgram.resolvedModules;
    resolvedTypeReferenceDirectiveNames = oldProgram.resolvedTypeReferenceDirectiveNames;
    resolvedLibReferences = oldProgram.resolvedLibReferences;
    packageMap = oldProgram.getCurrentPackagesMap();
    return 2 /* Completely */;
  }
  function getEmitHost(writeFileCallback) {
    return {
      getCanonicalFileName,
      getCommonSourceDirectory: program.getCommonSourceDirectory,
      getCompilerOptions: program.getCompilerOptions,
      getCurrentDirectory: () => currentDirectory,
      getSourceFile: program.getSourceFile,
      getSourceFileByPath: program.getSourceFileByPath,
      getSourceFiles: program.getSourceFiles,
      isSourceFileFromExternalLibrary,
      getResolvedProjectReferenceToRedirect,
      getProjectReferenceRedirect,
      isSourceOfProjectReferenceRedirect,
      getSymlinkCache,
      writeFile: writeFileCallback || writeFile2,
      isEmitBlocked,
      readFile: (f) => host.readFile(f),
      fileExists: (f) => {
        const path = toPath3(f);
        if (getSourceFileByPath(path)) return true;
        if (missingFileNames.has(path)) return false;
        return host.fileExists(f);
      },
      realpath: maybeBind(host, host.realpath),
      useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
      getBuildInfo: () => {
        var _a2;
        return (_a2 = program.getBuildInfo) == null ? void 0 : _a2.call(program);
      },
      getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref),
      redirectTargetsMap,
      getFileIncludeReasons: program.getFileIncludeReasons,
      createHash: maybeBind(host, host.createHash),
      getModuleResolutionCache: () => program.getModuleResolutionCache(),
      trace: maybeBind(host, host.trace)
    };
  }
  function writeFile2(fileName, text, writeByteOrderMark, onError, sourceFiles, data) {
    host.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
  }
  function emitBuildInfo(writeFileCallback) {
    var _a2, _b2;
    Debug.assert(!options.outFile);
    (_a2 = tracing) == null ? void 0 : _a2.push(
      tracing.Phase.Emit,
      "emitBuildInfo",
      {},
      /*separateBeginAndEnd*/
      true
    );
    mark("beforeEmit");
    const emitResult = emitFiles(
      notImplementedResolver,
      getEmitHost(writeFileCallback),
      /*targetSourceFile*/
      void 0,
      /*transformers*/
      noTransformers,
      /*emitOnly*/
      false,
      /*onlyBuildInfo*/
      true
    );
    mark("afterEmit");
    measure("Emit", "beforeEmit", "afterEmit");
    (_b2 = tracing) == null ? void 0 : _b2.pop();
    return emitResult;
  }
  function getResolvedProjectReferences() {
    return resolvedProjectReferences;
  }
  function getProjectReferences() {
    return projectReferences;
  }
  function isSourceFileFromExternalLibrary(file) {
    return !!sourceFilesFoundSearchingNodeModules.get(file.path);
  }
  function isSourceFileDefaultLibrary(file) {
    if (!file.isDeclarationFile) {
      return false;
    }
    if (file.hasNoDefaultLib) {
      return true;
    }
    if (!options.noLib) {
      return false;
    }
    const equalityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive;
    if (!options.lib) {
      return equalityComparer(file.fileName, getDefaultLibraryFileName());
    } else {
      return some(options.lib, (libFileName) => equalityComparer(file.fileName, resolvedLibReferences.get(libFileName).actual));
    }
  }
  function getTypeChecker() {
    return typeChecker || (typeChecker = createTypeChecker(program));
  }
  function emit(sourceFile, writeFileCallback, cancellationToken, emitOnly, transformers, forceDtsEmit) {
    var _a2, _b2;
    (_a2 = tracing) == null ? void 0 : _a2.push(
      tracing.Phase.Emit,
      "emit",
      { path: sourceFile == null ? void 0 : sourceFile.path },
      /*separateBeginAndEnd*/
      true
    );
    const result = runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnly, transformers, forceDtsEmit));
    (_b2 = tracing) == null ? void 0 : _b2.pop();
    return result;
  }
  function isEmitBlocked(emitFileName) {
    return hasEmitBlockingDiagnostics.has(toPath3(emitFileName));
  }
  function emitWorker(program2, sourceFile, writeFileCallback, cancellationToken, emitOnly, customTransformers, forceDtsEmit) {
    if (!forceDtsEmit) {
      const result = handleNoEmitOptions(program2, sourceFile, writeFileCallback, cancellationToken);
      if (result) return result;
    }
    const typeChecker2 = getTypeChecker();
    const emitResolver = typeChecker2.getEmitResolver(
      options.outFile ? void 0 : sourceFile,
      cancellationToken,
      emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit)
    );
    mark("beforeEmit");
    const emitResult = typeChecker2.runWithCancellationToken(
      cancellationToken,
      () => emitFiles(
        emitResolver,
        getEmitHost(writeFileCallback),
        sourceFile,
        getTransformers(options, customTransformers, emitOnly),
        emitOnly,
        /*onlyBuildInfo*/
        false,
        forceDtsEmit
      )
    );
    mark("afterEmit");
    measure("Emit", "beforeEmit", "afterEmit");
    return emitResult;
  }
  function getSourceFile(fileName) {
    return getSourceFileByPath(toPath3(fileName));
  }
  function getSourceFileByPath(path) {
    return filesByName.get(path) || void 0;
  }
  function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) {
    if (sourceFile) {
      return sortAndDeduplicateDiagnostics(getDiagnostics(sourceFile, cancellationToken));
    }
    return sortAndDeduplicateDiagnostics(flatMap(program.getSourceFiles(), (sourceFile2) => {
      if (cancellationToken) {
        cancellationToken.throwIfCancellationRequested();
      }
      return getDiagnostics(sourceFile2, cancellationToken);
    }));
  }
  function getSyntacticDiagnostics(sourceFile, cancellationToken) {
    return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
  }
  function getSemanticDiagnostics(sourceFile, cancellationToken) {
    return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
  }
  function getCachedSemanticDiagnostics(sourceFile) {
    var _a2;
    return sourceFile ? (_a2 = cachedBindAndCheckDiagnosticsForFile.perFile) == null ? void 0 : _a2.get(sourceFile.path) : cachedBindAndCheckDiagnosticsForFile.allDiagnostics;
  }
  function getBindAndCheckDiagnostics(sourceFile, cancellationToken) {
    return getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken);
  }
  function getProgramDiagnostics(sourceFile) {
    var _a2;
    if (skipTypeChecking(sourceFile, options, program)) {
      return emptyArray;
    }
    const programDiagnosticsInFile = updateAndGetProgramDiagnostics().getDiagnostics(sourceFile.fileName);
    if (!((_a2 = sourceFile.commentDirectives) == null ? void 0 : _a2.length)) {
      return programDiagnosticsInFile;
    }
    return getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, programDiagnosticsInFile).diagnostics;
  }
  function getDeclarationDiagnostics2(sourceFile, cancellationToken) {
    const options2 = program.getCompilerOptions();
    if (!sourceFile || options2.outFile) {
      return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
    } else {
      return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken);
    }
  }
  function getSyntacticDiagnosticsForFile(sourceFile) {
    if (isSourceFileJS(sourceFile)) {
      if (!sourceFile.additionalSyntacticDiagnostics) {
        sourceFile.additionalSyntacticDiagnostics = getJSSyntacticDiagnosticsForFile(sourceFile);
      }
      return concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
    }
    return sourceFile.parseDiagnostics;
  }
  function runWithCancellationToken(func) {
    try {
      return func();
    } catch (e) {
      if (e instanceof OperationCanceledException) {
        typeChecker = void 0;
      }
      throw e;
    }
  }
  function getSemanticDiagnosticsForFile(sourceFile, cancellationToken) {
    return concatenate(
      filterSemanticDiagnostics(getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken), options),
      getProgramDiagnostics(sourceFile)
    );
  }
  function getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken) {
    return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedBindAndCheckDiagnosticsForFile, getBindAndCheckDiagnosticsForFileNoCache);
  }
  function getBindAndCheckDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
    return runWithCancellationToken(() => {
      if (skipTypeChecking(sourceFile, options, program)) {
        return emptyArray;
      }
      const typeChecker2 = getTypeChecker();
      Debug.assert(!!sourceFile.bindDiagnostics);
      const isJs = sourceFile.scriptKind === 1 /* JS */ || sourceFile.scriptKind === 2 /* JSX */;
      const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options);
      const isPlainJs = isPlainJsFile(sourceFile, options.checkJs);
      let bindDiagnostics = sourceFile.bindDiagnostics;
      let checkDiagnostics = typeChecker2.getDiagnostics(sourceFile, cancellationToken);
      if (isPlainJs) {
        bindDiagnostics = filter(bindDiagnostics, (d) => plainJSErrors.has(d.code));
        checkDiagnostics = filter(checkDiagnostics, (d) => plainJSErrors.has(d.code));
      }
      return getMergedBindAndCheckDiagnostics(sourceFile, !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : void 0);
    });
  }
  function getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics, ...allDiagnostics) {
    var _a2;
    const flatDiagnostics = flatten(allDiagnostics);
    if (!includeBindAndCheckDiagnostics || !((_a2 = sourceFile.commentDirectives) == null ? void 0 : _a2.length)) {
      return flatDiagnostics;
    }
    const { diagnostics, directives } = getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, flatDiagnostics);
    for (const errorExpectation of directives.getUnusedExpectations()) {
      diagnostics.push(createDiagnosticForRange(sourceFile, errorExpectation.range, Diagnostics.Unused_ts_expect_error_directive));
    }
    return diagnostics;
  }
  function getDiagnosticsWithPrecedingDirectives(sourceFile, commentDirectives, flatDiagnostics) {
    const directives = createCommentDirectivesMap(sourceFile, commentDirectives);
    const diagnostics = flatDiagnostics.filter((diagnostic) => markPrecedingCommentDirectiveLine(diagnostic, directives) === -1);
    return { diagnostics, directives };
  }
  function getSuggestionDiagnostics(sourceFile, cancellationToken) {
    return runWithCancellationToken(() => {
      return getTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
    });
  }
  function markPrecedingCommentDirectiveLine(diagnostic, directives) {
    const { file, start } = diagnostic;
    if (!file) {
      return -1;
    }
    const lineStarts = getLineStarts(file);
    let line = computeLineAndCharacterOfPosition(lineStarts, start).line - 1;
    while (line >= 0) {
      if (directives.markUsed(line)) {
        return line;
      }
      const lineText = file.text.slice(lineStarts[line], lineStarts[line + 1]).trim();
      if (lineText !== "" && !/^(\s*)\/\/(.*)$/.test(lineText)) {
        return -1;
      }
      line--;
    }
    return -1;
  }
  function getJSSyntacticDiagnosticsForFile(sourceFile) {
    return runWithCancellationToken(() => {
      const diagnostics = [];
      walk(sourceFile, sourceFile);
      forEachChildRecursively(sourceFile, walk, walkArray);
      return diagnostics;
      function walk(node, parent) {
        switch (parent.kind) {
          case 169 /* Parameter */:
          case 172 /* PropertyDeclaration */:
          case 174 /* MethodDeclaration */:
            if (parent.questionToken === node) {
              diagnostics.push(createDiagnosticForNode2(node, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?"));
              return "skip";
            }
          case 173 /* MethodSignature */:
          case 176 /* Constructor */:
          case 177 /* GetAccessor */:
          case 178 /* SetAccessor */:
          case 218 /* FunctionExpression */:
          case 262 /* FunctionDeclaration */:
          case 219 /* ArrowFunction */:
          case 260 /* VariableDeclaration */:
            if (parent.type === node) {
              diagnostics.push(createDiagnosticForNode2(node, Diagnostics.Type_annotations_can_only_be_used_in_TypeScript_files));
              return "skip";
            }
        }
        switch (node.kind) {
          case 273 /* ImportClause */:
            if (node.isTypeOnly) {
              diagnostics.push(createDiagnosticForNode2(parent, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "import type"));
              return "skip";
            }
            break;
          case 278 /* ExportDeclaration */:
            if (node.isTypeOnly) {
              diagnostics.push(createDiagnosticForNode2(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "export type"));
              return "skip";
            }
            break;
          case 276 /* ImportSpecifier */:
          case 281 /* ExportSpecifier */:
            if (node.isTypeOnly) {
              diagnostics.push(createDiagnosticForNode2(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, isImportSpecifier(node) ? "import...type" : "export...type"));
              return "skip";
            }
            break;
          case 271 /* ImportEqualsDeclaration */:
            diagnostics.push(createDiagnosticForNode2(node, Diagnostics.import_can_only_be_used_in_TypeScript_files));
            return "skip";
          case 277 /* ExportAssignment */:
            if (node.isExportEquals) {
              diagnostics.push(createDiagnosticForNode2(node, Diagnostics.export_can_only_be_used_in_TypeScript_files));
              return "skip";
            }
            break;
          case 298 /* HeritageClause */:
            const heritageClause = node;
            if (heritageClause.token === 119 /* ImplementsKeyword */) {
              diagnostics.push(createDiagnosticForNode2(node, Diagnostics.implements_clauses_can_only_be_used_in_TypeScript_files));
              return "skip";
            }
            break;
          case 264 /* InterfaceDeclaration */:
            const interfaceKeyword = tokenToString(120 /* InterfaceKeyword */);
            Debug.assertIsDefined(interfaceKeyword);
            diagnostics.push(createDiagnosticForNode2(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, interfaceKeyword));
            return "skip";
          case 267 /* ModuleDeclaration */:
            const moduleKeyword = node.flags & 32 /* Namespace */ ? tokenToString(145 /* NamespaceKeyword */) : tokenToString(144 /* ModuleKeyword */);
            Debug.assertIsDefined(moduleKeyword);
            diagnostics.push(createDiagnosticForNode2(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, moduleKeyword));
            return "skip";
          case 265 /* TypeAliasDeclaration */:
            diagnostics.push(createDiagnosticForNode2(node, Diagnostics.Type_aliases_can_only_be_used_in_TypeScript_files));
            return "skip";
          case 176 /* Constructor */:
          case 174 /* MethodDeclaration */:
          case 262 /* FunctionDeclaration */:
            if (!node.body) {
              diagnostics.push(createDiagnosticForNode2(node, Diagnostics.Signature_declarations_can_only_be_used_in_TypeScript_files));
              return "skip";
            }
            return;
          case 266 /* EnumDeclaration */:
            const enumKeyword = Debug.checkDefined(tokenToString(94 /* EnumKeyword */));
            diagnostics.push(createDiagnosticForNode2(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, enumKeyword));
            return "skip";
          case 235 /* NonNullExpression */:
            diagnostics.push(createDiagnosticForNode2(node, Diagnostics.Non_null_assertions_can_only_be_used_in_TypeScript_files));
            return "skip";
          case 234 /* AsExpression */:
            diagnostics.push(createDiagnosticForNode2(node.type, Diagnostics.Type_assertion_expressions_can_only_be_used_in_TypeScript_files));
            return "skip";
          case 238 /* SatisfiesExpression */:
            diagnostics.push(createDiagnosticForNode2(node.type, Diagnostics.Type_satisfaction_expressions_can_only_be_used_in_TypeScript_files));
            return "skip";
          case 216 /* TypeAssertionExpression */:
            Debug.fail();
        }
      }
      function walkArray(nodes, parent) {
        if (canHaveIllegalDecorators(parent)) {
          const decorator = find(parent.modifiers, isDecorator);
          if (decorator) {
            diagnostics.push(createDiagnosticForNode2(decorator, Diagnostics.Decorators_are_not_valid_here));
          }
        } else if (canHaveDecorators(parent) && parent.modifiers) {
          const decoratorIndex = findIndex(parent.modifiers, isDecorator);
          if (decoratorIndex >= 0) {
            if (isParameter(parent) && !options.experimentalDecorators) {
              diagnostics.push(createDiagnosticForNode2(parent.modifiers[decoratorIndex], Diagnostics.Decorators_are_not_valid_here));
            } else if (isClassDeclaration(parent)) {
              const exportIndex = findIndex(parent.modifiers, isExportModifier);
              if (exportIndex >= 0) {
                const defaultIndex = findIndex(parent.modifiers, isDefaultModifier);
                if (decoratorIndex > exportIndex && defaultIndex >= 0 && decoratorIndex < defaultIndex) {
                  diagnostics.push(createDiagnosticForNode2(parent.modifiers[decoratorIndex], Diagnostics.Decorators_are_not_valid_here));
                } else if (exportIndex >= 0 && decoratorIndex < exportIndex) {
                  const trailingDecoratorIndex = findIndex(parent.modifiers, isDecorator, exportIndex);
                  if (trailingDecoratorIndex >= 0) {
                    diagnostics.push(addRelatedInfo(
                      createDiagnosticForNode2(parent.modifiers[trailingDecoratorIndex], Diagnostics.Decorators_may_not_appear_after_export_or_export_default_if_they_also_appear_before_export),
                      createDiagnosticForNode2(parent.modifiers[decoratorIndex], Diagnostics.Decorator_used_before_export_here)
                    ));
                  }
                }
              }
            }
          }
        }
        switch (parent.kind) {
          case 263 /* ClassDeclaration */:
          case 231 /* ClassExpression */:
          case 174 /* MethodDeclaration */:
          case 176 /* Constructor */:
          case 177 /* GetAccessor */:
          case 178 /* SetAccessor */:
          case 218 /* FunctionExpression */:
          case 262 /* FunctionDeclaration */:
          case 219 /* ArrowFunction */:
            if (nodes === parent.typeParameters) {
              diagnostics.push(createDiagnosticForNodeArray2(nodes, Diagnostics.Type_parameter_declarations_can_only_be_used_in_TypeScript_files));
              return "skip";
            }
          case 243 /* VariableStatement */:
            if (nodes === parent.modifiers) {
              checkModifiers(parent.modifiers, parent.kind === 243 /* VariableStatement */);
              return "skip";
            }
            break;
          case 172 /* PropertyDeclaration */:
            if (nodes === parent.modifiers) {
              for (const modifier of nodes) {
                if (isModifier(modifier) && modifier.kind !== 126 /* StaticKeyword */ && modifier.kind !== 129 /* AccessorKeyword */) {
                  diagnostics.push(createDiagnosticForNode2(modifier, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, tokenToString(modifier.kind)));
                }
              }
              return "skip";
            }
            break;
          case 169 /* Parameter */:
            if (nodes === parent.modifiers && some(nodes, isModifier)) {
              diagnostics.push(createDiagnosticForNodeArray2(nodes, Diagnostics.Parameter_modifiers_can_only_be_used_in_TypeScript_files));
              return "skip";
            }
            break;
          case 213 /* CallExpression */:
          case 214 /* NewExpression */:
          case 233 /* ExpressionWithTypeArguments */:
          case 285 /* JsxSelfClosingElement */:
          case 286 /* JsxOpeningElement */:
          case 215 /* TaggedTemplateExpression */:
            if (nodes === parent.typeArguments) {
              diagnostics.push(createDiagnosticForNodeArray2(nodes, Diagnostics.Type_arguments_can_only_be_used_in_TypeScript_files));
              return "skip";
            }
            break;
        }
      }
      function checkModifiers(modifiers, isConstValid) {
        for (const modifier of modifiers) {
          switch (modifier.kind) {
            case 87 /* ConstKeyword */:
              if (isConstValid) {
                continue;
              }
            case 125 /* PublicKeyword */:
            case 123 /* PrivateKeyword */:
            case 124 /* ProtectedKeyword */:
            case 148 /* ReadonlyKeyword */:
            case 138 /* DeclareKeyword */:
            case 128 /* AbstractKeyword */:
            case 164 /* OverrideKeyword */:
            case 103 /* InKeyword */:
            case 147 /* OutKeyword */:
              diagnostics.push(createDiagnosticForNode2(modifier, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, tokenToString(modifier.kind)));
              break;
            case 126 /* StaticKeyword */:
            case 95 /* ExportKeyword */:
            case 90 /* DefaultKeyword */:
            case 129 /* AccessorKeyword */:
          }
        }
      }
      function createDiagnosticForNodeArray2(nodes, message, ...args) {
        const start = nodes.pos;
        return createFileDiagnostic(sourceFile, start, nodes.end - start, message, ...args);
      }
      function createDiagnosticForNode2(node, message, ...args) {
        return createDiagnosticForNodeInSourceFile(sourceFile, node, message, ...args);
      }
    });
  }
  function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) {
    return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
  }
  function getDeclarationDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
    return runWithCancellationToken(() => {
      const resolver = getTypeChecker().getEmitResolver(sourceFile, cancellationToken);
      return getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile) || emptyArray;
    });
  }
  function getAndCacheDiagnostics(sourceFile, cancellationToken, cache, getDiagnostics) {
    var _a2;
    const cachedResult = sourceFile ? (_a2 = cache.perFile) == null ? void 0 : _a2.get(sourceFile.path) : cache.allDiagnostics;
    if (cachedResult) {
      return cachedResult;
    }
    const result = getDiagnostics(sourceFile, cancellationToken);
    if (sourceFile) {
      (cache.perFile || (cache.perFile = /* @__PURE__ */ new Map())).set(sourceFile.path, result);
    } else {
      cache.allDiagnostics = result;
    }
    return result;
  }
  function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) {
    return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
  }
  function getOptionsDiagnostics() {
    return sortAndDeduplicateDiagnostics(concatenate(
      updateAndGetProgramDiagnostics().getGlobalDiagnostics(),
      getOptionsDiagnosticsOfConfigFile()
    ));
  }
  function getOptionsDiagnosticsOfConfigFile() {
    if (!options.configFile) return emptyArray;
    let diagnostics = updateAndGetProgramDiagnostics().getDiagnostics(options.configFile.fileName);
    forEachResolvedProjectReference2((resolvedRef) => {
      diagnostics = concatenate(diagnostics, updateAndGetProgramDiagnostics().getDiagnostics(resolvedRef.sourceFile.fileName));
    });
    return diagnostics;
  }
  function getGlobalDiagnostics() {
    return rootNames.length ? sortAndDeduplicateDiagnostics(getTypeChecker().getGlobalDiagnostics().slice()) : emptyArray;
  }
  function getConfigFileParsingDiagnostics2() {
    return configFileParsingDiagnostics || emptyArray;
  }
  function processRootFile(fileName, isDefaultLib, ignoreNoDefaultLib, reason) {
    processSourceFile(
      normalizePath(fileName),
      isDefaultLib,
      ignoreNoDefaultLib,
      /*packageId*/
      void 0,
      reason
    );
  }
  function fileReferenceIsEqualTo(a, b) {
    return a.fileName === b.fileName;
  }
  function moduleNameIsEqualTo(a, b) {
    return a.kind === 80 /* Identifier */ ? b.kind === 80 /* Identifier */ && a.escapedText === b.escapedText : b.kind === 11 /* StringLiteral */ && a.text === b.text;
  }
  function createSyntheticImport(text, file) {
    const externalHelpersModuleReference = factory.createStringLiteral(text);
    const importDecl = factory.createImportDeclaration(
      /*modifiers*/
      void 0,
      /*importClause*/
      void 0,
      externalHelpersModuleReference
    );
    addInternalEmitFlags(importDecl, 2 /* NeverApplyImportHelper */);
    setParent(externalHelpersModuleReference, importDecl);
    setParent(importDecl, file);
    externalHelpersModuleReference.flags &= ~16 /* Synthesized */;
    importDecl.flags &= ~16 /* Synthesized */;
    return externalHelpersModuleReference;
  }
  function collectExternalModuleReferences(file) {
    if (file.imports) {
      return;
    }
    const isJavaScriptFile = isSourceFileJS(file);
    const isExternalModuleFile = isExternalModule(file);
    let imports;
    let moduleAugmentations;
    let ambientModules;
    if (isJavaScriptFile || !file.isDeclarationFile && (getIsolatedModules(options) || isExternalModule(file))) {
      if (options.importHelpers) {
        imports = [createSyntheticImport(externalHelpersModuleNameText, file)];
      }
      const jsxImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options);
      if (jsxImport) {
        (imports || (imports = [])).push(createSyntheticImport(jsxImport, file));
      }
    }
    for (const node of file.statements) {
      collectModuleReferences(
        node,
        /*inAmbientModule*/
        false
      );
    }
    if (file.flags & 4194304 /* PossiblyContainsDynamicImport */ || isJavaScriptFile) {
      collectDynamicImportOrRequireOrJsDocImportCalls(file);
    }
    file.imports = imports || emptyArray;
    file.moduleAugmentations = moduleAugmentations || emptyArray;
    file.ambientModuleNames = ambientModules || emptyArray;
    return;
    function collectModuleReferences(node, inAmbientModule) {
      if (isAnyImportOrReExport(node)) {
        const moduleNameExpr = getExternalModuleName(node);
        if (moduleNameExpr && isStringLiteral(moduleNameExpr) && moduleNameExpr.text && (!inAmbientModule || !isExternalModuleNameRelative(moduleNameExpr.text))) {
          setParentRecursive(
            node,
            /*incremental*/
            false
          );
          imports = append(imports, moduleNameExpr);
          if (!usesUriStyleNodeCoreModules && currentNodeModulesDepth === 0 && !file.isDeclarationFile) {
            usesUriStyleNodeCoreModules = startsWith(moduleNameExpr.text, "node:");
          }
        }
      } else if (isModuleDeclaration(node)) {
        if (isAmbientModule(node) && (inAmbientModule || hasSyntacticModifier(node, 128 /* Ambient */) || file.isDeclarationFile)) {
          node.name.parent = node;
          const nameText = getTextOfIdentifierOrLiteral(node.name);
          if (isExternalModuleFile || inAmbientModule && !isExternalModuleNameRelative(nameText)) {
            (moduleAugmentations || (moduleAugmentations = [])).push(node.name);
          } else if (!inAmbientModule) {
            if (file.isDeclarationFile) {
              (ambientModules || (ambientModules = [])).push(nameText);
            }
            const body = node.body;
            if (body) {
              for (const statement of body.statements) {
                collectModuleReferences(
                  statement,
                  /*inAmbientModule*/
                  true
                );
              }
            }
          }
        }
      }
    }
    function collectDynamicImportOrRequireOrJsDocImportCalls(file2) {
      const r = /import|require/g;
      while (r.exec(file2.text) !== null) {
        const node = getNodeAtPosition(file2, r.lastIndex);
        if (isJavaScriptFile && isRequireCall(
          node,
          /*requireStringLiteralLikeArgument*/
          true
        )) {
          setParentRecursive(
            node,
            /*incremental*/
            false
          );
          imports = append(imports, node.arguments[0]);
        } else if (isImportCall(node) && node.arguments.length >= 1 && isStringLiteralLike(node.arguments[0])) {
          setParentRecursive(
            node,
            /*incremental*/
            false
          );
          imports = append(imports, node.arguments[0]);
        } else if (isLiteralImportTypeNode(node)) {
          setParentRecursive(
            node,
            /*incremental*/
            false
          );
          imports = append(imports, node.argument.literal);
        } else if (isJavaScriptFile && isJSDocImportTag(node)) {
          const moduleNameExpr = getExternalModuleName(node);
          if (moduleNameExpr && isStringLiteral(moduleNameExpr) && moduleNameExpr.text) {
            setParentRecursive(
              node,
              /*incremental*/
              false
            );
            imports = append(imports, moduleNameExpr);
          }
        }
      }
    }
    function getNodeAtPosition(sourceFile, position) {
      let current = sourceFile;
      const getContainingChild = (child) => {
        if (child.pos <= position && (position < child.end || position === child.end && child.kind === 1 /* EndOfFileToken */)) {
          return child;
        }
      };
      while (true) {
        const child = isJavaScriptFile && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild);
        if (!child) {
          return current;
        }
        current = child;
      }
    }
  }
  function getLibFileFromReference(ref) {
    var _a2;
    const libFileName = getLibFileNameFromLibReference(ref);
    const actualFileName = libFileName && ((_a2 = resolvedLibReferences == null ? void 0 : resolvedLibReferences.get(libFileName)) == null ? void 0 : _a2.actual);
    return actualFileName !== void 0 ? getSourceFile(actualFileName) : void 0;
  }
  function getSourceFileFromReference(referencingFile, ref) {
    return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), getSourceFile);
  }
  function getSourceFileFromReferenceWorker(fileName, getSourceFile2, fail, reason) {
    if (hasExtension(fileName)) {
      const canonicalFileName = host.getCanonicalFileName(fileName);
      if (!options.allowNonTsExtensions && !forEach(flatten(supportedExtensionsWithJsonIfResolveJsonModule), (extension) => fileExtensionIs(canonicalFileName, extension))) {
        if (fail) {
          if (hasJSFileExtension(canonicalFileName)) {
            fail(Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName);
          } else {
            fail(Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'");
          }
        }
        return void 0;
      }
      const sourceFile = getSourceFile2(fileName);
      if (fail) {
        if (!sourceFile) {
          const redirect = getProjectReferenceRedirect(fileName);
          if (redirect) {
            fail(Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, fileName);
          } else {
            fail(Diagnostics.File_0_not_found, fileName);
          }
        } else if (isReferencedFile(reason) && canonicalFileName === host.getCanonicalFileName(getSourceFileByPath(reason.file).fileName)) {
          fail(Diagnostics.A_file_cannot_have_a_reference_to_itself);
        }
      }
      return sourceFile;
    } else {
      const sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile2(fileName);
      if (sourceFileNoExtension) return sourceFileNoExtension;
      if (fail && options.allowNonTsExtensions) {
        fail(Diagnostics.File_0_not_found, fileName);
        return void 0;
      }
      const sourceFileWithAddedExtension = forEach(supportedExtensions[0], (extension) => getSourceFile2(fileName + extension));
      if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'");
      return sourceFileWithAddedExtension;
    }
  }
  function processSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, packageId, reason) {
    getSourceFileFromReferenceWorker(
      fileName,
      (fileName2) => findSourceFile(fileName2, isDefaultLib, ignoreNoDefaultLib, reason, packageId),
      // TODO: GH#18217
      (diagnostic, ...args) => addFilePreprocessingFileExplainingDiagnostic(
        /*file*/
        void 0,
        reason,
        diagnostic,
        args
      ),
      reason
    );
  }
  function processProjectReferenceFile(fileName, reason) {
    return processSourceFile(
      fileName,
      /*isDefaultLib*/
      false,
      /*ignoreNoDefaultLib*/
      false,
      /*packageId*/
      void 0,
      reason
    );
  }
  function reportFileNamesDifferOnlyInCasingError(fileName, existingFile, reason) {
    const hasExistingReasonToReportErrorOn = !isReferencedFile(reason) && some(fileReasons.get(existingFile.path), isReferencedFile);
    if (hasExistingReasonToReportErrorOn) {
      addFilePreprocessingFileExplainingDiagnostic(existingFile, reason, Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, [existingFile.fileName, fileName]);
    } else {
      addFilePreprocessingFileExplainingDiagnostic(existingFile, reason, Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, [fileName, existingFile.fileName]);
    }
  }
  function createRedirectedSourceFile(redirectTarget, unredirected, fileName, path, resolvedPath, originalFileName, sourceFileOptions) {
    var _a2;
    const redirect = parseNodeFactory.createRedirectedSourceFile({ redirectTarget, unredirected });
    redirect.fileName = fileName;
    redirect.path = path;
    redirect.resolvedPath = resolvedPath;
    redirect.originalFileName = originalFileName;
    redirect.packageJsonLocations = ((_a2 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a2.length) ? sourceFileOptions.packageJsonLocations : void 0;
    redirect.packageJsonScope = sourceFileOptions.packageJsonScope;
    sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
    return redirect;
  }
  function findSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId) {
    var _a2, _b2;
    (_a2 = tracing) == null ? void 0 : _a2.push(tracing.Phase.Program, "findSourceFile", {
      fileName,
      isDefaultLib: isDefaultLib || void 0,
      fileIncludeKind: FileIncludeKind[reason.kind]
    });
    const result = findSourceFileWorker(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId);
    (_b2 = tracing) == null ? void 0 : _b2.pop();
    return result;
  }
  function getCreateSourceFileOptions(fileName, moduleResolutionCache2, host2, options2) {
    const result = getImpliedNodeFormatForFileWorker(getNormalizedAbsolutePath(fileName, currentDirectory), moduleResolutionCache2 == null ? void 0 : moduleResolutionCache2.getPackageJsonInfoCache(), host2, options2);
    const languageVersion = getEmitScriptTarget(options2);
    const setExternalModuleIndicator2 = getSetExternalModuleIndicator(options2);
    return typeof result === "object" ? { ...result, languageVersion, setExternalModuleIndicator: setExternalModuleIndicator2, jsDocParsingMode: host2.jsDocParsingMode } : { languageVersion, impliedNodeFormat: result, setExternalModuleIndicator: setExternalModuleIndicator2, jsDocParsingMode: host2.jsDocParsingMode };
  }
  function findSourceFileWorker(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId) {
    var _a2;
    const path = toPath3(fileName);
    if (useSourceOfProjectReferenceRedirect) {
      let source = getSourceOfProjectReferenceRedirect(path);
      if (!source && host.realpath && options.preserveSymlinks && isDeclarationFileName(fileName) && fileName.includes(nodeModulesPathPart)) {
        const realPath2 = toPath3(host.realpath(fileName));
        if (realPath2 !== path) source = getSourceOfProjectReferenceRedirect(realPath2);
      }
      if (source) {
        const file2 = isString(source) ? findSourceFile(source, isDefaultLib, ignoreNoDefaultLib, reason, packageId) : void 0;
        if (file2) addFileToFilesByName(
          file2,
          path,
          fileName,
          /*redirectedPath*/
          void 0
        );
        return file2;
      }
    }
    const originalFileName = fileName;
    if (filesByName.has(path)) {
      const file2 = filesByName.get(path);
      const addedReason = addFileIncludeReason(
        file2 || void 0,
        reason,
        /*checkExisting*/
        true
      );
      if (file2 && addedReason && !(options.forceConsistentCasingInFileNames === false)) {
        const checkedName = file2.fileName;
        const isRedirect = toPath3(checkedName) !== toPath3(fileName);
        if (isRedirect) {
          fileName = getProjectReferenceRedirect(fileName) || fileName;
        }
        const checkedAbsolutePath = getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory);
        const inputAbsolutePath = getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory);
        if (checkedAbsolutePath !== inputAbsolutePath) {
          reportFileNamesDifferOnlyInCasingError(fileName, file2, reason);
        }
      }
      if (file2 && sourceFilesFoundSearchingNodeModules.get(file2.path) && currentNodeModulesDepth === 0) {
        sourceFilesFoundSearchingNodeModules.set(file2.path, false);
        if (!options.noResolve) {
          processReferencedFiles(file2, isDefaultLib);
          processTypeReferenceDirectives(file2);
        }
        if (!options.noLib) {
          processLibReferenceDirectives(file2);
        }
        modulesWithElidedImports.set(file2.path, false);
        processImportedModules(file2);
      } else if (file2 && modulesWithElidedImports.get(file2.path)) {
        if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
          modulesWithElidedImports.set(file2.path, false);
          processImportedModules(file2);
        }
      }
      return file2 || void 0;
    }
    let redirectedPath;
    if (!useSourceOfProjectReferenceRedirect) {
      const redirectProject = getProjectReferenceRedirectProject(fileName);
      if (redirectProject) {
        if (redirectProject.commandLine.options.outFile) {
          return void 0;
        }
        const redirect = getProjectReferenceOutputName(redirectProject, fileName);
        fileName = redirect;
        redirectedPath = toPath3(redirect);
      }
    }
    const sourceFileOptions = getCreateSourceFileOptions(fileName, moduleResolutionCache, host, options);
    const file = host.getSourceFile(
      fileName,
      sourceFileOptions,
      (hostErrorMessage) => addFilePreprocessingFileExplainingDiagnostic(
        /*file*/
        void 0,
        reason,
        Diagnostics.Cannot_read_file_0_Colon_1,
        [fileName, hostErrorMessage]
      ),
      shouldCreateNewSourceFile
    );
    if (packageId) {
      const packageIdKey = packageIdToString(packageId);
      const fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
      if (fileFromPackageId) {
        const dupFile = createRedirectedSourceFile(fileFromPackageId, file, fileName, path, toPath3(fileName), originalFileName, sourceFileOptions);
        redirectTargetsMap.add(fileFromPackageId.path, fileName);
        addFileToFilesByName(dupFile, path, fileName, redirectedPath);
        addFileIncludeReason(
          dupFile,
          reason,
          /*checkExisting*/
          false
        );
        sourceFileToPackageName.set(path, packageIdToPackageName(packageId));
        processingOtherFiles.push(dupFile);
        return dupFile;
      } else if (file) {
        packageIdToSourceFile.set(packageIdKey, file);
        sourceFileToPackageName.set(path, packageIdToPackageName(packageId));
      }
    }
    addFileToFilesByName(file, path, fileName, redirectedPath);
    if (file) {
      sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
      file.fileName = fileName;
      file.path = path;
      file.resolvedPath = toPath3(fileName);
      file.originalFileName = originalFileName;
      file.packageJsonLocations = ((_a2 = sourceFileOptions.packageJsonLocations) == null ? void 0 : _a2.length) ? sourceFileOptions.packageJsonLocations : void 0;
      file.packageJsonScope = sourceFileOptions.packageJsonScope;
      addFileIncludeReason(
        file,
        reason,
        /*checkExisting*/
        false
      );
      if (host.useCaseSensitiveFileNames()) {
        const pathLowerCase = toFileNameLowerCase(path);
        const existingFile = filesByNameIgnoreCase.get(pathLowerCase);
        if (existingFile) {
          reportFileNamesDifferOnlyInCasingError(fileName, existingFile, reason);
        } else {
          filesByNameIgnoreCase.set(pathLowerCase, file);
        }
      }
      skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib && !ignoreNoDefaultLib;
      if (!options.noResolve) {
        processReferencedFiles(file, isDefaultLib);
        processTypeReferenceDirectives(file);
      }
      if (!options.noLib) {
        processLibReferenceDirectives(file);
      }
      processImportedModules(file);
      if (isDefaultLib) {
        processingDefaultLibFiles.push(file);
      } else {
        processingOtherFiles.push(file);
      }
      (filesWithReferencesProcessed ?? (filesWithReferencesProcessed = /* @__PURE__ */ new Set())).add(file.path);
    }
    return file;
  }
  function addFileIncludeReason(file, reason, checkExisting) {
    if (file && (!checkExisting || !isReferencedFile(reason) || !(filesWithReferencesProcessed == null ? void 0 : filesWithReferencesProcessed.has(reason.file)))) {
      fileReasons.add(file.path, reason);
      return true;
    }
    return false;
  }
  function addFileToFilesByName(file, path, fileName, redirectedPath) {
    if (redirectedPath) {
      updateFilesByNameMap(fileName, redirectedPath, file);
      updateFilesByNameMap(fileName, path, file || false);
    } else {
      updateFilesByNameMap(fileName, path, file);
    }
  }
  function updateFilesByNameMap(fileName, path, file) {
    filesByName.set(path, file);
    if (file !== void 0) missingFileNames.delete(path);
    else missingFileNames.set(path, fileName);
  }
  function getProjectReferenceRedirect(fileName) {
    const referencedProject = getProjectReferenceRedirectProject(fileName);
    return referencedProject && getProjectReferenceOutputName(referencedProject, fileName);
  }
  function getProjectReferenceRedirectProject(fileName) {
    if (!resolvedProjectReferences || !resolvedProjectReferences.length || isDeclarationFileName(fileName) || fileExtensionIs(fileName, ".json" /* Json */)) {
      return void 0;
    }
    return getResolvedProjectReferenceToRedirect(fileName);
  }
  function getProjectReferenceOutputName(referencedProject, fileName) {
    const out = referencedProject.commandLine.options.outFile;
    return out ? changeExtension(out, ".d.ts" /* Dts */) : getOutputDeclarationFileName(fileName, referencedProject.commandLine, !host.useCaseSensitiveFileNames());
  }
  function getResolvedProjectReferenceToRedirect(fileName) {
    if (mapFromFileToProjectReferenceRedirects === void 0) {
      mapFromFileToProjectReferenceRedirects = /* @__PURE__ */ new Map();
      forEachResolvedProjectReference2((referencedProject) => {
        if (toPath3(options.configFilePath) !== referencedProject.sourceFile.path) {
          referencedProject.commandLine.fileNames.forEach((f) => mapFromFileToProjectReferenceRedirects.set(toPath3(f), referencedProject.sourceFile.path));
        }
      });
    }
    const referencedProjectPath = mapFromFileToProjectReferenceRedirects.get(toPath3(fileName));
    return referencedProjectPath && getResolvedProjectReferenceByPath(referencedProjectPath);
  }
  function forEachResolvedProjectReference2(cb) {
    return forEachResolvedProjectReference(resolvedProjectReferences, cb);
  }
  function getSourceOfProjectReferenceRedirect(path) {
    if (!isDeclarationFileName(path)) return void 0;
    if (mapFromToProjectReferenceRedirectSource === void 0) {
      mapFromToProjectReferenceRedirectSource = /* @__PURE__ */ new Map();
      forEachResolvedProjectReference2((resolvedRef) => {
        const out = resolvedRef.commandLine.options.outFile;
        if (out) {
          const outputDts = changeExtension(out, ".d.ts" /* Dts */);
          mapFromToProjectReferenceRedirectSource.set(toPath3(outputDts), true);
        } else {
          const getCommonSourceDirectory3 = memoize(() => getCommonSourceDirectoryOfConfig(resolvedRef.commandLine, !host.useCaseSensitiveFileNames()));
          forEach(resolvedRef.commandLine.fileNames, (fileName) => {
            if (!isDeclarationFileName(fileName) && !fileExtensionIs(fileName, ".json" /* Json */)) {
              const outputDts = getOutputDeclarationFileName(fileName, resolvedRef.commandLine, !host.useCaseSensitiveFileNames(), getCommonSourceDirectory3);
              mapFromToProjectReferenceRedirectSource.set(toPath3(outputDts), fileName);
            }
          });
        }
      });
    }
    return mapFromToProjectReferenceRedirectSource.get(path);
  }
  function isSourceOfProjectReferenceRedirect(fileName) {
    return useSourceOfProjectReferenceRedirect && !!getResolvedProjectReferenceToRedirect(fileName);
  }
  function getResolvedProjectReferenceByPath(projectReferencePath) {
    if (!projectReferenceRedirects) {
      return void 0;
    }
    return projectReferenceRedirects.get(projectReferencePath) || void 0;
  }
  function processReferencedFiles(file, isDefaultLib) {
    forEach(file.referencedFiles, (ref, index) => {
      processSourceFile(
        resolveTripleslashReference(ref.fileName, file.fileName),
        isDefaultLib,
        /*ignoreNoDefaultLib*/
        false,
        /*packageId*/
        void 0,
        { kind: 4 /* ReferenceFile */, file: file.path, index }
      );
    });
  }
  function processTypeReferenceDirectives(file) {
    const typeDirectives = file.typeReferenceDirectives;
    if (!typeDirectives.length) return;
    const resolutions = (resolvedTypeReferenceDirectiveNamesProcessing == null ? void 0 : resolvedTypeReferenceDirectiveNamesProcessing.get(file.path)) || resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectives, file);
    const resolutionsInFile = createModeAwareCache();
    (resolvedTypeReferenceDirectiveNames ?? (resolvedTypeReferenceDirectiveNames = /* @__PURE__ */ new Map())).set(file.path, resolutionsInFile);
    for (let index = 0; index < typeDirectives.length; index++) {
      const ref = file.typeReferenceDirectives[index];
      const resolvedTypeReferenceDirective = resolutions[index];
      const fileName = ref.fileName;
      resolutionsInFile.set(fileName, getModeForFileReference(ref, file.impliedNodeFormat), resolvedTypeReferenceDirective);
      const mode = ref.resolutionMode || file.impliedNodeFormat;
      processTypeReferenceDirective(fileName, mode, resolvedTypeReferenceDirective, { kind: 5 /* TypeReferenceDirective */, file: file.path, index });
    }
  }
  function processTypeReferenceDirective(typeReferenceDirective, mode, resolution, reason) {
    var _a2, _b2;
    (_a2 = tracing) == null ? void 0 : _a2.push(tracing.Phase.Program, "processTypeReferenceDirective", { directive: typeReferenceDirective, hasResolved: !!resolution.resolvedTypeReferenceDirective, refKind: reason.kind, refPath: isReferencedFile(reason) ? reason.file : void 0 });
    processTypeReferenceDirectiveWorker(typeReferenceDirective, mode, resolution, reason);
    (_b2 = tracing) == null ? void 0 : _b2.pop();
  }
  function processTypeReferenceDirectiveWorker(typeReferenceDirective, mode, resolution, reason) {
    addResolutionDiagnostics(resolution);
    const { resolvedTypeReferenceDirective } = resolution;
    if (resolvedTypeReferenceDirective) {
      if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth++;
      processSourceFile(
        resolvedTypeReferenceDirective.resolvedFileName,
        /*isDefaultLib*/
        false,
        /*ignoreNoDefaultLib*/
        false,
        resolvedTypeReferenceDirective.packageId,
        reason
      );
      if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--;
    } else {
      addFilePreprocessingFileExplainingDiagnostic(
        /*file*/
        void 0,
        reason,
        Diagnostics.Cannot_find_type_definition_file_for_0,
        [typeReferenceDirective]
      );
    }
  }
  function pathForLibFile(libFileName) {
    const existing = resolvedLibReferences == null ? void 0 : resolvedLibReferences.get(libFileName);
    if (existing) return existing.actual;
    const result = pathForLibFileWorker(libFileName);
    (resolvedLibReferences ?? (resolvedLibReferences = /* @__PURE__ */ new Map())).set(libFileName, result);
    return result.actual;
  }
  function pathForLibFileWorker(libFileName) {
    var _a2, _b2, _c2, _d2, _e2;
    const existing = resolvedLibProcessing == null ? void 0 : resolvedLibProcessing.get(libFileName);
    if (existing) return existing;
    if (structureIsReused !== 0 /* Not */ && oldProgram && !hasInvalidatedLibResolutions(libFileName)) {
      const oldResolution = (_a2 = oldProgram.resolvedLibReferences) == null ? void 0 : _a2.get(libFileName);
      if (oldResolution) {
        if (oldResolution.resolution && isTraceEnabled(options, host)) {
          const libraryName2 = getLibraryNameFromLibFileName(libFileName);
          const resolveFrom2 = getInferredLibraryNameResolveFrom(options, currentDirectory, libFileName);
          trace(
            host,
            oldResolution.resolution.resolvedModule ? oldResolution.resolution.resolvedModule.packageId ? Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_not_resolved,
            libraryName2,
            getNormalizedAbsolutePath(resolveFrom2, currentDirectory),
            (_b2 = oldResolution.resolution.resolvedModule) == null ? void 0 : _b2.resolvedFileName,
            ((_c2 = oldResolution.resolution.resolvedModule) == null ? void 0 : _c2.packageId) && packageIdToString(oldResolution.resolution.resolvedModule.packageId)
          );
        }
        (resolvedLibProcessing ?? (resolvedLibProcessing = /* @__PURE__ */ new Map())).set(libFileName, oldResolution);
        return oldResolution;
      }
    }
    const libraryName = getLibraryNameFromLibFileName(libFileName);
    const resolveFrom = getInferredLibraryNameResolveFrom(options, currentDirectory, libFileName);
    (_d2 = tracing) == null ? void 0 : _d2.push(tracing.Phase.Program, "resolveLibrary", { resolveFrom });
    mark("beforeResolveLibrary");
    const resolution = actualResolveLibrary(libraryName, resolveFrom, options, libFileName);
    mark("afterResolveLibrary");
    measure("ResolveLibrary", "beforeResolveLibrary", "afterResolveLibrary");
    (_e2 = tracing) == null ? void 0 : _e2.pop();
    const result = {
      resolution,
      actual: resolution.resolvedModule ? resolution.resolvedModule.resolvedFileName : combinePaths(defaultLibraryPath, libFileName)
    };
    (resolvedLibProcessing ?? (resolvedLibProcessing = /* @__PURE__ */ new Map())).set(libFileName, result);
    return result;
  }
  function processLibReferenceDirectives(file) {
    forEach(file.libReferenceDirectives, (libReference, index) => {
      const libFileName = getLibFileNameFromLibReference(libReference);
      if (libFileName) {
        processRootFile(
          pathForLibFile(libFileName),
          /*isDefaultLib*/
          true,
          /*ignoreNoDefaultLib*/
          true,
          { kind: 7 /* LibReferenceDirective */, file: file.path, index }
        );
      } else {
        (fileProcessingDiagnostics || (fileProcessingDiagnostics = [])).push({
          kind: 0 /* FilePreprocessingLibReferenceDiagnostic */,
          reason: { kind: 7 /* LibReferenceDirective */, file: file.path, index }
        });
      }
    });
  }
  function getCanonicalFileName(fileName) {
    return host.getCanonicalFileName(fileName);
  }
  function processImportedModules(file) {
    var _a2;
    collectExternalModuleReferences(file);
    if (file.imports.length || file.moduleAugmentations.length) {
      const moduleNames = getModuleNames(file);
      const resolutions = (resolvedModulesProcessing == null ? void 0 : resolvedModulesProcessing.get(file.path)) || resolveModuleNamesReusingOldState(moduleNames, file);
      Debug.assert(resolutions.length === moduleNames.length);
      const optionsForFile = ((_a2 = getRedirectReferenceForResolution(file)) == null ? void 0 : _a2.commandLine.options) || options;
      const resolutionsInFile = createModeAwareCache();
      (resolvedModules ?? (resolvedModules = /* @__PURE__ */ new Map())).set(file.path, resolutionsInFile);
      for (let index = 0; index < moduleNames.length; index++) {
        const resolution = resolutions[index].resolvedModule;
        const moduleName = moduleNames[index].text;
        const mode = getModeForUsageLocationWorker(file, moduleNames[index], optionsForFile);
        resolutionsInFile.set(moduleName, mode, resolutions[index]);
        addResolutionDiagnosticsFromResolutionOrCache(file, moduleName, resolutions[index], mode);
        if (!resolution) {
          continue;
        }
        const isFromNodeModulesSearch = resolution.isExternalLibraryImport;
        const isJsFile = !resolutionExtensionIsTSOrJson(resolution.extension) && !getProjectReferenceRedirectProject(resolution.resolvedFileName);
        const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile && (!resolution.originalPath || pathContainsNodeModules(resolution.resolvedFileName));
        const resolvedFileName = resolution.resolvedFileName;
        if (isFromNodeModulesSearch) {
          currentNodeModulesDepth++;
        }
        const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
        const shouldAddFile = resolvedFileName && !getResolutionDiagnostic(optionsForFile, resolution, file) && !optionsForFile.noResolve && index < file.imports.length && !elideImport && !(isJsFile && !getAllowJSCompilerOption(optionsForFile)) && (isInJSFile(file.imports[index]) || !(file.imports[index].flags & 16777216 /* JSDoc */));
        if (elideImport) {
          modulesWithElidedImports.set(file.path, true);
        } else if (shouldAddFile) {
          findSourceFile(
            resolvedFileName,
            /*isDefaultLib*/
            false,
            /*ignoreNoDefaultLib*/
            false,
            { kind: 3 /* Import */, file: file.path, index },
            resolution.packageId
          );
        }
        if (isFromNodeModulesSearch) {
          currentNodeModulesDepth--;
        }
      }
    }
  }
  function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
    let allFilesBelongToPath = true;
    const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
    for (const sourceFile of sourceFiles) {
      if (!sourceFile.isDeclarationFile) {
        const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
        if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
          addLazyProgramDiagnosticExplainingFile(
            sourceFile,
            Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files,
            [sourceFile.fileName, rootDirectory]
          );
          allFilesBelongToPath = false;
        }
      }
    }
    return allFilesBelongToPath;
  }
  function parseProjectReferenceConfigFile(ref) {
    if (!projectReferenceRedirects) {
      projectReferenceRedirects = /* @__PURE__ */ new Map();
    }
    const refPath = resolveProjectReferencePath(ref);
    const sourceFilePath = toPath3(refPath);
    const fromCache = projectReferenceRedirects.get(sourceFilePath);
    if (fromCache !== void 0) {
      return fromCache || void 0;
    }
    let commandLine;
    let sourceFile;
    if (host.getParsedCommandLine) {
      commandLine = host.getParsedCommandLine(refPath);
      if (!commandLine) {
        addFileToFilesByName(
          /*file*/
          void 0,
          sourceFilePath,
          refPath,
          /*redirectedPath*/
          void 0
        );
        projectReferenceRedirects.set(sourceFilePath, false);
        return void 0;
      }
      sourceFile = Debug.checkDefined(commandLine.options.configFile);
      Debug.assert(!sourceFile.path || sourceFile.path === sourceFilePath);
      addFileToFilesByName(
        sourceFile,
        sourceFilePath,
        refPath,
        /*redirectedPath*/
        void 0
      );
    } else {
      const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), currentDirectory);
      sourceFile = host.getSourceFile(refPath, 100 /* JSON */);
      addFileToFilesByName(
        sourceFile,
        sourceFilePath,
        refPath,
        /*redirectedPath*/
        void 0
      );
      if (sourceFile === void 0) {
        projectReferenceRedirects.set(sourceFilePath, false);
        return void 0;
      }
      commandLine = parseJsonSourceFileConfigFileContent(
        sourceFile,
        configParsingHost,
        basePath,
        /*existingOptions*/
        void 0,
        refPath
      );
    }
    sourceFile.fileName = refPath;
    sourceFile.path = sourceFilePath;
    sourceFile.resolvedPath = sourceFilePath;
    sourceFile.originalFileName = refPath;
    const resolvedRef = { commandLine, sourceFile };
    projectReferenceRedirects.set(sourceFilePath, resolvedRef);
    if (commandLine.projectReferences) {
      resolvedRef.references = commandLine.projectReferences.map(parseProjectReferenceConfigFile);
    }
    return resolvedRef;
  }
  function verifyCompilerOptions() {
    if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) {
      createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
    }
    if (options.exactOptionalPropertyTypes && !getStrictOptionValue(options, "strictNullChecks")) {
      createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "exactOptionalPropertyTypes", "strictNullChecks");
    }
    if (options.isolatedModules || options.verbatimModuleSyntax) {
      if (options.outFile) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", options.verbatimModuleSyntax ? "verbatimModuleSyntax" : "isolatedModules");
      }
    }
    if (options.isolatedDeclarations) {
      if (getAllowJSCompilerOption(options)) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "isolatedDeclarations");
      }
      if (!getEmitDeclarations(options)) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "isolatedDeclarations", "declaration", "composite");
      }
    }
    if (options.inlineSourceMap) {
      if (options.sourceMap) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
      }
      if (options.mapRoot) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
      }
    }
    if (options.composite) {
      if (options.declaration === false) {
        createDiagnosticForOptionName(Diagnostics.Composite_projects_may_not_disable_declaration_emit, "declaration");
      }
      if (options.incremental === false) {
        createDiagnosticForOptionName(Diagnostics.Composite_projects_may_not_disable_incremental_compilation, "declaration");
      }
    }
    const outputFile = options.outFile;
    if (options.tsBuildInfoFile) {
      if (!isIncrementalCompilation(options)) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite");
      }
    } else if (options.incremental && !outputFile && !options.configFilePath) {
      programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
    }
    verifyDeprecatedCompilerOptions();
    verifyProjectReferences();
    if (options.composite) {
      const rootPaths = new Set(rootNames.map(toPath3));
      for (const file of files) {
        if (sourceFileMayBeEmitted(file, program) && !rootPaths.has(file.path)) {
          addLazyProgramDiagnosticExplainingFile(
            file,
            Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern,
            [file.fileName, options.configFilePath || ""]
          );
        }
      }
    }
    if (options.paths) {
      for (const key in options.paths) {
        if (!hasProperty(options.paths, key)) {
          continue;
        }
        if (!hasZeroOrOneAsteriskCharacter(key)) {
          createDiagnosticForOptionPaths(
            /*onKey*/
            true,
            key,
            Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character,
            key
          );
        }
        if (isArray(options.paths[key])) {
          const len = options.paths[key].length;
          if (len === 0) {
            createDiagnosticForOptionPaths(
              /*onKey*/
              false,
              key,
              Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array,
              key
            );
          }
          for (let i = 0; i < len; i++) {
            const subst = options.paths[key][i];
            const typeOfSubst = typeof subst;
            if (typeOfSubst === "string") {
              if (!hasZeroOrOneAsteriskCharacter(subst)) {
                createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character, subst, key);
              }
              if (!options.baseUrl && !pathIsRelative(subst) && !pathIsAbsolute(subst)) {
                createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Non_relative_paths_are_not_allowed_when_baseUrl_is_not_set_Did_you_forget_a_leading_Slash);
              }
            } else {
              createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
            }
          }
        } else {
          createDiagnosticForOptionPaths(
            /*onKey*/
            false,
            key,
            Diagnostics.Substitutions_for_pattern_0_should_be_an_array,
            key
          );
        }
      }
    }
    if (!options.sourceMap && !options.inlineSourceMap) {
      if (options.inlineSources) {
        createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
      }
      if (options.sourceRoot) {
        createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
      }
    }
    if (options.mapRoot && !(options.sourceMap || options.declarationMap)) {
      createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "mapRoot", "sourceMap", "declarationMap");
    }
    if (options.declarationDir) {
      if (!getEmitDeclarations(options)) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite");
      }
      if (outputFile) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", "outFile");
      }
    }
    if (options.declarationMap && !getEmitDeclarations(options)) {
      createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite");
    }
    if (options.lib && options.noLib) {
      createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
    }
    const languageVersion = getEmitScriptTarget(options);
    const firstNonAmbientExternalModuleSourceFile = find(files, (f) => isExternalModule(f) && !f.isDeclarationFile);
    if (options.isolatedModules || options.verbatimModuleSyntax) {
      if (options.module === 0 /* None */ && languageVersion < 2 /* ES2015 */ && options.isolatedModules) {
        createDiagnosticForOptionName(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
      }
      if (options.preserveConstEnums === false) {
        createDiagnosticForOptionName(Diagnostics.Option_preserveConstEnums_cannot_be_disabled_when_0_is_enabled, options.verbatimModuleSyntax ? "verbatimModuleSyntax" : "isolatedModules", "preserveConstEnums");
      }
    } else if (firstNonAmbientExternalModuleSourceFile && languageVersion < 2 /* ES2015 */ && options.module === 0 /* None */) {
      const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, typeof firstNonAmbientExternalModuleSourceFile.externalModuleIndicator === "boolean" ? firstNonAmbientExternalModuleSourceFile : firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
      programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
    }
    if (outputFile && !options.emitDeclarationOnly) {
      if (options.module && !(options.module === 2 /* AMD */ || options.module === 4 /* System */)) {
        createDiagnosticForOptionName(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, "outFile", "module");
      } else if (options.module === void 0 && firstNonAmbientExternalModuleSourceFile) {
        const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, typeof firstNonAmbientExternalModuleSourceFile.externalModuleIndicator === "boolean" ? firstNonAmbientExternalModuleSourceFile : firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
        programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, "outFile"));
      }
    }
    if (getResolveJsonModule(options)) {
      if (getEmitModuleResolutionKind(options) === 1 /* Classic */) {
        createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_when_moduleResolution_is_set_to_classic, "resolveJsonModule");
      } else if (!hasJsonModuleEmitEnabled(options)) {
        createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_when_module_is_set_to_none_system_or_umd, "resolveJsonModule", "module");
      }
    }
    if (options.outDir || // there is --outDir specified
    options.rootDir || // there is --rootDir specified
    options.sourceRoot || // there is --sourceRoot specified
    options.mapRoot || // there is --mapRoot specified
    getEmitDeclarations(options) && options.declarationDir) {
      const dir = getCommonSourceDirectory2();
      if (options.outDir && dir === "" && files.some((file) => getRootLength(file.fileName) > 1)) {
        createDiagnosticForOptionName(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
      }
    }
    if (options.checkJs && !getAllowJSCompilerOption(options)) {
      createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs");
    }
    if (options.emitDeclarationOnly) {
      if (!getEmitDeclarations(options)) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite");
      }
      if (options.noEmit) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationOnly", "noEmit");
      }
    }
    if (options.noCheck) {
      if (options.noEmit) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noCheck", "noEmit");
      }
    }
    if (options.emitDecoratorMetadata && !options.experimentalDecorators) {
      createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
    }
    if (options.jsxFactory) {
      if (options.reactNamespace) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
      }
      if (options.jsx === 4 /* ReactJSX */ || options.jsx === 5 /* ReactJSXDev */) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxFactory", inverseJsxOptionMap.get("" + options.jsx));
      }
      if (!parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
        createOptionValueDiagnostic("jsxFactory", Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
      }
    } else if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) {
      createOptionValueDiagnostic("reactNamespace", Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
    }
    if (options.jsxFragmentFactory) {
      if (!options.jsxFactory) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "jsxFragmentFactory", "jsxFactory");
      }
      if (options.jsx === 4 /* ReactJSX */ || options.jsx === 5 /* ReactJSXDev */) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxFragmentFactory", inverseJsxOptionMap.get("" + options.jsx));
      }
      if (!parseIsolatedEntityName(options.jsxFragmentFactory, languageVersion)) {
        createOptionValueDiagnostic("jsxFragmentFactory", Diagnostics.Invalid_value_for_jsxFragmentFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFragmentFactory);
      }
    }
    if (options.reactNamespace) {
      if (options.jsx === 4 /* ReactJSX */ || options.jsx === 5 /* ReactJSXDev */) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "reactNamespace", inverseJsxOptionMap.get("" + options.jsx));
      }
    }
    if (options.jsxImportSource) {
      if (options.jsx === 2 /* React */) {
        createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxImportSource", inverseJsxOptionMap.get("" + options.jsx));
      }
    }
    const moduleKind = getEmitModuleKind(options);
    if (options.verbatimModuleSyntax) {
      if (moduleKind === 2 /* AMD */ || moduleKind === 3 /* UMD */ || moduleKind === 4 /* System */) {
        createDiagnosticForOptionName(Diagnostics.Option_verbatimModuleSyntax_cannot_be_used_when_module_is_set_to_UMD_AMD_or_System, "verbatimModuleSyntax");
      }
    }
    if (options.allowImportingTsExtensions && !(options.noEmit || options.emitDeclarationOnly)) {
      createOptionValueDiagnostic("allowImportingTsExtensions", Diagnostics.Option_allowImportingTsExtensions_can_only_be_used_when_either_noEmit_or_emitDeclarationOnly_is_set);
    }
    const moduleResolution = getEmitModuleResolutionKind(options);
    if (options.resolvePackageJsonExports && !moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) {
      createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler, "resolvePackageJsonExports");
    }
    if (options.resolvePackageJsonImports && !moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) {
      createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler, "resolvePackageJsonImports");
    }
    if (options.customConditions && !moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) {
      createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler, "customConditions");
    }
    if (moduleResolution === 100 /* Bundler */ && !emitModuleKindIsNonNodeESM(moduleKind) && moduleKind !== 200 /* Preserve */) {
      createOptionValueDiagnostic("moduleResolution", Diagnostics.Option_0_can_only_be_used_when_module_is_set_to_preserve_or_to_es2015_or_later, "bundler");
    }
    if (ModuleKind[moduleKind] && (100 /* Node16 */ <= moduleKind && moduleKind <= 199 /* NodeNext */) && !(3 /* Node16 */ <= moduleResolution && moduleResolution <= 99 /* NodeNext */)) {
      const moduleKindName = ModuleKind[moduleKind];
      createOptionValueDiagnostic("moduleResolution", Diagnostics.Option_moduleResolution_must_be_set_to_0_or_left_unspecified_when_option_module_is_set_to_1, moduleKindName, moduleKindName);
    } else if (ModuleResolutionKind[moduleResolution] && (3 /* Node16 */ <= moduleResolution && moduleResolution <= 99 /* NodeNext */) && !(100 /* Node16 */ <= moduleKind && moduleKind <= 199 /* NodeNext */)) {
      const moduleResolutionName = ModuleResolutionKind[moduleResolution];
      createOptionValueDiagnostic("module", Diagnostics.Option_module_must_be_set_to_0_when_option_moduleResolution_is_set_to_1, moduleResolutionName, moduleResolutionName);
    }
    if (!options.noEmit && !options.suppressOutputPathCheck) {
      const emitHost = getEmitHost();
      const emitFilesSeen = /* @__PURE__ */ new Set();
      forEachEmittedFile(emitHost, (emitFileNames) => {
        if (!options.emitDeclarationOnly) {
          verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
        }
        verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
      });
    }
    function verifyEmitFilePath(emitFileName, emitFilesSeen) {
      if (emitFileName) {
        const emitFilePath = toPath3(emitFileName);
        if (filesByName.has(emitFilePath)) {
          let chain;
          if (!options.configFilePath) {
            chain = chainDiagnosticMessages(
              /*details*/
              void 0,
              Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig
            );
          }
          chain = chainDiagnosticMessages(chain, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
          blockEmittingOfFile(emitFileName, createCompilerDiagnosticFromMessageChain(chain));
        }
        const emitFileKey = !host.useCaseSensitiveFileNames() ? toFileNameLowerCase(emitFilePath) : emitFilePath;
        if (emitFilesSeen.has(emitFileKey)) {
          blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
        } else {
          emitFilesSeen.add(emitFileKey);
        }
      }
    }
  }
  function getIgnoreDeprecationsVersion() {
    const ignoreDeprecations = options.ignoreDeprecations;
    if (ignoreDeprecations) {
      if (ignoreDeprecations === "5.0") {
        return new Version(ignoreDeprecations);
      }
      reportInvalidIgnoreDeprecations();
    }
    return Version.zero;
  }
  function checkDeprecations(deprecatedIn, stopsWorkingIn, removedIn, createDiagnostic, fn) {
    const deprecatedInVersion = new Version(deprecatedIn);
    const removedInVersion = new Version(removedIn);
    const typescriptVersion = new Version(typeScriptVersion2 || versionMajorMinor);
    const ignoreDeprecationsVersion = getIgnoreDeprecationsVersion();
    const mustBeRemoved = !(removedInVersion.compareTo(typescriptVersion) === 1 /* GreaterThan */);
    const canBeSilenced = !mustBeRemoved && ignoreDeprecationsVersion.compareTo(deprecatedInVersion) === -1 /* LessThan */;
    if (mustBeRemoved || canBeSilenced) {
      fn((name, value, useInstead) => {
        if (mustBeRemoved) {
          if (value === void 0) {
            createDiagnostic(name, value, useInstead, Diagnostics.Option_0_has_been_removed_Please_remove_it_from_your_configuration, name);
          } else {
            createDiagnostic(name, value, useInstead, Diagnostics.Option_0_1_has_been_removed_Please_remove_it_from_your_configuration, name, value);
          }
        } else {
          if (value === void 0) {
            createDiagnostic(name, value, useInstead, Diagnostics.Option_0_is_deprecated_and_will_stop_functioning_in_TypeScript_1_Specify_compilerOption_ignoreDeprecations_Colon_2_to_silence_this_error, name, stopsWorkingIn, deprecatedIn);
          } else {
            createDiagnostic(name, value, useInstead, Diagnostics.Option_0_1_is_deprecated_and_will_stop_functioning_in_TypeScript_2_Specify_compilerOption_ignoreDeprecations_Colon_3_to_silence_this_error, name, value, stopsWorkingIn, deprecatedIn);
          }
        }
      });
    }
  }
  function verifyDeprecatedCompilerOptions() {
    function createDiagnostic(name, value, useInstead, message, ...args) {
      if (useInstead) {
        const details = chainDiagnosticMessages(
          /*details*/
          void 0,
          Diagnostics.Use_0_instead,
          useInstead
        );
        const chain = chainDiagnosticMessages(details, message, ...args);
        createDiagnosticForOption(
          /*onKey*/
          !value,
          name,
          /*option2*/
          void 0,
          chain
        );
      } else {
        createDiagnosticForOption(
          /*onKey*/
          !value,
          name,
          /*option2*/
          void 0,
          message,
          ...args
        );
      }
    }
    checkDeprecations("5.0", "5.5", "6.0", createDiagnostic, (createDeprecatedDiagnostic) => {
      if (options.target === 0 /* ES3 */) {
        createDeprecatedDiagnostic("target", "ES3");
      }
      if (options.noImplicitUseStrict) {
        createDeprecatedDiagnostic("noImplicitUseStrict");
      }
      if (options.keyofStringsOnly) {
        createDeprecatedDiagnostic("keyofStringsOnly");
      }
      if (options.suppressExcessPropertyErrors) {
        createDeprecatedDiagnostic("suppressExcessPropertyErrors");
      }
      if (options.suppressImplicitAnyIndexErrors) {
        createDeprecatedDiagnostic("suppressImplicitAnyIndexErrors");
      }
      if (options.noStrictGenericChecks) {
        createDeprecatedDiagnostic("noStrictGenericChecks");
      }
      if (options.charset) {
        createDeprecatedDiagnostic("charset");
      }
      if (options.out) {
        createDeprecatedDiagnostic(
          "out",
          /*value*/
          void 0,
          "outFile"
        );
      }
      if (options.importsNotUsedAsValues) {
        createDeprecatedDiagnostic(
          "importsNotUsedAsValues",
          /*value*/
          void 0,
          "verbatimModuleSyntax"
        );
      }
      if (options.preserveValueImports) {
        createDeprecatedDiagnostic(
          "preserveValueImports",
          /*value*/
          void 0,
          "verbatimModuleSyntax"
        );
      }
    });
  }
  function verifyDeprecatedProjectReference(ref, parentFile, index) {
    function createDiagnostic(_name, _value, _useInstead, message, ...args) {
      createDiagnosticForReference(parentFile, index, message, ...args);
    }
    checkDeprecations("5.0", "5.5", "6.0", createDiagnostic, (createDeprecatedDiagnostic) => {
      if (ref.prepend) {
        createDeprecatedDiagnostic("prepend");
      }
    });
  }
  function createDiagnosticExplainingFile(file, fileProcessingReason, diagnostic, args) {
    let seenReasons;
    const reasons = file && fileReasons.get(file.path);
    let fileIncludeReasons;
    let relatedInfo;
    let locationReason = isReferencedFile(fileProcessingReason) ? fileProcessingReason : void 0;
    let fileIncludeReasonDetails;
    let redirectInfo;
    let cachedChain = file && (fileReasonsToChain == null ? void 0 : fileReasonsToChain.get(file.path));
    let chain;
    if (cachedChain) {
      if (cachedChain.fileIncludeReasonDetails) {
        seenReasons = new Set(reasons);
        reasons == null ? void 0 : reasons.forEach(populateRelatedInfo);
      } else {
        reasons == null ? void 0 : reasons.forEach(processReason);
      }
      redirectInfo = cachedChain.redirectInfo;
    } else {
      reasons == null ? void 0 : reasons.forEach(processReason);
      redirectInfo = file && explainIfFileIsRedirectAndImpliedFormat(file);
    }
    if (fileProcessingReason) processReason(fileProcessingReason);
    const processedExtraReason = (seenReasons == null ? void 0 : seenReasons.size) !== (reasons == null ? void 0 : reasons.length);
    if (locationReason && (seenReasons == null ? void 0 : seenReasons.size) === 1) seenReasons = void 0;
    if (seenReasons && cachedChain) {
      if (cachedChain.details && !processedExtraReason) {
        chain = chainDiagnosticMessages(cachedChain.details, diagnostic, ...args || emptyArray);
      } else if (cachedChain.fileIncludeReasonDetails) {
        if (!processedExtraReason) {
          if (!cachedFileIncludeDetailsHasProcessedExtraReason()) {
            fileIncludeReasonDetails = cachedChain.fileIncludeReasonDetails;
          } else {
            fileIncludeReasons = cachedChain.fileIncludeReasonDetails.next.slice(0, reasons.length);
          }
        } else {
          if (!cachedFileIncludeDetailsHasProcessedExtraReason()) {
            fileIncludeReasons = [...cachedChain.fileIncludeReasonDetails.next, fileIncludeReasons[0]];
          } else {
            fileIncludeReasons = append(cachedChain.fileIncludeReasonDetails.next.slice(0, reasons.length), fileIncludeReasons[0]);
          }
        }
      }
    }
    if (!chain) {
      if (!fileIncludeReasonDetails) fileIncludeReasonDetails = seenReasons && chainDiagnosticMessages(fileIncludeReasons, Diagnostics.The_file_is_in_the_program_because_Colon);
      chain = chainDiagnosticMessages(
        redirectInfo ? fileIncludeReasonDetails ? [fileIncludeReasonDetails, ...redirectInfo] : redirectInfo : fileIncludeReasonDetails,
        diagnostic,
        ...args || emptyArray
      );
    }
    if (file) {
      if (cachedChain) {
        if (!cachedChain.fileIncludeReasonDetails || !processedExtraReason && fileIncludeReasonDetails) {
          cachedChain.fileIncludeReasonDetails = fileIncludeReasonDetails;
        }
      } else {
        (fileReasonsToChain ?? (fileReasonsToChain = /* @__PURE__ */ new Map())).set(file.path, cachedChain = { fileIncludeReasonDetails, redirectInfo });
      }
      if (!cachedChain.details && !processedExtraReason) cachedChain.details = chain.next;
    }
    const location = locationReason && getReferencedFileLocation(program, locationReason);
    return location && isReferenceFileLocation(location) ? createFileDiagnosticFromMessageChain(location.file, location.pos, location.end - location.pos, chain, relatedInfo) : createCompilerDiagnosticFromMessageChain(chain, relatedInfo);
    function processReason(reason) {
      if (seenReasons == null ? void 0 : seenReasons.has(reason)) return;
      (seenReasons ?? (seenReasons = /* @__PURE__ */ new Set())).add(reason);
      (fileIncludeReasons ?? (fileIncludeReasons = [])).push(fileIncludeReasonToDiagnostics(program, reason));
      populateRelatedInfo(reason);
    }
    function populateRelatedInfo(reason) {
      if (!locationReason && isReferencedFile(reason)) {
        locationReason = reason;
      } else if (locationReason !== reason) {
        relatedInfo = append(relatedInfo, getFileIncludeReasonToRelatedInformation(reason));
      }
    }
    function cachedFileIncludeDetailsHasProcessedExtraReason() {
      var _a2;
      return ((_a2 = cachedChain.fileIncludeReasonDetails.next) == null ? void 0 : _a2.length) !== (reasons == null ? void 0 : reasons.length);
    }
  }
  function addFilePreprocessingFileExplainingDiagnostic(file, fileProcessingReason, diagnostic, args) {
    (fileProcessingDiagnostics || (fileProcessingDiagnostics = [])).push({
      kind: 1 /* FilePreprocessingFileExplainingDiagnostic */,
      file: file && file.path,
      fileProcessingReason,
      diagnostic,
      args
    });
  }
  function addLazyProgramDiagnosticExplainingFile(file, diagnostic, args) {
    lazyProgramDiagnosticExplainingFile.push({ file, diagnostic, args });
  }
  function getFileIncludeReasonToRelatedInformation(reason) {
    let relatedInfo = reasonToRelatedInfo == null ? void 0 : reasonToRelatedInfo.get(reason);
    if (relatedInfo === void 0) (reasonToRelatedInfo ?? (reasonToRelatedInfo = /* @__PURE__ */ new Map())).set(reason, relatedInfo = fileIncludeReasonToRelatedInformation(reason) ?? false);
    return relatedInfo || void 0;
  }
  function fileIncludeReasonToRelatedInformation(reason) {
    if (isReferencedFile(reason)) {
      const referenceLocation = getReferencedFileLocation(program, reason);
      let message2;
      switch (reason.kind) {
        case 3 /* Import */:
          message2 = Diagnostics.File_is_included_via_import_here;
          break;
        case 4 /* ReferenceFile */:
          message2 = Diagnostics.File_is_included_via_reference_here;
          break;
        case 5 /* TypeReferenceDirective */:
          message2 = Diagnostics.File_is_included_via_type_library_reference_here;
          break;
        case 7 /* LibReferenceDirective */:
          message2 = Diagnostics.File_is_included_via_library_reference_here;
          break;
        default:
          Debug.assertNever(reason);
      }
      return isReferenceFileLocation(referenceLocation) ? createFileDiagnostic(
        referenceLocation.file,
        referenceLocation.pos,
        referenceLocation.end - referenceLocation.pos,
        message2
      ) : void 0;
    }
    if (!options.configFile) return void 0;
    let configFileNode;
    let message;
    switch (reason.kind) {
      case 0 /* RootFile */:
        if (!options.configFile.configFileSpecs) return void 0;
        const fileName = getNormalizedAbsolutePath(rootNames[reason.index], currentDirectory);
        const matchedByFiles = getMatchedFileSpec(program, fileName);
        if (matchedByFiles) {
          configFileNode = getTsConfigPropArrayElementValue(options.configFile, "files", matchedByFiles);
          message = Diagnostics.File_is_matched_by_files_list_specified_here;
          break;
        }
        const matchedByInclude = getMatchedIncludeSpec(program, fileName);
        if (!matchedByInclude || !isString(matchedByInclude)) return void 0;
        configFileNode = getTsConfigPropArrayElementValue(options.configFile, "include", matchedByInclude);
        message = Diagnostics.File_is_matched_by_include_pattern_specified_here;
        break;
      case 1 /* SourceFromProjectReference */:
      case 2 /* OutputFromProjectReference */:
        const referencedResolvedRef = Debug.checkDefined(resolvedProjectReferences == null ? void 0 : resolvedProjectReferences[reason.index]);
        const referenceInfo = forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index2) => resolvedRef === referencedResolvedRef ? { sourceFile: (parent == null ? void 0 : parent.sourceFile) || options.configFile, index: index2 } : void 0);
        if (!referenceInfo) return void 0;
        const { sourceFile, index } = referenceInfo;
        const referencesSyntax = forEachTsConfigPropArray(sourceFile, "references", (property) => isArrayLiteralExpression(property.initializer) ? property.initializer : void 0);
        return referencesSyntax && referencesSyntax.elements.length > index ? createDiagnosticForNodeInSourceFile(
          sourceFile,
          referencesSyntax.elements[index],
          reason.kind === 2 /* OutputFromProjectReference */ ? Diagnostics.File_is_output_from_referenced_project_specified_here : Diagnostics.File_is_source_from_referenced_project_specified_here
        ) : void 0;
      case 8 /* AutomaticTypeDirectiveFile */:
        if (!options.types) return void 0;
        configFileNode = getOptionsSyntaxByArrayElementValue("types", reason.typeReference);
        message = Diagnostics.File_is_entry_point_of_type_library_specified_here;
        break;
      case 6 /* LibFile */:
        if (reason.index !== void 0) {
          configFileNode = getOptionsSyntaxByArrayElementValue("lib", options.lib[reason.index]);
          message = Diagnostics.File_is_library_specified_here;
          break;
        }
        const target = getNameOfScriptTarget(getEmitScriptTarget(options));
        configFileNode = target ? getOptionsSyntaxByValue("target", target) : void 0;
        message = Diagnostics.File_is_default_library_for_target_specified_here;
        break;
      default:
        Debug.assertNever(reason);
    }
    return configFileNode && createDiagnosticForNodeInSourceFile(
      options.configFile,
      configFileNode,
      message
    );
  }
  function verifyProjectReferences() {
    const buildInfoPath = !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : void 0;
    forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index) => {
      const ref = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
      const parentFile = parent && parent.sourceFile;
      verifyDeprecatedProjectReference(ref, parentFile, index);
      if (!resolvedRef) {
        createDiagnosticForReference(parentFile, index, Diagnostics.File_0_not_found, ref.path);
        return;
      }
      const options2 = resolvedRef.commandLine.options;
      if (!options2.composite || options2.noEmit) {
        const inputs = parent ? parent.commandLine.fileNames : rootNames;
        if (inputs.length) {
          if (!options2.composite) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
          if (options2.noEmit) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_may_not_disable_emit, ref.path);
        }
      }
      if (!parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath(options2)) {
        createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path);
        hasEmitBlockingDiagnostics.set(toPath3(buildInfoPath), true);
      }
    });
  }
  function createDiagnosticForOptionPathKeyValue(key, valueIndex, message, ...args) {
    let needCompilerDiagnostic = true;
    forEachOptionPathsSyntax((pathProp) => {
      if (isObjectLiteralExpression(pathProp.initializer)) {
        forEachPropertyAssignment(pathProp.initializer, key, (keyProps) => {
          const initializer = keyProps.initializer;
          if (isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) {
            programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, initializer.elements[valueIndex], message, ...args));
            needCompilerDiagnostic = false;
          }
        });
      }
    });
    if (needCompilerDiagnostic) {
      createCompilerOptionsDiagnostic(message, ...args);
    }
  }
  function createDiagnosticForOptionPaths(onKey, key, message, ...args) {
    let needCompilerDiagnostic = true;
    forEachOptionPathsSyntax((pathProp) => {
      if (isObjectLiteralExpression(pathProp.initializer) && createOptionDiagnosticInObjectLiteralSyntax(
        pathProp.initializer,
        onKey,
        key,
        /*key2*/
        void 0,
        message,
        ...args
      )) {
        needCompilerDiagnostic = false;
      }
    });
    if (needCompilerDiagnostic) {
      createCompilerOptionsDiagnostic(message, ...args);
    }
  }
  function forEachOptionsSyntaxByName(name, callback) {
    return forEachPropertyAssignment(getCompilerOptionsObjectLiteralSyntax(), name, callback);
  }
  function forEachOptionPathsSyntax(callback) {
    return forEachOptionsSyntaxByName("paths", callback);
  }
  function getOptionsSyntaxByValue(name, value) {
    return forEachOptionsSyntaxByName(name, (property) => isStringLiteral(property.initializer) && property.initializer.text === value ? property.initializer : void 0);
  }
  function getOptionsSyntaxByArrayElementValue(name, value) {
    const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
    return compilerOptionsObjectLiteralSyntax && getPropertyArrayElementValue(compilerOptionsObjectLiteralSyntax, name, value);
  }
  function createDiagnosticForOptionName(message, option1, option2, option3) {
    createDiagnosticForOption(
      /*onKey*/
      true,
      option1,
      option2,
      message,
      option1,
      option2,
      option3
    );
  }
  function createOptionValueDiagnostic(option1, message, ...args) {
    createDiagnosticForOption(
      /*onKey*/
      false,
      option1,
      /*option2*/
      void 0,
      message,
      ...args
    );
  }
  function createDiagnosticForReference(sourceFile, index, message, ...args) {
    const referencesSyntax = forEachTsConfigPropArray(sourceFile || options.configFile, "references", (property) => isArrayLiteralExpression(property.initializer) ? property.initializer : void 0);
    if (referencesSyntax && referencesSyntax.elements.length > index) {
      programDiagnostics.add(createDiagnosticForNodeInSourceFile(sourceFile || options.configFile, referencesSyntax.elements[index], message, ...args));
    } else {
      programDiagnostics.add(createCompilerDiagnostic(message, ...args));
    }
  }
  function createDiagnosticForOption(onKey, option1, option2, message, ...args) {
    const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
    const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax || !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, ...args);
    if (needCompilerDiagnostic) {
      createCompilerOptionsDiagnostic(message, ...args);
    }
  }
  function createCompilerOptionsDiagnostic(message, ...args) {
    const compilerOptionsProperty = getCompilerOptionsPropertySyntax();
    if (compilerOptionsProperty) {
      if ("messageText" in message) {
        programDiagnostics.add(createDiagnosticForNodeFromMessageChain(options.configFile, compilerOptionsProperty.name, message));
      } else {
        programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, compilerOptionsProperty.name, message, ...args));
      }
    } else if ("messageText" in message) {
      programDiagnostics.add(createCompilerDiagnosticFromMessageChain(message));
    } else {
      programDiagnostics.add(createCompilerDiagnostic(message, ...args));
    }
  }
  function getCompilerOptionsObjectLiteralSyntax() {
    if (_compilerOptionsObjectLiteralSyntax === void 0) {
      const compilerOptionsProperty = getCompilerOptionsPropertySyntax();
      _compilerOptionsObjectLiteralSyntax = compilerOptionsProperty ? tryCast(compilerOptionsProperty.initializer, isObjectLiteralExpression) || false : false;
    }
    return _compilerOptionsObjectLiteralSyntax || void 0;
  }
  function getCompilerOptionsPropertySyntax() {
    if (_compilerOptionsPropertySyntax === void 0) {
      _compilerOptionsPropertySyntax = forEachPropertyAssignment(
        getTsConfigObjectLiteralExpression(options.configFile),
        "compilerOptions",
        identity
      ) || false;
    }
    return _compilerOptionsPropertySyntax || void 0;
  }
  function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral, onKey, key1, key2, message, ...args) {
    let needsCompilerDiagnostic = false;
    forEachPropertyAssignment(objectLiteral, key1, (prop) => {
      if ("messageText" in message) {
        programDiagnostics.add(createDiagnosticForNodeFromMessageChain(options.configFile, onKey ? prop.name : prop.initializer, message));
      } else {
        programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, ...args));
      }
      needsCompilerDiagnostic = true;
    }, key2);
    return needsCompilerDiagnostic;
  }
  function blockEmittingOfFile(emitFileName, diag2) {
    hasEmitBlockingDiagnostics.set(toPath3(emitFileName), true);
    programDiagnostics.add(diag2);
  }
  function isEmittedFile(file) {
    if (options.noEmit) {
      return false;
    }
    const filePath = toPath3(file);
    if (getSourceFileByPath(filePath)) {
      return false;
    }
    const out = options.outFile;
    if (out) {
      return isSameFile(filePath, out) || isSameFile(filePath, removeFileExtension(out) + ".d.ts" /* Dts */);
    }
    if (options.declarationDir && containsPath(options.declarationDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames())) {
      return true;
    }
    if (options.outDir) {
      return containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames());
    }
    if (fileExtensionIsOneOf(filePath, supportedJSExtensionsFlat) || isDeclarationFileName(filePath)) {
      const filePathWithoutExtension = removeFileExtension(filePath);
      return !!getSourceFileByPath(filePathWithoutExtension + ".ts" /* Ts */) || !!getSourceFileByPath(filePathWithoutExtension + ".tsx" /* Tsx */);
    }
    return false;
  }
  function isSameFile(file1, file2) {
    return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
  }
  function getSymlinkCache() {
    if (host.getSymlinkCache) {
      return host.getSymlinkCache();
    }
    if (!symlinks) {
      symlinks = createSymlinkCache(currentDirectory, getCanonicalFileName);
    }
    if (files && !symlinks.hasProcessedResolutions()) {
      symlinks.setSymlinksFromResolutions(forEachResolvedModule, forEachResolvedTypeReferenceDirective, automaticTypeDirectiveResolutions);
    }
    return symlinks;
  }
  function getModeForUsageLocation2(file, usage) {
    var _a2;
    const optionsForFile = ((_a2 = getRedirectReferenceForResolution(file)) == null ? void 0 : _a2.commandLine.options) || options;
    return getModeForUsageLocationWorker(file, usage, optionsForFile);
  }
  function getModeForResolutionAtIndex2(file, index) {
    return getModeForUsageLocation2(file, getModuleNameStringLiteralAt(file, index));
  }
}
function updateHostForUseSourceOfProjectReferenceRedirect(host) {
  let setOfDeclarationDirectories;
  const originalFileExists = host.compilerHost.fileExists;
  const originalDirectoryExists = host.compilerHost.directoryExists;
  const originalGetDirectories = host.compilerHost.getDirectories;
  const originalRealpath = host.compilerHost.realpath;
  if (!host.useSourceOfProjectReferenceRedirect) return { onProgramCreateComplete: noop, fileExists };
  host.compilerHost.fileExists = fileExists;
  let directoryExists;
  if (originalDirectoryExists) {
    directoryExists = host.compilerHost.directoryExists = (path) => {
      if (originalDirectoryExists.call(host.compilerHost, path)) {
        handleDirectoryCouldBeSymlink(path);
        return true;
      }
      if (!host.getResolvedProjectReferences()) return false;
      if (!setOfDeclarationDirectories) {
        setOfDeclarationDirectories = /* @__PURE__ */ new Set();
        host.forEachResolvedProjectReference((ref) => {
          const out = ref.commandLine.options.outFile;
          if (out) {
            setOfDeclarationDirectories.add(getDirectoryPath(host.toPath(out)));
          } else {
            const declarationDir = ref.commandLine.options.declarationDir || ref.commandLine.options.outDir;
            if (declarationDir) {
              setOfDeclarationDirectories.add(host.toPath(declarationDir));
            }
          }
        });
      }
      return fileOrDirectoryExistsUsingSource(
        path,
        /*isFile*/
        false
      );
    };
  }
  if (originalGetDirectories) {
    host.compilerHost.getDirectories = (path) => !host.getResolvedProjectReferences() || originalDirectoryExists && originalDirectoryExists.call(host.compilerHost, path) ? originalGetDirectories.call(host.compilerHost, path) : [];
  }
  if (originalRealpath) {
    host.compilerHost.realpath = (s) => {
      var _a;
      return ((_a = host.getSymlinkCache().getSymlinkedFiles()) == null ? void 0 : _a.get(host.toPath(s))) || originalRealpath.call(host.compilerHost, s);
    };
  }
  return { onProgramCreateComplete, fileExists, directoryExists };
  function onProgramCreateComplete() {
    host.compilerHost.fileExists = originalFileExists;
    host.compilerHost.directoryExists = originalDirectoryExists;
    host.compilerHost.getDirectories = originalGetDirectories;
  }
  function fileExists(file) {
    if (originalFileExists.call(host.compilerHost, file)) return true;
    if (!host.getResolvedProjectReferences()) return false;
    if (!isDeclarationFileName(file)) return false;
    return fileOrDirectoryExistsUsingSource(
      file,
      /*isFile*/
      true
    );
  }
  function fileExistsIfProjectReferenceDts(file) {
    const source = host.getSourceOfProjectReferenceRedirect(host.toPath(file));
    return source !== void 0 ? isString(source) ? originalFileExists.call(host.compilerHost, source) : true : void 0;
  }
  function directoryExistsIfProjectReferenceDeclDir(dir) {
    const dirPath = host.toPath(dir);
    const dirPathWithTrailingDirectorySeparator = `${dirPath}${directorySeparator}`;
    return forEachKey(
      setOfDeclarationDirectories,
      (declDirPath) => dirPath === declDirPath || // Any parent directory of declaration dir
      startsWith(declDirPath, dirPathWithTrailingDirectorySeparator) || // Any directory inside declaration dir
      startsWith(dirPath, `${declDirPath}/`)
    );
  }
  function handleDirectoryCouldBeSymlink(directory) {
    var _a;
    if (!host.getResolvedProjectReferences() || containsIgnoredPath(directory)) return;
    if (!originalRealpath || !directory.includes(nodeModulesPathPart)) return;
    const symlinkCache = host.getSymlinkCache();
    const directoryPath = ensureTrailingDirectorySeparator(host.toPath(directory));
    if ((_a = symlinkCache.getSymlinkedDirectories()) == null ? void 0 : _a.has(directoryPath)) return;
    const real = normalizePath(originalRealpath.call(host.compilerHost, directory));
    let realPath2;
    if (real === directory || (realPath2 = ensureTrailingDirectorySeparator(host.toPath(real))) === directoryPath) {
      symlinkCache.setSymlinkedDirectory(directoryPath, false);
      return;
    }
    symlinkCache.setSymlinkedDirectory(directory, {
      real: ensureTrailingDirectorySeparator(real),
      realPath: realPath2
    });
  }
  function fileOrDirectoryExistsUsingSource(fileOrDirectory, isFile) {
    var _a;
    const fileOrDirectoryExistsUsingSource2 = isFile ? (file) => fileExistsIfProjectReferenceDts(file) : (dir) => directoryExistsIfProjectReferenceDeclDir(dir);
    const result = fileOrDirectoryExistsUsingSource2(fileOrDirectory);
    if (result !== void 0) return result;
    const symlinkCache = host.getSymlinkCache();
    const symlinkedDirectories = symlinkCache.getSymlinkedDirectories();
    if (!symlinkedDirectories) return false;
    const fileOrDirectoryPath = host.toPath(fileOrDirectory);
    if (!fileOrDirectoryPath.includes(nodeModulesPathPart)) return false;
    if (isFile && ((_a = symlinkCache.getSymlinkedFiles()) == null ? void 0 : _a.has(fileOrDirectoryPath))) return true;
    return firstDefinedIterator(
      symlinkedDirectories.entries(),
      ([directoryPath, symlinkedDirectory]) => {
        if (!symlinkedDirectory || !startsWith(fileOrDirectoryPath, directoryPath)) return void 0;
        const result2 = fileOrDirectoryExistsUsingSource2(fileOrDirectoryPath.replace(directoryPath, symlinkedDirectory.realPath));
        if (isFile && result2) {
          const absolutePath = getNormalizedAbsolutePath(fileOrDirectory, host.compilerHost.getCurrentDirectory());
          symlinkCache.setSymlinkedFile(
            fileOrDirectoryPath,
            `${symlinkedDirectory.real}${absolutePath.replace(new RegExp(directoryPath, "i"), "")}`
          );
        }
        return result2;
      }
    ) || false;
  }
}
var emitSkippedWithNoDiagnostics = { diagnostics: emptyArray, sourceMaps: void 0, emittedFiles: void 0, emitSkipped: true };
function handleNoEmitOptions(program, sourceFile, writeFile2, cancellationToken) {
  const options = program.getCompilerOptions();
  if (options.noEmit) {
    program.getSemanticDiagnostics(sourceFile, cancellationToken);
    return sourceFile || options.outFile ? emitSkippedWithNoDiagnostics : program.emitBuildInfo(writeFile2, cancellationToken);
  }
  if (!options.noEmitOnError) return void 0;
  let diagnostics = [
    ...program.getOptionsDiagnostics(cancellationToken),
    ...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
    ...program.getGlobalDiagnostics(cancellationToken),
    ...program.getSemanticDiagnostics(sourceFile, cancellationToken)
  ];
  if (diagnostics.length === 0 && getEmitDeclarations(program.getCompilerOptions())) {
    diagnostics = program.getDeclarationDiagnostics(
      /*sourceFile*/
      void 0,
      cancellationToken
    );
  }
  if (!diagnostics.length) return void 0;
  let emittedFiles;
  if (!sourceFile && !options.outFile) {
    const emitResult = program.emitBuildInfo(writeFile2, cancellationToken);
    if (emitResult.diagnostics) diagnostics = [...diagnostics, ...emitResult.diagnostics];
    emittedFiles = emitResult.emittedFiles;
  }
  return { diagnostics, sourceMaps: void 0, emittedFiles, emitSkipped: true };
}
function filterSemanticDiagnostics(diagnostic, option) {
  return filter(diagnostic, (d) => !d.skippedOn || !option[d.skippedOn]);
}
function parseConfigHostFromCompilerHostLike(host, directoryStructureHost = host) {
  return {
    fileExists: (f) => directoryStructureHost.fileExists(f),
    readDirectory(root, extensions, excludes, includes, depth) {
      Debug.assertIsDefined(directoryStructureHost.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
      return directoryStructureHost.readDirectory(root, extensions, excludes, includes, depth);
    },
    readFile: (f) => directoryStructureHost.readFile(f),
    directoryExists: maybeBind(directoryStructureHost, directoryStructureHost.directoryExists),
    getDirectories: maybeBind(directoryStructureHost, directoryStructureHost.getDirectories),
    realpath: maybeBind(directoryStructureHost, directoryStructureHost.realpath),
    useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
    getCurrentDirectory: () => host.getCurrentDirectory(),
    onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || returnUndefined,
    trace: host.trace ? (s) => host.trace(s) : void 0
  };
}
function resolveProjectReferencePath(ref) {
  return resolveConfigFileProjectName(ref.path);
}
function getResolutionDiagnostic(options, { extension }, { isDeclarationFile }) {
  switch (extension) {
    case ".ts" /* Ts */:
    case ".d.ts" /* Dts */:
    case ".mts" /* Mts */:
    case ".d.mts" /* Dmts */:
    case ".cts" /* Cts */:
    case ".d.cts" /* Dcts */:
      return void 0;
    case ".tsx" /* Tsx */:
      return needJsx();
    case ".jsx" /* Jsx */:
      return needJsx() || needAllowJs();
    case ".js" /* Js */:
    case ".mjs" /* Mjs */:
    case ".cjs" /* Cjs */:
      return needAllowJs();
    case ".json" /* Json */:
      return needResolveJsonModule();
    default:
      return needAllowArbitraryExtensions();
  }
  function needJsx() {
    return options.jsx ? void 0 : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
  }
  function needAllowJs() {
    return getAllowJSCompilerOption(options) || !getStrictOptionValue(options, "noImplicitAny") ? void 0 : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
  }
  function needResolveJsonModule() {
    return getResolveJsonModule(options) ? void 0 : Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used;
  }
  function needAllowArbitraryExtensions() {
    return isDeclarationFile || options.allowArbitraryExtensions ? void 0 : Diagnostics.Module_0_was_resolved_to_1_but_allowArbitraryExtensions_is_not_set;
  }
}
function getModuleNames({ imports, moduleAugmentations }) {
  const res = imports.map((i) => i);
  for (const aug of moduleAugmentations) {
    if (aug.kind === 11 /* StringLiteral */) {
      res.push(aug);
    }
  }
  return res;
}
function getModuleNameStringLiteralAt({ imports, moduleAugmentations }, index) {
  if (index < imports.length) return imports[index];
  let augIndex = imports.length;
  for (const aug of moduleAugmentations) {
    if (aug.kind === 11 /* StringLiteral */) {
      if (index === augIndex) return aug;
      augIndex++;
    }
  }
  Debug.fail("should never ask for module name at index higher than possible module name");
}

// src/compiler/builderState.ts
var BuilderState;
((BuilderState2) => {
  function createManyToManyPathMap() {
    function create2(forward, reverse, deleted) {
      const map2 = {
        getKeys: (v) => reverse.get(v),
        getValues: (k) => forward.get(k),
        keys: () => forward.keys(),
        size: () => forward.size,
        deleteKey: (k) => {
          (deleted || (deleted = /* @__PURE__ */ new Set())).add(k);
          const set = forward.get(k);
          if (!set) {
            return false;
          }
          set.forEach((v) => deleteFromMultimap(reverse, v, k));
          forward.delete(k);
          return true;
        },
        set: (k, vSet) => {
          deleted == null ? void 0 : deleted.delete(k);
          const existingVSet = forward.get(k);
          forward.set(k, vSet);
          existingVSet == null ? void 0 : existingVSet.forEach((v) => {
            if (!vSet.has(v)) {
              deleteFromMultimap(reverse, v, k);
            }
          });
          vSet.forEach((v) => {
            if (!(existingVSet == null ? void 0 : existingVSet.has(v))) {
              addToMultimap(reverse, v, k);
            }
          });
          return map2;
        }
      };
      return map2;
    }
    return create2(
      /* @__PURE__ */ new Map(),
      /* @__PURE__ */ new Map(),
      /*deleted*/
      void 0
    );
  }
  BuilderState2.createManyToManyPathMap = createManyToManyPathMap;
  function addToMultimap(map2, k, v) {
    let set = map2.get(k);
    if (!set) {
      set = /* @__PURE__ */ new Set();
      map2.set(k, set);
    }
    set.add(v);
  }
  function deleteFromMultimap(map2, k, v) {
    const set = map2.get(k);
    if (set == null ? void 0 : set.delete(v)) {
      if (!set.size) {
        map2.delete(k);
      }
      return true;
    }
    return false;
  }
  function getReferencedFilesFromImportedModuleSymbol(symbol) {
    return mapDefined(symbol.declarations, (declaration) => {
      var _a;
      return (_a = getSourceFileOfNode(declaration)) == null ? void 0 : _a.resolvedPath;
    });
  }
  function getReferencedFilesFromImportLiteral(checker, importName) {
    const symbol = checker.getSymbolAtLocation(importName);
    return symbol && getReferencedFilesFromImportedModuleSymbol(symbol);
  }
  function getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName) {
    return toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName);
  }
  function getReferencedFiles(program, sourceFile, getCanonicalFileName) {
    let referencedFiles;
    if (sourceFile.imports && sourceFile.imports.length > 0) {
      const checker = program.getTypeChecker();
      for (const importName of sourceFile.imports) {
        const declarationSourceFilePaths = getReferencedFilesFromImportLiteral(checker, importName);
        declarationSourceFilePaths == null ? void 0 : declarationSourceFilePaths.forEach(addReferencedFile);
      }
    }
    const sourceFileDirectory = getDirectoryPath(sourceFile.resolvedPath);
    if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
      for (const referencedFile of sourceFile.referencedFiles) {
        const referencedPath = getReferencedFileFromFileName(program, referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
        addReferencedFile(referencedPath);
      }
    }
    program.forEachResolvedTypeReferenceDirective(({ resolvedTypeReferenceDirective }) => {
      if (!resolvedTypeReferenceDirective) {
        return;
      }
      const fileName = resolvedTypeReferenceDirective.resolvedFileName;
      const typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
      addReferencedFile(typeFilePath);
    }, sourceFile);
    if (sourceFile.moduleAugmentations.length) {
      const checker = program.getTypeChecker();
      for (const moduleName of sourceFile.moduleAugmentations) {
        if (!isStringLiteral(moduleName)) continue;
        const symbol = checker.getSymbolAtLocation(moduleName);
        if (!symbol) continue;
        addReferenceFromAmbientModule(symbol);
      }
    }
    for (const ambientModule of program.getTypeChecker().getAmbientModules()) {
      if (ambientModule.declarations && ambientModule.declarations.length > 1) {
        addReferenceFromAmbientModule(ambientModule);
      }
    }
    return referencedFiles;
    function addReferenceFromAmbientModule(symbol) {
      if (!symbol.declarations) {
        return;
      }
      for (const declaration of symbol.declarations) {
        const declarationSourceFile = getSourceFileOfNode(declaration);
        if (declarationSourceFile && declarationSourceFile !== sourceFile) {
          addReferencedFile(declarationSourceFile.resolvedPath);
        }
      }
    }
    function addReferencedFile(referencedPath) {
      (referencedFiles || (referencedFiles = /* @__PURE__ */ new Set())).add(referencedPath);
    }
  }
  function canReuseOldState(newReferencedMap, oldState) {
    return oldState && !oldState.referencedMap === !newReferencedMap;
  }
  BuilderState2.canReuseOldState = canReuseOldState;
  function createReferencedMap(options) {
    return options.module !== 0 /* None */ && !options.outFile ? createManyToManyPathMap() : void 0;
  }
  BuilderState2.createReferencedMap = createReferencedMap;
  function create(newProgram, oldState, disableUseFileVersionAsSignature) {
    var _a, _b;
    const fileInfos = /* @__PURE__ */ new Map();
    const options = newProgram.getCompilerOptions();
    const referencedMap = createReferencedMap(options);
    const useOldState = canReuseOldState(referencedMap, oldState);
    newProgram.getTypeChecker();
    for (const sourceFile of newProgram.getSourceFiles()) {
      const version2 = Debug.checkDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set");
      const oldUncommittedSignature = useOldState ? (_a = oldState.oldSignatures) == null ? void 0 : _a.get(sourceFile.resolvedPath) : void 0;
      const signature = oldUncommittedSignature === void 0 ? useOldState ? (_b = oldState.fileInfos.get(sourceFile.resolvedPath)) == null ? void 0 : _b.signature : void 0 : oldUncommittedSignature || void 0;
      if (referencedMap) {
        const newReferences = getReferencedFiles(newProgram, sourceFile, newProgram.getCanonicalFileName);
        if (newReferences) {
          referencedMap.set(sourceFile.resolvedPath, newReferences);
        }
      }
      fileInfos.set(sourceFile.resolvedPath, {
        version: version2,
        signature,
        // No need to calculate affectsGlobalScope with --out since its not used at all
        affectsGlobalScope: !options.outFile ? isFileAffectingGlobalScope(sourceFile) || void 0 : void 0,
        impliedFormat: sourceFile.impliedNodeFormat
      });
    }
    return {
      fileInfos,
      referencedMap,
      useFileVersionAsSignature: !disableUseFileVersionAsSignature && !useOldState
    };
  }
  BuilderState2.create = create;
  function releaseCache2(state) {
    state.allFilesExcludingDefaultLibraryFile = void 0;
    state.allFileNames = void 0;
  }
  BuilderState2.releaseCache = releaseCache2;
  function getFilesAffectedBy(state, programOfThisState, path, cancellationToken, host) {
    var _a;
    const result = getFilesAffectedByWithOldState(
      state,
      programOfThisState,
      path,
      cancellationToken,
      host
    );
    (_a = state.oldSignatures) == null ? void 0 : _a.clear();
    return result;
  }
  BuilderState2.getFilesAffectedBy = getFilesAffectedBy;
  function getFilesAffectedByWithOldState(state, programOfThisState, path, cancellationToken, host) {
    const sourceFile = programOfThisState.getSourceFileByPath(path);
    if (!sourceFile) {
      return emptyArray;
    }
    if (!updateShapeSignature(state, programOfThisState, sourceFile, cancellationToken, host)) {
      return [sourceFile];
    }
    return (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, cancellationToken, host);
  }
  BuilderState2.getFilesAffectedByWithOldState = getFilesAffectedByWithOldState;
  function updateSignatureOfFile(state, signature, path) {
    state.fileInfos.get(path).signature = signature;
    (state.hasCalledUpdateShapeSignature || (state.hasCalledUpdateShapeSignature = /* @__PURE__ */ new Set())).add(path);
  }
  BuilderState2.updateSignatureOfFile = updateSignatureOfFile;
  function computeDtsSignature(programOfThisState, sourceFile, cancellationToken, host, onNewSignature) {
    programOfThisState.emit(
      sourceFile,
      (fileName, text, _writeByteOrderMark, _onError, sourceFiles, data) => {
        Debug.assert(isDeclarationFileName(fileName), `File extension for signature expected to be dts: Got:: ${fileName}`);
        onNewSignature(
          computeSignatureWithDiagnostics(
            programOfThisState,
            sourceFile,
            text,
            host,
            data
          ),
          sourceFiles
        );
      },
      cancellationToken,
      2 /* BuilderSignature */,
      /*customTransformers*/
      void 0,
      /*forceDtsEmit*/
      true
    );
  }
  BuilderState2.computeDtsSignature = computeDtsSignature;
  function updateShapeSignature(state, programOfThisState, sourceFile, cancellationToken, host, useFileVersionAsSignature = state.useFileVersionAsSignature) {
    var _a;
    if ((_a = state.hasCalledUpdateShapeSignature) == null ? void 0 : _a.has(sourceFile.resolvedPath)) return false;
    const info = state.fileInfos.get(sourceFile.resolvedPath);
    const prevSignature = info.signature;
    let latestSignature;
    if (!sourceFile.isDeclarationFile && !useFileVersionAsSignature) {
      computeDtsSignature(programOfThisState, sourceFile, cancellationToken, host, (signature) => {
        latestSignature = signature;
        if (host.storeSignatureInfo) (state.signatureInfo ?? (state.signatureInfo = /* @__PURE__ */ new Map())).set(sourceFile.resolvedPath, 0 /* ComputedDts */);
      });
    }
    if (latestSignature === void 0) {
      latestSignature = sourceFile.version;
      if (host.storeSignatureInfo) (state.signatureInfo ?? (state.signatureInfo = /* @__PURE__ */ new Map())).set(sourceFile.resolvedPath, 2 /* UsedVersion */);
    }
    (state.oldSignatures || (state.oldSignatures = /* @__PURE__ */ new Map())).set(sourceFile.resolvedPath, prevSignature || false);
    (state.hasCalledUpdateShapeSignature || (state.hasCalledUpdateShapeSignature = /* @__PURE__ */ new Set())).add(sourceFile.resolvedPath);
    info.signature = latestSignature;
    return latestSignature !== prevSignature;
  }
  BuilderState2.updateShapeSignature = updateShapeSignature;
  function getAllDependencies(state, programOfThisState, sourceFile) {
    const compilerOptions = programOfThisState.getCompilerOptions();
    if (compilerOptions.outFile) {
      return getAllFileNames(state, programOfThisState);
    }
    if (!state.referencedMap || isFileAffectingGlobalScope(sourceFile)) {
      return getAllFileNames(state, programOfThisState);
    }
    const seenMap = /* @__PURE__ */ new Set();
    const queue = [sourceFile.resolvedPath];
    while (queue.length) {
      const path = queue.pop();
      if (!seenMap.has(path)) {
        seenMap.add(path);
        const references = state.referencedMap.getValues(path);
        if (references) {
          for (const key of references.keys()) {
            queue.push(key);
          }
        }
      }
    }
    return arrayFrom(mapDefinedIterator(seenMap.keys(), (path) => {
      var _a;
      return ((_a = programOfThisState.getSourceFileByPath(path)) == null ? void 0 : _a.fileName) ?? path;
    }));
  }
  BuilderState2.getAllDependencies = getAllDependencies;
  function getAllFileNames(state, programOfThisState) {
    if (!state.allFileNames) {
      const sourceFiles = programOfThisState.getSourceFiles();
      state.allFileNames = sourceFiles === emptyArray ? emptyArray : sourceFiles.map((file) => file.fileName);
    }
    return state.allFileNames;
  }
  function getReferencedByPaths(state, referencedFilePath) {
    const keys = state.referencedMap.getKeys(referencedFilePath);
    return keys ? arrayFrom(keys.keys()) : [];
  }
  BuilderState2.getReferencedByPaths = getReferencedByPaths;
  function containsOnlyAmbientModules(sourceFile) {
    for (const statement of sourceFile.statements) {
      if (!isModuleWithStringLiteralName(statement)) {
        return false;
      }
    }
    return true;
  }
  function containsGlobalScopeAugmentation(sourceFile) {
    return some(sourceFile.moduleAugmentations, (augmentation) => isGlobalScopeAugmentation(augmentation.parent));
  }
  function isFileAffectingGlobalScope(sourceFile) {
    return containsGlobalScopeAugmentation(sourceFile) || !isExternalOrCommonJsModule(sourceFile) && !isJsonSourceFile(sourceFile) && !containsOnlyAmbientModules(sourceFile);
  }
  function getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, firstSourceFile) {
    if (state.allFilesExcludingDefaultLibraryFile) {
      return state.allFilesExcludingDefaultLibraryFile;
    }
    let result;
    if (firstSourceFile) addSourceFile(firstSourceFile);
    for (const sourceFile of programOfThisState.getSourceFiles()) {
      if (sourceFile !== firstSourceFile) {
        addSourceFile(sourceFile);
      }
    }
    state.allFilesExcludingDefaultLibraryFile = result || emptyArray;
    return state.allFilesExcludingDefaultLibraryFile;
    function addSourceFile(sourceFile) {
      if (!programOfThisState.isSourceFileDefaultLibrary(sourceFile)) {
        (result || (result = [])).push(sourceFile);
      }
    }
  }
  BuilderState2.getAllFilesExcludingDefaultLibraryFile = getAllFilesExcludingDefaultLibraryFile;
  function getFilesAffectedByUpdatedShapeWhenNonModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape) {
    const compilerOptions = programOfThisState.getCompilerOptions();
    if (compilerOptions && compilerOptions.outFile) {
      return [sourceFileWithUpdatedShape];
    }
    return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
  }
  function getFilesAffectedByUpdatedShapeWhenModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape, cancellationToken, host) {
    if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) {
      return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
    }
    const compilerOptions = programOfThisState.getCompilerOptions();
    if (compilerOptions && (getIsolatedModules(compilerOptions) || compilerOptions.outFile)) {
      return [sourceFileWithUpdatedShape];
    }
    const seenFileNamesMap = /* @__PURE__ */ new Map();
    seenFileNamesMap.set(sourceFileWithUpdatedShape.resolvedPath, sourceFileWithUpdatedShape);
    const queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.resolvedPath);
    while (queue.length > 0) {
      const currentPath = queue.pop();
      if (!seenFileNamesMap.has(currentPath)) {
        const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath);
        seenFileNamesMap.set(currentPath, currentSourceFile);
        if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cancellationToken, host)) {
          queue.push(...getReferencedByPaths(state, currentSourceFile.resolvedPath));
        }
      }
    }
    return arrayFrom(mapDefinedIterator(seenFileNamesMap.values(), (value) => value));
  }
})(BuilderState || (BuilderState = {}));

// src/compiler/builder.ts
function getBuilderFileEmit(options) {
  let result = 1 /* Js */;
  if (options.sourceMap) result = result | 2 /* JsMap */;
  if (options.inlineSourceMap) result = result | 4 /* JsInlineMap */;
  if (getEmitDeclarations(options)) result = result | 8 /* Dts */;
  if (options.declarationMap) result = result | 16 /* DtsMap */;
  if (options.emitDeclarationOnly) result = result & 24 /* AllDts */;
  return result;
}
function getPendingEmitKind(optionsOrEmitKind, oldOptionsOrEmitKind) {
  const oldEmitKind = oldOptionsOrEmitKind && (isNumber(oldOptionsOrEmitKind) ? oldOptionsOrEmitKind : getBuilderFileEmit(oldOptionsOrEmitKind));
  const emitKind = isNumber(optionsOrEmitKind) ? optionsOrEmitKind : getBuilderFileEmit(optionsOrEmitKind);
  if (oldEmitKind === emitKind) return 0 /* None */;
  if (!oldEmitKind || !emitKind) return emitKind;
  const diff = oldEmitKind ^ emitKind;
  let result = 0 /* None */;
  if (diff & 7 /* AllJs */) result = emitKind & 7 /* AllJs */;
  if (diff & 24 /* AllDts */) result = result | emitKind & 24 /* AllDts */;
  return result;
}
function hasSameKeys(map1, map2) {
  return map1 === map2 || map1 !== void 0 && map2 !== void 0 && map1.size === map2.size && !forEachKey(map1, (key) => !map2.has(key));
}
function createBuilderProgramState(newProgram, oldState) {
  var _a, _b;
  const state = BuilderState.create(
    newProgram,
    oldState,
    /*disableUseFileVersionAsSignature*/
    false
  );
  state.program = newProgram;
  const compilerOptions = newProgram.getCompilerOptions();
  state.compilerOptions = compilerOptions;
  const outFilePath = compilerOptions.outFile;
  if (!outFilePath) {
    state.semanticDiagnosticsPerFile = /* @__PURE__ */ new Map();
  } else if (compilerOptions.composite && (oldState == null ? void 0 : oldState.outSignature) && outFilePath === oldState.compilerOptions.outFile) {
    state.outSignature = oldState.outSignature && getEmitSignatureFromOldSignature(compilerOptions, oldState.compilerOptions, oldState.outSignature);
  }
  state.changedFilesSet = /* @__PURE__ */ new Set();
  state.latestChangedDtsFile = compilerOptions.composite ? oldState == null ? void 0 : oldState.latestChangedDtsFile : void 0;
  const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
  const oldCompilerOptions = useOldState ? oldState.compilerOptions : void 0;
  const canCopySemanticDiagnostics = useOldState && oldState.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile && !compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions);
  const canCopyEmitSignatures = compilerOptions.composite && (oldState == null ? void 0 : oldState.emitSignatures) && !outFilePath && !compilerOptionsAffectDeclarationPath(compilerOptions, oldState.compilerOptions);
  if (useOldState) {
    (_a = oldState.changedFilesSet) == null ? void 0 : _a.forEach((value) => state.changedFilesSet.add(value));
    if (!outFilePath && ((_b = oldState.affectedFilesPendingEmit) == null ? void 0 : _b.size)) {
      state.affectedFilesPendingEmit = new Map(oldState.affectedFilesPendingEmit);
      state.seenAffectedFiles = /* @__PURE__ */ new Set();
    }
    state.programEmitPending = oldState.programEmitPending;
  } else {
    state.buildInfoEmitPending = true;
  }
  const referencedMap = state.referencedMap;
  const oldReferencedMap = useOldState ? oldState.referencedMap : void 0;
  const copyDeclarationFileDiagnostics = canCopySemanticDiagnostics && !compilerOptions.skipLibCheck === !oldCompilerOptions.skipLibCheck;
  const copyLibFileDiagnostics = copyDeclarationFileDiagnostics && !compilerOptions.skipDefaultLibCheck === !oldCompilerOptions.skipDefaultLibCheck;
  state.fileInfos.forEach((info, sourceFilePath) => {
    var _a2;
    let oldInfo;
    let newReferences;
    if (!useOldState || // File wasn't present in old state
    !(oldInfo = oldState.fileInfos.get(sourceFilePath)) || // versions dont match
    oldInfo.version !== info.version || // Implied formats dont match
    oldInfo.impliedFormat !== info.impliedFormat || // Referenced files changed
    !hasSameKeys(newReferences = referencedMap && referencedMap.getValues(sourceFilePath), oldReferencedMap && oldReferencedMap.getValues(sourceFilePath)) || // Referenced file was deleted in the new program
    newReferences && forEachKey(newReferences, (path) => !state.fileInfos.has(path) && oldState.fileInfos.has(path))) {
      addFileToChangeSet(state, sourceFilePath);
    } else {
      const sourceFile = newProgram.getSourceFileByPath(sourceFilePath);
      const emitDiagnostics = (_a2 = oldState.emitDiagnosticsPerFile) == null ? void 0 : _a2.get(sourceFilePath);
      if (emitDiagnostics) {
        (state.emitDiagnosticsPerFile ?? (state.emitDiagnosticsPerFile = /* @__PURE__ */ new Map())).set(
          sourceFilePath,
          oldState.hasReusableDiagnostic ? convertToDiagnostics(emitDiagnostics, sourceFilePath, newProgram) : repopulateDiagnostics(emitDiagnostics, newProgram)
        );
      }
      if (canCopySemanticDiagnostics) {
        if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) return;
        if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) return;
        const diagnostics = oldState.semanticDiagnosticsPerFile.get(sourceFilePath);
        if (diagnostics) {
          state.semanticDiagnosticsPerFile.set(
            sourceFilePath,
            oldState.hasReusableDiagnostic ? convertToDiagnostics(diagnostics, sourceFilePath, newProgram) : repopulateDiagnostics(diagnostics, newProgram)
          );
          (state.semanticDiagnosticsFromOldState ?? (state.semanticDiagnosticsFromOldState = /* @__PURE__ */ new Set())).add(sourceFilePath);
        }
      }
    }
    if (canCopyEmitSignatures) {
      const oldEmitSignature = oldState.emitSignatures.get(sourceFilePath);
      if (oldEmitSignature) {
        (state.emitSignatures ?? (state.emitSignatures = /* @__PURE__ */ new Map())).set(sourceFilePath, getEmitSignatureFromOldSignature(compilerOptions, oldState.compilerOptions, oldEmitSignature));
      }
    }
  });
  if (useOldState && forEachEntry(oldState.fileInfos, (info, sourceFilePath) => {
    if (state.fileInfos.has(sourceFilePath)) return false;
    if (outFilePath || info.affectsGlobalScope) return true;
    state.buildInfoEmitPending = true;
    return false;
  })) {
    BuilderState.getAllFilesExcludingDefaultLibraryFile(
      state,
      newProgram,
      /*firstSourceFile*/
      void 0
    ).forEach((file) => addFileToChangeSet(state, file.resolvedPath));
  } else if (oldCompilerOptions) {
    const pendingEmitKind = compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions) ? getBuilderFileEmit(compilerOptions) : getPendingEmitKind(compilerOptions, oldCompilerOptions);
    if (pendingEmitKind !== 0 /* None */) {
      if (!outFilePath) {
        newProgram.getSourceFiles().forEach((f) => {
          if (!state.changedFilesSet.has(f.resolvedPath)) {
            addToAffectedFilesPendingEmit(
              state,
              f.resolvedPath,
              pendingEmitKind
            );
          }
        });
        Debug.assert(!state.seenAffectedFiles || !state.seenAffectedFiles.size);
        state.seenAffectedFiles = state.seenAffectedFiles || /* @__PURE__ */ new Set();
        state.buildInfoEmitPending = true;
      } else {
        state.programEmitPending = state.programEmitPending ? state.programEmitPending | pendingEmitKind : pendingEmitKind;
      }
    }
  }
  return state;
}
function addFileToChangeSet(state, path) {
  state.changedFilesSet.add(path);
  state.buildInfoEmitPending = true;
  state.programEmitPending = void 0;
}
function getEmitSignatureFromOldSignature(options, oldOptions, oldEmitSignature) {
  return !!options.declarationMap === !!oldOptions.declarationMap ? (
    // Use same format of signature
    oldEmitSignature
  ) : (
    // Convert to different format
    isString(oldEmitSignature) ? [oldEmitSignature] : oldEmitSignature[0]
  );
}
function repopulateDiagnostics(diagnostics, newProgram) {
  if (!diagnostics.length) return diagnostics;
  return sameMap(diagnostics, (diag2) => {
    if (isString(diag2.messageText)) return diag2;
    const repopulatedChain = convertOrRepopulateDiagnosticMessageChain(diag2.messageText, diag2.file, newProgram, (chain) => {
      var _a;
      return (_a = chain.repopulateInfo) == null ? void 0 : _a.call(chain);
    });
    return repopulatedChain === diag2.messageText ? diag2 : { ...diag2, messageText: repopulatedChain };
  });
}
function convertOrRepopulateDiagnosticMessageChain(chain, sourceFile, newProgram, repopulateInfo) {
  const info = repopulateInfo(chain);
  if (info) {
    return {
      ...createModuleNotFoundChain(sourceFile, newProgram, info.moduleReference, info.mode, info.packageName || info.moduleReference),
      next: convertOrRepopulateDiagnosticMessageChainArray(chain.next, sourceFile, newProgram, repopulateInfo)
    };
  }
  const next = convertOrRepopulateDiagnosticMessageChainArray(chain.next, sourceFile, newProgram, repopulateInfo);
  return next === chain.next ? chain : { ...chain, next };
}
function convertOrRepopulateDiagnosticMessageChainArray(array, sourceFile, newProgram, repopulateInfo) {
  return sameMap(array, (chain) => convertOrRepopulateDiagnosticMessageChain(chain, sourceFile, newProgram, repopulateInfo));
}
function convertToDiagnostics(diagnostics, diagnosticFilePath, newProgram) {
  if (!diagnostics.length) return emptyArray;
  let buildInfoDirectory;
  return diagnostics.map((diagnostic) => {
    const result = convertToDiagnosticRelatedInformation(diagnostic, diagnosticFilePath, newProgram, toPathInBuildInfoDirectory);
    result.reportsUnnecessary = diagnostic.reportsUnnecessary;
    result.reportsDeprecated = diagnostic.reportDeprecated;
    result.source = diagnostic.source;
    result.skippedOn = diagnostic.skippedOn;
    const { relatedInformation } = diagnostic;
    result.relatedInformation = relatedInformation ? relatedInformation.length ? relatedInformation.map((r) => convertToDiagnosticRelatedInformation(r, diagnosticFilePath, newProgram, toPathInBuildInfoDirectory)) : [] : void 0;
    return result;
  });
  function toPathInBuildInfoDirectory(path) {
    buildInfoDirectory ?? (buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions()), newProgram.getCurrentDirectory())));
    return toPath(path, buildInfoDirectory, newProgram.getCanonicalFileName);
  }
}
function convertToDiagnosticRelatedInformation(diagnostic, diagnosticFilePath, newProgram, toPath3) {
  const { file } = diagnostic;
  const sourceFile = file !== false ? newProgram.getSourceFileByPath(file ? toPath3(file) : diagnosticFilePath) : void 0;
  return {
    ...diagnostic,
    file: sourceFile,
    messageText: isString(diagnostic.messageText) ? diagnostic.messageText : convertOrRepopulateDiagnosticMessageChain(diagnostic.messageText, sourceFile, newProgram, (chain) => chain.info)
  };
}
function releaseCache(state) {
  BuilderState.releaseCache(state);
  state.program = void 0;
}
function backupBuilderProgramEmitState(state) {
  const outFilePath = state.compilerOptions.outFile;
  Debug.assert(!state.changedFilesSet.size || outFilePath);
  return {
    affectedFilesPendingEmit: state.affectedFilesPendingEmit && new Map(state.affectedFilesPendingEmit),
    seenEmittedFiles: state.seenEmittedFiles && new Map(state.seenEmittedFiles),
    programEmitPending: state.programEmitPending,
    emitSignatures: state.emitSignatures && new Map(state.emitSignatures),
    outSignature: state.outSignature,
    latestChangedDtsFile: state.latestChangedDtsFile,
    hasChangedEmitSignature: state.hasChangedEmitSignature,
    changedFilesSet: outFilePath ? new Set(state.changedFilesSet) : void 0,
    buildInfoEmitPending: state.buildInfoEmitPending,
    emitDiagnosticsPerFile: state.emitDiagnosticsPerFile && new Map(state.emitDiagnosticsPerFile)
  };
}
function restoreBuilderProgramEmitState(state, savedEmitState) {
  state.affectedFilesPendingEmit = savedEmitState.affectedFilesPendingEmit;
  state.seenEmittedFiles = savedEmitState.seenEmittedFiles;
  state.programEmitPending = savedEmitState.programEmitPending;
  state.emitSignatures = savedEmitState.emitSignatures;
  state.outSignature = savedEmitState.outSignature;
  state.latestChangedDtsFile = savedEmitState.latestChangedDtsFile;
  state.hasChangedEmitSignature = savedEmitState.hasChangedEmitSignature;
  state.buildInfoEmitPending = savedEmitState.buildInfoEmitPending;
  state.emitDiagnosticsPerFile = savedEmitState.emitDiagnosticsPerFile;
  if (savedEmitState.changedFilesSet) state.changedFilesSet = savedEmitState.changedFilesSet;
}
function assertSourceFileOkWithoutNextAffectedCall(state, sourceFile) {
  Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex - 1] !== sourceFile || !state.semanticDiagnosticsPerFile.has(sourceFile.resolvedPath));
}
function getNextAffectedFile(state, cancellationToken, host) {
  var _a;
  while (true) {
    const { affectedFiles } = state;
    if (affectedFiles) {
      const seenAffectedFiles = state.seenAffectedFiles;
      let affectedFilesIndex = state.affectedFilesIndex;
      while (affectedFilesIndex < affectedFiles.length) {
        const affectedFile = affectedFiles[affectedFilesIndex];
        if (!seenAffectedFiles.has(affectedFile.resolvedPath)) {
          state.affectedFilesIndex = affectedFilesIndex;
          addToAffectedFilesPendingEmit(state, affectedFile.resolvedPath, getBuilderFileEmit(state.compilerOptions));
          handleDtsMayChangeOfAffectedFile(
            state,
            affectedFile,
            cancellationToken,
            host
          );
          return affectedFile;
        }
        affectedFilesIndex++;
      }
      state.changedFilesSet.delete(state.currentChangedFilePath);
      state.currentChangedFilePath = void 0;
      (_a = state.oldSignatures) == null ? void 0 : _a.clear();
      state.affectedFiles = void 0;
    }
    const nextKey = state.changedFilesSet.keys().next();
    if (nextKey.done) {
      return void 0;
    }
    const program = Debug.checkDefined(state.program);
    const compilerOptions = program.getCompilerOptions();
    if (compilerOptions.outFile) {
      Debug.assert(!state.semanticDiagnosticsPerFile);
      return program;
    }
    state.affectedFiles = BuilderState.getFilesAffectedByWithOldState(
      state,
      program,
      nextKey.value,
      cancellationToken,
      host
    );
    state.currentChangedFilePath = nextKey.value;
    state.affectedFilesIndex = 0;
    if (!state.seenAffectedFiles) state.seenAffectedFiles = /* @__PURE__ */ new Set();
  }
}
function clearAffectedFilesPendingEmit(state, emitOnlyDtsFiles) {
  var _a;
  if (!((_a = state.affectedFilesPendingEmit) == null ? void 0 : _a.size)) return;
  if (!emitOnlyDtsFiles) return state.affectedFilesPendingEmit = void 0;
  state.affectedFilesPendingEmit.forEach((emitKind, path) => {
    const pending = emitKind & 7 /* AllJs */;
    if (!pending) state.affectedFilesPendingEmit.delete(path);
    else state.affectedFilesPendingEmit.set(path, pending);
  });
}
function getNextAffectedFilePendingEmit(state, emitOnlyDtsFiles) {
  var _a;
  if (!((_a = state.affectedFilesPendingEmit) == null ? void 0 : _a.size)) return void 0;
  return forEachEntry(state.affectedFilesPendingEmit, (emitKind, path) => {
    var _a2;
    const affectedFile = state.program.getSourceFileByPath(path);
    if (!affectedFile || !sourceFileMayBeEmitted(affectedFile, state.program)) {
      state.affectedFilesPendingEmit.delete(path);
      return void 0;
    }
    const seenKind = (_a2 = state.seenEmittedFiles) == null ? void 0 : _a2.get(affectedFile.resolvedPath);
    let pendingKind = getPendingEmitKind(emitKind, seenKind);
    if (emitOnlyDtsFiles) pendingKind = pendingKind & 24 /* AllDts */;
    if (pendingKind) return { affectedFile, emitKind: pendingKind };
  });
}
function getNextPendingEmitDiagnosticsFile(state) {
  var _a;
  if (!((_a = state.emitDiagnosticsPerFile) == null ? void 0 : _a.size)) return void 0;
  return forEachEntry(state.emitDiagnosticsPerFile, (diagnostics, path) => {
    var _a2;
    const affectedFile = state.program.getSourceFileByPath(path);
    if (!affectedFile || !sourceFileMayBeEmitted(affectedFile, state.program)) {
      state.emitDiagnosticsPerFile.delete(path);
      return void 0;
    }
    const seenKind = ((_a2 = state.seenEmittedFiles) == null ? void 0 : _a2.get(affectedFile.resolvedPath)) || 0 /* None */;
    if (!(seenKind & 24 /* AllDts */)) return { affectedFile, diagnostics, seenKind };
  });
}
function removeDiagnosticsOfLibraryFiles(state) {
  if (!state.cleanedDiagnosticsOfLibFiles) {
    state.cleanedDiagnosticsOfLibFiles = true;
    const program = Debug.checkDefined(state.program);
    const options = program.getCompilerOptions();
    forEach(program.getSourceFiles(), (f) => program.isSourceFileDefaultLibrary(f) && !skipTypeChecking(f, options, program) && removeSemanticDiagnosticsOf(state, f.resolvedPath));
  }
}
function handleDtsMayChangeOfAffectedFile(state, affectedFile, cancellationToken, host) {
  removeSemanticDiagnosticsOf(state, affectedFile.resolvedPath);
  if (state.allFilesExcludingDefaultLibraryFile === state.affectedFiles) {
    removeDiagnosticsOfLibraryFiles(state);
    BuilderState.updateShapeSignature(
      state,
      Debug.checkDefined(state.program),
      affectedFile,
      cancellationToken,
      host
    );
    return;
  }
  if (state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) return;
  handleDtsMayChangeOfReferencingExportOfAffectedFile(
    state,
    affectedFile,
    cancellationToken,
    host
  );
}
function handleDtsMayChangeOf(state, path, invalidateJsFiles, cancellationToken, host) {
  removeSemanticDiagnosticsOf(state, path);
  if (!state.changedFilesSet.has(path)) {
    const program = Debug.checkDefined(state.program);
    const sourceFile = program.getSourceFileByPath(path);
    if (sourceFile) {
      BuilderState.updateShapeSignature(
        state,
        program,
        sourceFile,
        cancellationToken,
        host,
        /*useFileVersionAsSignature*/
        true
      );
      if (invalidateJsFiles) {
        addToAffectedFilesPendingEmit(state, path, getBuilderFileEmit(state.compilerOptions));
      } else if (getEmitDeclarations(state.compilerOptions)) {
        addToAffectedFilesPendingEmit(state, path, state.compilerOptions.declarationMap ? 24 /* AllDts */ : 8 /* Dts */);
      }
    }
  }
}
function removeSemanticDiagnosticsOf(state, path) {
  if (!state.semanticDiagnosticsFromOldState) {
    return true;
  }
  state.semanticDiagnosticsFromOldState.delete(path);
  state.semanticDiagnosticsPerFile.delete(path);
  return !state.semanticDiagnosticsFromOldState.size;
}
function isChangedSignature(state, path) {
  const oldSignature = Debug.checkDefined(state.oldSignatures).get(path) || void 0;
  const newSignature = Debug.checkDefined(state.fileInfos.get(path)).signature;
  return newSignature !== oldSignature;
}
function handleDtsMayChangeOfGlobalScope(state, filePath, invalidateJsFiles, cancellationToken, host) {
  var _a;
  if (!((_a = state.fileInfos.get(filePath)) == null ? void 0 : _a.affectsGlobalScope)) return false;
  BuilderState.getAllFilesExcludingDefaultLibraryFile(
    state,
    state.program,
    /*firstSourceFile*/
    void 0
  ).forEach(
    (file) => handleDtsMayChangeOf(
      state,
      file.resolvedPath,
      invalidateJsFiles,
      cancellationToken,
      host
    )
  );
  removeDiagnosticsOfLibraryFiles(state);
  return true;
}
function handleDtsMayChangeOfReferencingExportOfAffectedFile(state, affectedFile, cancellationToken, host) {
  var _a, _b;
  if (!state.referencedMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) return;
  if (!isChangedSignature(state, affectedFile.resolvedPath)) return;
  if (getIsolatedModules(state.compilerOptions)) {
    const seenFileNamesMap = /* @__PURE__ */ new Map();
    seenFileNamesMap.set(affectedFile.resolvedPath, true);
    const queue = BuilderState.getReferencedByPaths(state, affectedFile.resolvedPath);
    while (queue.length > 0) {
      const currentPath = queue.pop();
      if (!seenFileNamesMap.has(currentPath)) {
        seenFileNamesMap.set(currentPath, true);
        if (handleDtsMayChangeOfGlobalScope(
          state,
          currentPath,
          /*invalidateJsFiles*/
          false,
          cancellationToken,
          host
        )) return;
        handleDtsMayChangeOf(
          state,
          currentPath,
          /*invalidateJsFiles*/
          false,
          cancellationToken,
          host
        );
        if (isChangedSignature(state, currentPath)) {
          const currentSourceFile = Debug.checkDefined(state.program).getSourceFileByPath(currentPath);
          queue.push(...BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath));
        }
      }
    }
  }
  const seenFileAndExportsOfFile = /* @__PURE__ */ new Set();
  const invalidateJsFiles = !!((_a = affectedFile.symbol) == null ? void 0 : _a.exports) && !!forEachEntry(
    affectedFile.symbol.exports,
    (exported) => {
      if ((exported.flags & 128 /* ConstEnum */) !== 0) return true;
      const aliased = skipAlias(exported, state.program.getTypeChecker());
      if (aliased === exported) return false;
      return (aliased.flags & 128 /* ConstEnum */) !== 0 && some(aliased.declarations, (d) => getSourceFileOfNode(d) === affectedFile);
    }
  );
  (_b = state.referencedMap.getKeys(affectedFile.resolvedPath)) == null ? void 0 : _b.forEach((exportedFromPath) => {
    if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, invalidateJsFiles, cancellationToken, host)) return true;
    const references = state.referencedMap.getKeys(exportedFromPath);
    return references && forEachKey(references, (filePath) => handleDtsMayChangeOfFileAndExportsOfFile(
      state,
      filePath,
      invalidateJsFiles,
      seenFileAndExportsOfFile,
      cancellationToken,
      host
    ));
  });
}
function handleDtsMayChangeOfFileAndExportsOfFile(state, filePath, invalidateJsFiles, seenFileAndExportsOfFile, cancellationToken, host) {
  var _a;
  if (!tryAddToSet(seenFileAndExportsOfFile, filePath)) return void 0;
  if (handleDtsMayChangeOfGlobalScope(state, filePath, invalidateJsFiles, cancellationToken, host)) return true;
  handleDtsMayChangeOf(state, filePath, invalidateJsFiles, cancellationToken, host);
  (_a = state.referencedMap.getKeys(filePath)) == null ? void 0 : _a.forEach(
    (referencingFilePath) => handleDtsMayChangeOfFileAndExportsOfFile(
      state,
      referencingFilePath,
      invalidateJsFiles,
      seenFileAndExportsOfFile,
      cancellationToken,
      host
    )
  );
  return void 0;
}
function getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken) {
  return concatenate(
    getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken),
    Debug.checkDefined(state.program).getProgramDiagnostics(sourceFile)
  );
}
function getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken) {
  const path = sourceFile.resolvedPath;
  if (state.semanticDiagnosticsPerFile) {
    const cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
    if (cachedDiagnostics) {
      return filterSemanticDiagnostics(cachedDiagnostics, state.compilerOptions);
    }
  }
  const diagnostics = Debug.checkDefined(state.program).getBindAndCheckDiagnostics(sourceFile, cancellationToken);
  if (state.semanticDiagnosticsPerFile) {
    state.semanticDiagnosticsPerFile.set(path, diagnostics);
  }
  return filterSemanticDiagnostics(diagnostics, state.compilerOptions);
}
function isProgramBundleEmitBuildInfo(info) {
  var _a;
  return !!((_a = info.options) == null ? void 0 : _a.outFile);
}
function getBuildInfo2(state) {
  var _a, _b;
  const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
  const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions), currentDirectory));
  const latestChangedDtsFile = state.latestChangedDtsFile ? relativeToBuildInfoEnsuringAbsolutePath(state.latestChangedDtsFile) : void 0;
  const fileNames = [];
  const fileNameToFileId = /* @__PURE__ */ new Map();
  const rootFileNames = new Set(state.program.getRootFileNames().map((f) => toPath(f, currentDirectory, state.program.getCanonicalFileName)));
  const root = [];
  if (state.compilerOptions.outFile) {
    const fileInfos2 = arrayFrom(state.fileInfos.entries(), ([key, value]) => {
      const fileId = toFileId(key);
      tryAddRoot(key, fileId);
      return value.impliedFormat ? { version: value.version, impliedFormat: value.impliedFormat, signature: void 0, affectsGlobalScope: void 0 } : value.version;
    });
    const program2 = {
      fileNames,
      fileInfos: fileInfos2,
      root,
      resolvedRoot: toResolvedRoot(),
      options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
      outSignature: state.outSignature,
      latestChangedDtsFile,
      pendingEmit: !state.programEmitPending ? void 0 : (
        // Pending is undefined or None is encoded as undefined
        state.programEmitPending === getBuilderFileEmit(state.compilerOptions) ? false : (
          // Pending emit is same as deteremined by compilerOptions
          state.programEmitPending
        )
      )
      // Actual value
    };
    return createBuildInfo(program2);
  }
  let fileIdsList;
  let fileNamesToFileIdListId;
  let emitSignatures;
  const fileInfos = arrayFrom(state.fileInfos.entries(), ([key, value]) => {
    var _a2, _b2;
    const fileId = toFileId(key);
    tryAddRoot(key, fileId);
    Debug.assert(fileNames[fileId - 1] === relativeToBuildInfo(key));
    const oldSignature = (_a2 = state.oldSignatures) == null ? void 0 : _a2.get(key);
    const actualSignature = oldSignature !== void 0 ? oldSignature || void 0 : value.signature;
    if (state.compilerOptions.composite) {
      const file = state.program.getSourceFileByPath(key);
      if (!isJsonSourceFile(file) && sourceFileMayBeEmitted(file, state.program)) {
        const emitSignature = (_b2 = state.emitSignatures) == null ? void 0 : _b2.get(key);
        if (emitSignature !== actualSignature) {
          emitSignatures = append(
            emitSignatures,
            emitSignature === void 0 ? fileId : (
              // There is no emit, encode as false
              // fileId, signature: emptyArray if signature only differs in dtsMap option than our own compilerOptions otherwise EmitSignature
              [fileId, !isString(emitSignature) && emitSignature[0] === actualSignature ? emptyArray : emitSignature]
            )
          );
        }
      }
    }
    return value.version === actualSignature ? value.affectsGlobalScope || value.impliedFormat ? (
      // If file version is same as signature, dont serialize signature
      { version: value.version, signature: void 0, affectsGlobalScope: value.affectsGlobalScope, impliedFormat: value.impliedFormat }
    ) : (
      // If file info only contains version and signature and both are same we can just write string
      value.version
    ) : actualSignature !== void 0 ? (
      // If signature is not same as version, encode signature in the fileInfo
      oldSignature === void 0 ? (
        // If we havent computed signature, use fileInfo as is
        value
      ) : (
        // Serialize fileInfo with new updated signature
        { version: value.version, signature: actualSignature, affectsGlobalScope: value.affectsGlobalScope, impliedFormat: value.impliedFormat }
      )
    ) : (
      // Signature of the FileInfo is undefined, serialize it as false
      { version: value.version, signature: false, affectsGlobalScope: value.affectsGlobalScope, impliedFormat: value.impliedFormat }
    );
  });
  let referencedMap;
  if ((_a = state.referencedMap) == null ? void 0 : _a.size()) {
    referencedMap = arrayFrom(state.referencedMap.keys()).sort(compareStringsCaseSensitive).map((key) => [
      toFileId(key),
      toFileIdListId(state.referencedMap.getValues(key))
    ]);
  }
  const semanticDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics();
  let affectedFilesPendingEmit;
  if ((_b = state.affectedFilesPendingEmit) == null ? void 0 : _b.size) {
    const fullEmitForOptions = getBuilderFileEmit(state.compilerOptions);
    const seenFiles = /* @__PURE__ */ new Set();
    for (const path of arrayFrom(state.affectedFilesPendingEmit.keys()).sort(compareStringsCaseSensitive)) {
      if (tryAddToSet(seenFiles, path)) {
        const file = state.program.getSourceFileByPath(path);
        if (!file || !sourceFileMayBeEmitted(file, state.program)) continue;
        const fileId = toFileId(path), pendingEmit = state.affectedFilesPendingEmit.get(path);
        affectedFilesPendingEmit = append(
          affectedFilesPendingEmit,
          pendingEmit === fullEmitForOptions ? fileId : (
            // Pending full emit per options
            pendingEmit === 8 /* Dts */ ? [fileId] : (
              // Pending on Dts only
              [fileId, pendingEmit]
            )
          )
          // Anything else
        );
      }
    }
  }
  let changeFileSet;
  if (state.changedFilesSet.size) {
    for (const path of arrayFrom(state.changedFilesSet.keys()).sort(compareStringsCaseSensitive)) {
      changeFileSet = append(changeFileSet, toFileId(path));
    }
  }
  const emitDiagnosticsPerFile = convertToProgramBuildInfoEmitDiagnostics();
  const program = {
    fileNames,
    fileInfos,
    root,
    resolvedRoot: toResolvedRoot(),
    options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
    fileIdsList,
    referencedMap,
    semanticDiagnosticsPerFile,
    emitDiagnosticsPerFile,
    affectedFilesPendingEmit,
    changeFileSet,
    emitSignatures,
    latestChangedDtsFile
  };
  return createBuildInfo(program);
  function relativeToBuildInfoEnsuringAbsolutePath(path) {
    return relativeToBuildInfo(getNormalizedAbsolutePath(path, currentDirectory));
  }
  function relativeToBuildInfo(path) {
    return ensurePathIsNonModuleName(getRelativePathFromDirectory(buildInfoDirectory, path, state.program.getCanonicalFileName));
  }
  function toFileId(path) {
    let fileId = fileNameToFileId.get(path);
    if (fileId === void 0) {
      fileNames.push(relativeToBuildInfo(path));
      fileNameToFileId.set(path, fileId = fileNames.length);
    }
    return fileId;
  }
  function toFileIdListId(set) {
    const fileIds = arrayFrom(set.keys(), toFileId).sort(compareValues);
    const key = fileIds.join();
    let fileIdListId = fileNamesToFileIdListId == null ? void 0 : fileNamesToFileIdListId.get(key);
    if (fileIdListId === void 0) {
      fileIdsList = append(fileIdsList, fileIds);
      (fileNamesToFileIdListId ?? (fileNamesToFileIdListId = /* @__PURE__ */ new Map())).set(key, fileIdListId = fileIdsList.length);
    }
    return fileIdListId;
  }
  function tryAddRoot(path, fileId) {
    const file = state.program.getSourceFile(path);
    if (!state.program.getFileIncludeReasons().get(file.path).some((r) => r.kind === 0 /* RootFile */)) return;
    if (!root.length) return root.push(fileId);
    const last2 = root[root.length - 1];
    const isLastStartEnd = isArray(last2);
    if (isLastStartEnd && last2[1] === fileId - 1) return last2[1] = fileId;
    if (isLastStartEnd || root.length === 1 || last2 !== fileId - 1) return root.push(fileId);
    const lastButOne = root[root.length - 2];
    if (!isNumber(lastButOne) || lastButOne !== last2 - 1) return root.push(fileId);
    root[root.length - 2] = [lastButOne, fileId];
    return root.length = root.length - 1;
  }
  function toResolvedRoot() {
    let result;
    rootFileNames.forEach((path) => {
      const file = state.program.getSourceFileByPath(path);
      if (file && path !== file.resolvedPath) {
        result = append(result, [toFileId(file.resolvedPath), toFileId(path)]);
      }
    });
    return result;
  }
  function convertToProgramBuildInfoCompilerOptions(options) {
    let result;
    const { optionsNameMap } = getOptionsNameMap();
    for (const name of getOwnKeys(options).sort(compareStringsCaseSensitive)) {
      const optionInfo = optionsNameMap.get(name.toLowerCase());
      if (optionInfo == null ? void 0 : optionInfo.affectsBuildInfo) {
        (result || (result = {}))[name] = convertToReusableCompilerOptionValue(
          optionInfo,
          options[name]
        );
      }
    }
    return result;
  }
  function convertToReusableCompilerOptionValue(option, value) {
    if (option) {
      Debug.assert(option.type !== "listOrElement");
      if (option.type === "list") {
        const values = value;
        if (option.element.isFilePath && values.length) {
          return values.map(relativeToBuildInfoEnsuringAbsolutePath);
        }
      } else if (option.isFilePath) {
        return relativeToBuildInfoEnsuringAbsolutePath(value);
      }
    }
    return value;
  }
  function convertToProgramBuildInfoDiagnostics() {
    let result;
    state.fileInfos.forEach((_value, key) => {
      var _a2;
      const value = (_a2 = state.semanticDiagnosticsPerFile) == null ? void 0 : _a2.get(key);
      if (!value) {
        if (!state.changedFilesSet.has(key)) result = append(result, toFileId(key));
      } else if (value.length) {
        result = append(result, [
          toFileId(key),
          convertToReusableDiagnostics(value, key)
        ]);
      }
    });
    return result;
  }
  function convertToProgramBuildInfoEmitDiagnostics() {
    var _a2;
    let result;
    if (!((_a2 = state.emitDiagnosticsPerFile) == null ? void 0 : _a2.size)) return result;
    for (const key of arrayFrom(state.emitDiagnosticsPerFile.keys()).sort(compareStringsCaseSensitive)) {
      const value = state.emitDiagnosticsPerFile.get(key);
      result = append(result, [
        toFileId(key),
        convertToReusableDiagnostics(value, key)
      ]);
    }
    return result;
  }
  function convertToReusableDiagnostics(diagnostics, diagnosticFilePath) {
    Debug.assert(!!diagnostics.length);
    return diagnostics.map((diagnostic) => {
      const result = convertToReusableDiagnosticRelatedInformation(diagnostic, diagnosticFilePath);
      result.reportsUnnecessary = diagnostic.reportsUnnecessary;
      result.reportDeprecated = diagnostic.reportsDeprecated;
      result.source = diagnostic.source;
      result.skippedOn = diagnostic.skippedOn;
      const { relatedInformation } = diagnostic;
      result.relatedInformation = relatedInformation ? relatedInformation.length ? relatedInformation.map((r) => convertToReusableDiagnosticRelatedInformation(r, diagnosticFilePath)) : [] : void 0;
      return result;
    });
  }
  function convertToReusableDiagnosticRelatedInformation(diagnostic, diagnosticFilePath) {
    const { file } = diagnostic;
    return {
      ...diagnostic,
      file: file ? file.resolvedPath === diagnosticFilePath ? void 0 : relativeToBuildInfo(file.resolvedPath) : false,
      messageText: isString(diagnostic.messageText) ? diagnostic.messageText : convertToReusableDiagnosticMessageChain(diagnostic.messageText)
    };
  }
  function convertToReusableDiagnosticMessageChain(chain) {
    if (chain.repopulateInfo) {
      return {
        info: chain.repopulateInfo(),
        next: convertToReusableDiagnosticMessageChainArray(chain.next)
      };
    }
    const next = convertToReusableDiagnosticMessageChainArray(chain.next);
    return next === chain.next ? chain : { ...chain, next };
  }
  function convertToReusableDiagnosticMessageChainArray(array) {
    if (!array) return array;
    return forEach(array, (chain, index) => {
      const reusable = convertToReusableDiagnosticMessageChain(chain);
      if (chain === reusable) return void 0;
      const result = index > 0 ? array.slice(0, index - 1) : [];
      result.push(reusable);
      for (let i = index + 1; i < array.length; i++) {
        result.push(convertToReusableDiagnosticMessageChain(array[i]));
      }
      return result;
    }) || array;
  }
}
function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
  let host;
  let newProgram;
  let oldProgram;
  if (newProgramOrRootNames === void 0) {
    Debug.assert(hostOrOptions === void 0);
    host = oldProgramOrHost;
    oldProgram = configFileParsingDiagnosticsOrOldProgram;
    Debug.assert(!!oldProgram);
    newProgram = oldProgram.getProgram();
  } else if (isArray(newProgramOrRootNames)) {
    oldProgram = configFileParsingDiagnosticsOrOldProgram;
    newProgram = createProgram({
      rootNames: newProgramOrRootNames,
      options: hostOrOptions,
      host: oldProgramOrHost,
      oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),
      configFileParsingDiagnostics,
      projectReferences
    });
    host = oldProgramOrHost;
  } else {
    newProgram = newProgramOrRootNames;
    host = hostOrOptions;
    oldProgram = oldProgramOrHost;
    configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
  }
  return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
}
function getTextHandlingSourceMapForSignature(text, data) {
  return (data == null ? void 0 : data.sourceMapUrlPos) !== void 0 ? text.substring(0, data.sourceMapUrlPos) : text;
}
function computeSignatureWithDiagnostics(program, sourceFile, text, host, data) {
  var _a;
  text = getTextHandlingSourceMapForSignature(text, data);
  let sourceFileDirectory;
  if ((_a = data == null ? void 0 : data.diagnostics) == null ? void 0 : _a.length) {
    text += data.diagnostics.map((diagnostic) => `${locationInfo(diagnostic)}${DiagnosticCategory[diagnostic.category]}${diagnostic.code}: ${flattenDiagnosticMessageText2(diagnostic.messageText)}`).join("\n");
  }
  return (host.createHash ?? generateDjb2Hash)(text);
  function flattenDiagnosticMessageText2(diagnostic) {
    return isString(diagnostic) ? diagnostic : diagnostic === void 0 ? "" : !diagnostic.next ? diagnostic.messageText : diagnostic.messageText + diagnostic.next.map(flattenDiagnosticMessageText2).join("\n");
  }
  function locationInfo(diagnostic) {
    if (diagnostic.file.resolvedPath === sourceFile.resolvedPath) return `(${diagnostic.start},${diagnostic.length})`;
    if (sourceFileDirectory === void 0) sourceFileDirectory = getDirectoryPath(sourceFile.resolvedPath);
    return `${ensurePathIsNonModuleName(getRelativePathFromDirectory(
      sourceFileDirectory,
      diagnostic.file.resolvedPath,
      program.getCanonicalFileName
    ))}(${diagnostic.start},${diagnostic.length})`;
  }
}
function computeSignature(text, host, data) {
  return (host.createHash ?? generateDjb2Hash)(getTextHandlingSourceMapForSignature(text, data));
}
function createBuilderProgram(kind, { newProgram, host, oldProgram, configFileParsingDiagnostics }) {
  let oldState = oldProgram && oldProgram.getState();
  if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) {
    newProgram = void 0;
    oldState = void 0;
    return oldProgram;
  }
  const state = createBuilderProgramState(newProgram, oldState);
  newProgram.getBuildInfo = () => getBuildInfo2(state);
  newProgram = void 0;
  oldProgram = void 0;
  oldState = void 0;
  const getState = () => state;
  const builderProgram = createRedirectedBuilderProgram(getState, configFileParsingDiagnostics);
  builderProgram.getState = getState;
  builderProgram.saveEmitState = () => backupBuilderProgramEmitState(state);
  builderProgram.restoreEmitState = (saved) => restoreBuilderProgramEmitState(state, saved);
  builderProgram.hasChangedEmitSignature = () => !!state.hasChangedEmitSignature;
  builderProgram.getAllDependencies = (sourceFile) => BuilderState.getAllDependencies(state, Debug.checkDefined(state.program), sourceFile);
  builderProgram.getSemanticDiagnostics = getSemanticDiagnostics;
  builderProgram.emit = emit;
  builderProgram.releaseProgram = () => releaseCache(state);
  if (kind === 0 /* SemanticDiagnosticsBuilderProgram */) {
    builderProgram.getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
  } else if (kind === 1 /* EmitAndSemanticDiagnosticsBuilderProgram */) {
    builderProgram.getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
    builderProgram.emitNextAffectedFile = emitNextAffectedFile;
    builderProgram.emitBuildInfo = emitBuildInfo;
  } else {
    notImplemented();
  }
  return builderProgram;
  function emitBuildInfo(writeFile2, cancellationToken) {
    if (state.buildInfoEmitPending) {
      const result = Debug.checkDefined(state.program).emitBuildInfo(writeFile2 || maybeBind(host, host.writeFile), cancellationToken);
      state.buildInfoEmitPending = false;
      return result;
    }
    return emitSkippedWithNoDiagnostics;
  }
  function emitNextAffectedFile(writeFile2, cancellationToken, emitOnlyDtsFiles, customTransformers) {
    var _a, _b, _c;
    let affected = getNextAffectedFile(state, cancellationToken, host);
    const programEmitKind = getBuilderFileEmit(state.compilerOptions);
    let emitKind = emitOnlyDtsFiles ? programEmitKind & 24 /* AllDts */ : programEmitKind;
    if (!affected) {
      if (!state.compilerOptions.outFile) {
        const pendingAffectedFile = getNextAffectedFilePendingEmit(state, emitOnlyDtsFiles);
        if (!pendingAffectedFile) {
          const pendingForDiagnostics = getNextPendingEmitDiagnosticsFile(state);
          if (pendingForDiagnostics) {
            (state.seenEmittedFiles ?? (state.seenEmittedFiles = /* @__PURE__ */ new Map())).set(pendingForDiagnostics.affectedFile.resolvedPath, pendingForDiagnostics.seenKind | 24 /* AllDts */);
            return {
              result: { emitSkipped: true, diagnostics: pendingForDiagnostics.diagnostics },
              affected: pendingForDiagnostics.affectedFile
            };
          }
          if (!state.buildInfoEmitPending) return void 0;
          const affected2 = state.program;
          const result2 = affected2.emitBuildInfo(writeFile2 || maybeBind(host, host.writeFile), cancellationToken);
          state.buildInfoEmitPending = false;
          return { result: result2, affected: affected2 };
        }
        ({ affectedFile: affected, emitKind } = pendingAffectedFile);
      } else {
        if (!state.programEmitPending) return void 0;
        emitKind = state.programEmitPending;
        if (emitOnlyDtsFiles) emitKind = emitKind & 24 /* AllDts */;
        if (!emitKind) return void 0;
        affected = state.program;
      }
    }
    let emitOnly;
    if (emitKind & 7 /* AllJs */) emitOnly = 0 /* Js */;
    if (emitKind & 24 /* AllDts */) emitOnly = emitOnly === void 0 ? 1 /* Dts */ : void 0;
    if (affected === state.program) {
      state.programEmitPending = state.changedFilesSet.size ? getPendingEmitKind(programEmitKind, emitKind) : state.programEmitPending ? getPendingEmitKind(state.programEmitPending, emitKind) : void 0;
    }
    const result = state.program.emit(
      affected === state.program ? void 0 : affected,
      getWriteFileCallback(writeFile2, customTransformers),
      cancellationToken,
      emitOnly,
      customTransformers
    );
    if (affected !== state.program) {
      const affectedSourceFile = affected;
      state.seenAffectedFiles.add(affectedSourceFile.resolvedPath);
      if (state.affectedFilesIndex !== void 0) state.affectedFilesIndex++;
      state.buildInfoEmitPending = true;
      const existing = ((_a = state.seenEmittedFiles) == null ? void 0 : _a.get(affectedSourceFile.resolvedPath)) || 0 /* None */;
      (state.seenEmittedFiles ?? (state.seenEmittedFiles = /* @__PURE__ */ new Map())).set(affectedSourceFile.resolvedPath, emitKind | existing);
      const existingPending = ((_b = state.affectedFilesPendingEmit) == null ? void 0 : _b.get(affectedSourceFile.resolvedPath)) || programEmitKind;
      const pendingKind = getPendingEmitKind(existingPending, emitKind | existing);
      if (pendingKind) (state.affectedFilesPendingEmit ?? (state.affectedFilesPendingEmit = /* @__PURE__ */ new Map())).set(affectedSourceFile.resolvedPath, pendingKind);
      else (_c = state.affectedFilesPendingEmit) == null ? void 0 : _c.delete(affectedSourceFile.resolvedPath);
      if (result.diagnostics.length) (state.emitDiagnosticsPerFile ?? (state.emitDiagnosticsPerFile = /* @__PURE__ */ new Map())).set(affectedSourceFile.resolvedPath, result.diagnostics);
    } else {
      state.changedFilesSet.clear();
    }
    return { result, affected };
  }
  function getWriteFileCallback(writeFile2, customTransformers) {
    if (!getEmitDeclarations(state.compilerOptions)) return writeFile2 || maybeBind(host, host.writeFile);
    return (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => {
      var _a, _b, _c;
      if (isDeclarationFileName(fileName)) {
        if (!state.compilerOptions.outFile) {
          Debug.assert((sourceFiles == null ? void 0 : sourceFiles.length) === 1);
          let emitSignature;
          if (!customTransformers) {
            const file = sourceFiles[0];
            const info = state.fileInfos.get(file.resolvedPath);
            if (info.signature === file.version) {
              const signature = computeSignatureWithDiagnostics(
                state.program,
                file,
                text,
                host,
                data
              );
              if (!((_a = data == null ? void 0 : data.diagnostics) == null ? void 0 : _a.length)) emitSignature = signature;
              if (signature !== file.version) {
                if (host.storeSignatureInfo) (state.signatureInfo ?? (state.signatureInfo = /* @__PURE__ */ new Map())).set(file.resolvedPath, 1 /* StoredSignatureAtEmit */);
                if (state.affectedFiles) {
                  const existing = (_b = state.oldSignatures) == null ? void 0 : _b.get(file.resolvedPath);
                  if (existing === void 0) (state.oldSignatures ?? (state.oldSignatures = /* @__PURE__ */ new Map())).set(file.resolvedPath, info.signature || false);
                  info.signature = signature;
                } else {
                  info.signature = signature;
                }
              }
            }
          }
          if (state.compilerOptions.composite) {
            const filePath = sourceFiles[0].resolvedPath;
            emitSignature = handleNewSignature((_c = state.emitSignatures) == null ? void 0 : _c.get(filePath), emitSignature);
            if (!emitSignature) return;
            (state.emitSignatures ?? (state.emitSignatures = /* @__PURE__ */ new Map())).set(filePath, emitSignature);
          }
        } else if (state.compilerOptions.composite) {
          const newSignature = handleNewSignature(
            state.outSignature,
            /*newSignature*/
            void 0
          );
          if (!newSignature) return;
          state.outSignature = newSignature;
        }
      }
      if (writeFile2) writeFile2(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
      else if (host.writeFile) host.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
      else state.program.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
      function handleNewSignature(oldSignatureFormat, newSignature) {
        const oldSignature = !oldSignatureFormat || isString(oldSignatureFormat) ? oldSignatureFormat : oldSignatureFormat[0];
        newSignature ?? (newSignature = computeSignature(text, host, data));
        if (newSignature === oldSignature) {
          if (oldSignatureFormat === oldSignature) return void 0;
          else if (data) data.differsOnlyInMap = true;
          else data = { differsOnlyInMap: true };
        } else {
          state.hasChangedEmitSignature = true;
          state.latestChangedDtsFile = fileName;
        }
        return newSignature;
      }
    };
  }
  function emit(targetSourceFile, writeFile2, cancellationToken, emitOnlyDtsFiles, customTransformers) {
    if (kind === 1 /* EmitAndSemanticDiagnosticsBuilderProgram */) {
      assertSourceFileOkWithoutNextAffectedCall(state, targetSourceFile);
    }
    const result = handleNoEmitOptions(builderProgram, targetSourceFile, writeFile2, cancellationToken);
    if (result) return result;
    if (!targetSourceFile) {
      if (kind === 1 /* EmitAndSemanticDiagnosticsBuilderProgram */) {
        let sourceMaps = [];
        let emitSkipped = false;
        let diagnostics;
        let emittedFiles = [];
        let affectedEmitResult;
        while (affectedEmitResult = emitNextAffectedFile(writeFile2, cancellationToken, emitOnlyDtsFiles, customTransformers)) {
          emitSkipped = emitSkipped || affectedEmitResult.result.emitSkipped;
          diagnostics = addRange(diagnostics, affectedEmitResult.result.diagnostics);
          emittedFiles = addRange(emittedFiles, affectedEmitResult.result.emittedFiles);
          sourceMaps = addRange(sourceMaps, affectedEmitResult.result.sourceMaps);
        }
        return {
          emitSkipped,
          diagnostics: diagnostics || emptyArray,
          emittedFiles,
          sourceMaps
        };
      } else {
        clearAffectedFilesPendingEmit(state, emitOnlyDtsFiles);
      }
    }
    return Debug.checkDefined(state.program).emit(
      targetSourceFile,
      getWriteFileCallback(writeFile2, customTransformers),
      cancellationToken,
      emitOnlyDtsFiles,
      customTransformers
    );
  }
  function getSemanticDiagnosticsOfNextAffectedFile(cancellationToken, ignoreSourceFile) {
    while (true) {
      const affected = getNextAffectedFile(state, cancellationToken, host);
      let result;
      if (!affected) return void 0;
      else if (affected !== state.program) {
        const affectedSourceFile = affected;
        if (!ignoreSourceFile || !ignoreSourceFile(affectedSourceFile)) {
          result = getSemanticDiagnosticsOfFile(state, affectedSourceFile, cancellationToken);
        }
        state.seenAffectedFiles.add(affectedSourceFile.resolvedPath);
        state.affectedFilesIndex++;
        state.buildInfoEmitPending = true;
        if (!result) continue;
      } else {
        result = state.program.getSemanticDiagnostics(
          /*sourceFile*/
          void 0,
          cancellationToken
        );
        state.changedFilesSet.clear();
        state.programEmitPending = getBuilderFileEmit(state.compilerOptions);
      }
      return { result, affected };
    }
  }
  function getSemanticDiagnostics(sourceFile, cancellationToken) {
    assertSourceFileOkWithoutNextAffectedCall(state, sourceFile);
    const compilerOptions = Debug.checkDefined(state.program).getCompilerOptions();
    if (compilerOptions.outFile) {
      Debug.assert(!state.semanticDiagnosticsPerFile);
      return Debug.checkDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken);
    }
    if (sourceFile) {
      return getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken);
    }
    while (getSemanticDiagnosticsOfNextAffectedFile(cancellationToken)) {
    }
    let diagnostics;
    for (const sourceFile2 of Debug.checkDefined(state.program).getSourceFiles()) {
      diagnostics = addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile2, cancellationToken));
    }
    return diagnostics || emptyArray;
  }
}
function addToAffectedFilesPendingEmit(state, affectedFilePendingEmit, kind) {
  var _a, _b;
  const existingKind = ((_a = state.affectedFilesPendingEmit) == null ? void 0 : _a.get(affectedFilePendingEmit)) || 0 /* None */;
  (state.affectedFilesPendingEmit ?? (state.affectedFilesPendingEmit = /* @__PURE__ */ new Map())).set(affectedFilePendingEmit, existingKind | kind);
  (_b = state.emitDiagnosticsPerFile) == null ? void 0 : _b.delete(affectedFilePendingEmit);
}
function toBuilderStateFileInfoForMultiEmit(fileInfo) {
  return isString(fileInfo) ? { version: fileInfo, signature: fileInfo, affectsGlobalScope: void 0, impliedFormat: void 0 } : isString(fileInfo.signature) ? fileInfo : { version: fileInfo.version, signature: fileInfo.signature === false ? void 0 : fileInfo.version, affectsGlobalScope: fileInfo.affectsGlobalScope, impliedFormat: fileInfo.impliedFormat };
}
function toBuilderFileEmit(value, fullEmitForOptions) {
  return isNumber(value) ? fullEmitForOptions : value[1] || 8 /* Dts */;
}
function toProgramEmitPending(value, options) {
  return !value ? getBuilderFileEmit(options || {}) : value;
}
function createBuilderProgramUsingProgramBuildInfo(buildInfo, buildInfoPath, host) {
  var _a, _b, _c, _d;
  const program = buildInfo.program;
  const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
  const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
  let state;
  const filePaths = (_a = program.fileNames) == null ? void 0 : _a.map(toPathInBuildInfoDirectory);
  let filePathsSetList;
  const latestChangedDtsFile = program.latestChangedDtsFile ? toAbsolutePath(program.latestChangedDtsFile) : void 0;
  if (isProgramBundleEmitBuildInfo(program)) {
    const fileInfos = /* @__PURE__ */ new Map();
    program.fileInfos.forEach((fileInfo, index) => {
      const path = toFilePath(index + 1);
      fileInfos.set(path, isString(fileInfo) ? { version: fileInfo, signature: void 0, affectsGlobalScope: void 0, impliedFormat: void 0 } : fileInfo);
    });
    state = {
      fileInfos,
      compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
      latestChangedDtsFile,
      outSignature: program.outSignature,
      programEmitPending: program.pendingEmit === void 0 ? void 0 : toProgramEmitPending(program.pendingEmit, program.options)
    };
  } else {
    filePathsSetList = (_b = program.fileIdsList) == null ? void 0 : _b.map((fileIds) => new Set(fileIds.map(toFilePath)));
    const fileInfos = /* @__PURE__ */ new Map();
    const emitSignatures = ((_c = program.options) == null ? void 0 : _c.composite) && !program.options.outFile ? /* @__PURE__ */ new Map() : void 0;
    program.fileInfos.forEach((fileInfo, index) => {
      const path = toFilePath(index + 1);
      const stateFileInfo = toBuilderStateFileInfoForMultiEmit(fileInfo);
      fileInfos.set(path, stateFileInfo);
      if (emitSignatures && stateFileInfo.signature) emitSignatures.set(path, stateFileInfo.signature);
    });
    (_d = program.emitSignatures) == null ? void 0 : _d.forEach((value) => {
      if (isNumber(value)) emitSignatures.delete(toFilePath(value));
      else {
        const key = toFilePath(value[0]);
        emitSignatures.set(
          key,
          !isString(value[1]) && !value[1].length ? (
            // File signature is emit signature but differs in map
            [emitSignatures.get(key)]
          ) : value[1]
        );
      }
    });
    const changedFilesSet = new Set(map(program.changeFileSet, toFilePath));
    const fullEmitForOptions = program.affectedFilesPendingEmit ? getBuilderFileEmit(program.options || {}) : void 0;
    state = {
      fileInfos,
      compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
      referencedMap: toManyToManyPathMap(program.referencedMap, program.options ?? {}),
      semanticDiagnosticsPerFile: toPerFileSemanticDiagnostics(program.semanticDiagnosticsPerFile, fileInfos, changedFilesSet),
      emitDiagnosticsPerFile: toPerFileEmitDiagnostics(program.emitDiagnosticsPerFile),
      hasReusableDiagnostic: true,
      affectedFilesPendingEmit: program.affectedFilesPendingEmit && arrayToMap(program.affectedFilesPendingEmit, (value) => toFilePath(isNumber(value) ? value : value[0]), (value) => toBuilderFileEmit(value, fullEmitForOptions)),
      changedFilesSet,
      latestChangedDtsFile,
      emitSignatures: (emitSignatures == null ? void 0 : emitSignatures.size) ? emitSignatures : void 0
    };
  }
  return {
    getState: () => state,
    saveEmitState: noop,
    restoreEmitState: noop,
    getProgram: notImplemented,
    getProgramOrUndefined: returnUndefined,
    releaseProgram: noop,
    getCompilerOptions: () => state.compilerOptions,
    getSourceFile: notImplemented,
    getSourceFiles: notImplemented,
    getOptionsDiagnostics: notImplemented,
    getGlobalDiagnostics: notImplemented,
    getConfigFileParsingDiagnostics: notImplemented,
    getSyntacticDiagnostics: notImplemented,
    getDeclarationDiagnostics: notImplemented,
    getSemanticDiagnostics: notImplemented,
    emit: notImplemented,
    getAllDependencies: notImplemented,
    getCurrentDirectory: notImplemented,
    emitNextAffectedFile: notImplemented,
    getSemanticDiagnosticsOfNextAffectedFile: notImplemented,
    emitBuildInfo: notImplemented,
    close: noop,
    hasChangedEmitSignature: returnFalse
  };
  function toPathInBuildInfoDirectory(path) {
    return toPath(path, buildInfoDirectory, getCanonicalFileName);
  }
  function toAbsolutePath(path) {
    return getNormalizedAbsolutePath(path, buildInfoDirectory);
  }
  function toFilePath(fileId) {
    return filePaths[fileId - 1];
  }
  function toFilePathsSet(fileIdsListId) {
    return filePathsSetList[fileIdsListId - 1];
  }
  function toManyToManyPathMap(referenceMap, options) {
    const map2 = BuilderState.createReferencedMap(options);
    if (!map2 || !referenceMap) return map2;
    referenceMap.forEach(([fileId, fileIdListId]) => map2.set(toFilePath(fileId), toFilePathsSet(fileIdListId)));
    return map2;
  }
  function toPerFileSemanticDiagnostics(diagnostics, fileInfos, changedFilesSet) {
    const semanticDiagnostics = new Map(
      mapDefinedIterator(
        fileInfos.keys(),
        (key) => !changedFilesSet.has(key) ? [key, emptyArray] : void 0
      )
    );
    diagnostics == null ? void 0 : diagnostics.forEach((value) => {
      if (isNumber(value)) semanticDiagnostics.delete(toFilePath(value));
      else semanticDiagnostics.set(toFilePath(value[0]), value[1]);
    });
    return semanticDiagnostics.size ? semanticDiagnostics : void 0;
  }
  function toPerFileEmitDiagnostics(diagnostics) {
    return diagnostics && arrayToMap(diagnostics, (value) => toFilePath(value[0]), (value) => value[1]);
  }
}
function getBuildInfoFileVersionMap(program, buildInfoPath, host) {
  const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
  const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
  const fileInfos = /* @__PURE__ */ new Map();
  let rootIndex = 0;
  const roots = /* @__PURE__ */ new Map();
  const resolvedRoots = new Map(program.resolvedRoot);
  program.fileInfos.forEach((fileInfo, index) => {
    const path = toPath(program.fileNames[index], buildInfoDirectory, getCanonicalFileName);
    const version2 = isString(fileInfo) ? fileInfo : fileInfo.version;
    fileInfos.set(path, version2);
    if (rootIndex < program.root.length) {
      const current = program.root[rootIndex];
      const fileId = index + 1;
      if (isArray(current)) {
        if (current[0] <= fileId && fileId <= current[1]) {
          addRoot(fileId, path);
          if (current[1] === fileId) rootIndex++;
        }
      } else if (current === fileId) {
        addRoot(fileId, path);
        rootIndex++;
      }
    }
  });
  return { fileInfos, roots };
  function addRoot(fileId, path) {
    const root = resolvedRoots.get(fileId);
    if (root) {
      roots.set(toPath(program.fileNames[root - 1], buildInfoDirectory, getCanonicalFileName), path);
    } else {
      roots.set(path, void 0);
    }
  }
}
function createRedirectedBuilderProgram(getState, configFileParsingDiagnostics) {
  return {
    getState: notImplemented,
    saveEmitState: noop,
    restoreEmitState: noop,
    getProgram,
    getProgramOrUndefined: () => getState().program,
    releaseProgram: () => getState().program = void 0,
    getCompilerOptions: () => getState().compilerOptions,
    getSourceFile: (fileName) => getProgram().getSourceFile(fileName),
    getSourceFiles: () => getProgram().getSourceFiles(),
    getOptionsDiagnostics: (cancellationToken) => getProgram().getOptionsDiagnostics(cancellationToken),
    getGlobalDiagnostics: (cancellationToken) => getProgram().getGlobalDiagnostics(cancellationToken),
    getConfigFileParsingDiagnostics: () => configFileParsingDiagnostics,
    getSyntacticDiagnostics: (sourceFile, cancellationToken) => getProgram().getSyntacticDiagnostics(sourceFile, cancellationToken),
    getDeclarationDiagnostics: (sourceFile, cancellationToken) => getProgram().getDeclarationDiagnostics(sourceFile, cancellationToken),
    getSemanticDiagnostics: (sourceFile, cancellationToken) => getProgram().getSemanticDiagnostics(sourceFile, cancellationToken),
    emit: (sourceFile, writeFile2, cancellationToken, emitOnlyDts, customTransformers) => getProgram().emit(sourceFile, writeFile2, cancellationToken, emitOnlyDts, customTransformers),
    emitBuildInfo: (writeFile2, cancellationToken) => getProgram().emitBuildInfo(writeFile2, cancellationToken),
    getAllDependencies: notImplemented,
    getCurrentDirectory: () => getProgram().getCurrentDirectory(),
    close: noop
  };
  function getProgram() {
    return Debug.checkDefined(getState().program);
  }
}

// src/compiler/builderPublic.ts
function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
  return createBuilderProgram(1 /* EmitAndSemanticDiagnosticsBuilderProgram */, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
}

// src/compiler/resolutionCache.ts
function removeIgnoredPath(path) {
  if (endsWith(path, "/node_modules/.staging")) {
    return removeSuffix(path, "/.staging");
  }
  return some(ignoredPaths, (searchPath) => path.includes(searchPath)) ? void 0 : path;
}
function perceivedOsRootLengthForWatching(pathComponents2, length2) {
  if (length2 <= 1) return 1;
  let indexAfterOsRoot = 1;
  let isDosStyle = pathComponents2[0].search(/[a-zA-Z]:/) === 0;
  if (pathComponents2[0] !== directorySeparator && !isDosStyle && // Non dos style paths
  pathComponents2[1].search(/[a-zA-Z]\$$/) === 0) {
    if (length2 === 2) return 2;
    indexAfterOsRoot = 2;
    isDosStyle = true;
  }
  if (isDosStyle && !pathComponents2[indexAfterOsRoot].match(/^users$/i)) {
    return indexAfterOsRoot;
  }
  if (pathComponents2[indexAfterOsRoot].match(/^workspaces$/i)) {
    return indexAfterOsRoot + 1;
  }
  return indexAfterOsRoot + 2;
}
function canWatchDirectoryOrFile(pathComponents2, length2) {
  if (length2 === void 0) length2 = pathComponents2.length;
  if (length2 <= 2) return false;
  const perceivedOsRootLength = perceivedOsRootLengthForWatching(pathComponents2, length2);
  return length2 > perceivedOsRootLength + 1;
}
function canWatchAtTypes(atTypes) {
  return canWatchAffectedPackageJsonOrNodeModulesOfAtTypes(getDirectoryPath(atTypes));
}
function isInDirectoryPath(dirComponents, fileOrDirComponents) {
  if (fileOrDirComponents.length < fileOrDirComponents.length) return false;
  for (let i = 0; i < dirComponents.length; i++) {
    if (fileOrDirComponents[i] !== dirComponents[i]) return false;
  }
  return true;
}
function canWatchAffectedPackageJsonOrNodeModulesOfAtTypes(fileOrDirPath) {
  return canWatchDirectoryOrFile(getPathComponents(fileOrDirPath));
}
function canWatchAffectingLocation(filePath) {
  return canWatchAffectedPackageJsonOrNodeModulesOfAtTypes(filePath);
}
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath, rootDir, rootPath, rootPathComponents, getCurrentDirectory) {
  const failedLookupPathComponents = getPathComponents(failedLookupLocationPath);
  failedLookupLocation = isRootedDiskPath(failedLookupLocation) ? normalizePath(failedLookupLocation) : getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory());
  const failedLookupComponents = getPathComponents(failedLookupLocation);
  const perceivedOsRootLength = perceivedOsRootLengthForWatching(failedLookupPathComponents, failedLookupPathComponents.length);
  if (failedLookupPathComponents.length <= perceivedOsRootLength + 1) return void 0;
  const nodeModulesIndex = failedLookupPathComponents.indexOf("node_modules");
  if (nodeModulesIndex !== -1 && nodeModulesIndex + 1 <= perceivedOsRootLength + 1) return void 0;
  const lastNodeModulesIndex = failedLookupPathComponents.lastIndexOf("node_modules");
  if (isInDirectoryPath(rootPathComponents, failedLookupPathComponents)) {
    if (failedLookupPathComponents.length > rootPathComponents.length + 1) {
      return getDirectoryOfFailedLookupWatch(
        failedLookupComponents,
        failedLookupPathComponents,
        Math.max(rootPathComponents.length + 1, perceivedOsRootLength + 1),
        lastNodeModulesIndex
      );
    } else {
      return {
        dir: rootDir,
        dirPath: rootPath,
        nonRecursive: true
      };
    }
  }
  return getDirectoryToWatchFromFailedLookupLocationDirectory(
    failedLookupComponents,
    failedLookupPathComponents,
    failedLookupPathComponents.length - 1,
    perceivedOsRootLength,
    nodeModulesIndex,
    rootPathComponents,
    lastNodeModulesIndex
  );
}
function getDirectoryToWatchFromFailedLookupLocationDirectory(dirComponents, dirPathComponents, dirPathComponentsLength, perceivedOsRootLength, nodeModulesIndex, rootPathComponents, lastNodeModulesIndex) {
  if (nodeModulesIndex !== -1) {
    return getDirectoryOfFailedLookupWatch(
      dirComponents,
      dirPathComponents,
      nodeModulesIndex + 1,
      lastNodeModulesIndex
    );
  }
  let nonRecursive = true;
  let length2 = dirPathComponentsLength;
  for (let i = 0; i < dirPathComponentsLength; i++) {
    if (dirPathComponents[i] !== rootPathComponents[i]) {
      nonRecursive = false;
      length2 = Math.max(i + 1, perceivedOsRootLength + 1);
      break;
    }
  }
  return getDirectoryOfFailedLookupWatch(
    dirComponents,
    dirPathComponents,
    length2,
    lastNodeModulesIndex,
    nonRecursive
  );
}
function getDirectoryOfFailedLookupWatch(dirComponents, dirPathComponents, length2, lastNodeModulesIndex, nonRecursive) {
  let packageDirLength;
  if (lastNodeModulesIndex !== -1 && lastNodeModulesIndex + 1 >= length2 && lastNodeModulesIndex + 2 < dirPathComponents.length) {
    if (!startsWith(dirPathComponents[lastNodeModulesIndex + 1], "@")) {
      packageDirLength = lastNodeModulesIndex + 2;
    } else if (lastNodeModulesIndex + 3 < dirPathComponents.length) {
      packageDirLength = lastNodeModulesIndex + 3;
    }
  }
  return {
    dir: getPathFromPathComponents(dirComponents, length2),
    dirPath: getPathFromPathComponents(dirPathComponents, length2),
    nonRecursive,
    packageDir: packageDirLength !== void 0 ? getPathFromPathComponents(dirComponents, packageDirLength) : void 0,
    packageDirPath: packageDirLength !== void 0 ? getPathFromPathComponents(dirPathComponents, packageDirLength) : void 0
  };
}
function getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot, typeRootPath, rootPath, rootPathComponents, getCurrentDirectory, filterCustomPath) {
  const typeRootPathComponents = getPathComponents(typeRootPath);
  if (isInDirectoryPath(rootPathComponents, typeRootPathComponents)) {
    return rootPath;
  }
  typeRoot = isRootedDiskPath(typeRoot) ? normalizePath(typeRoot) : getNormalizedAbsolutePath(typeRoot, getCurrentDirectory());
  const toWatch = getDirectoryToWatchFromFailedLookupLocationDirectory(
    getPathComponents(typeRoot),
    typeRootPathComponents,
    typeRootPathComponents.length,
    perceivedOsRootLengthForWatching(typeRootPathComponents, typeRootPathComponents.length),
    typeRootPathComponents.indexOf("node_modules"),
    rootPathComponents,
    typeRootPathComponents.lastIndexOf("node_modules")
  );
  return toWatch && filterCustomPath(toWatch.dirPath) ? toWatch.dirPath : void 0;
}
function getRootDirectoryOfResolutionCache(rootDirForResolution, getCurrentDirectory) {
  const normalized = getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory());
  return !isDiskPathRoot(normalized) ? removeTrailingDirectorySeparator(normalized) : normalized;
}
function getModuleResolutionHost(resolutionHost) {
  var _a;
  return ((_a = resolutionHost.getCompilerHost) == null ? void 0 : _a.call(resolutionHost)) || resolutionHost;
}
function createModuleResolutionLoaderUsingGlobalCache(containingFile, redirectedReference, options, resolutionHost, moduleResolutionCache) {
  return {
    nameAndMode: moduleResolutionNameAndModeGetter,
    resolve: (moduleName, resoluionMode) => resolveModuleNameUsingGlobalCache(
      resolutionHost,
      moduleResolutionCache,
      moduleName,
      containingFile,
      options,
      redirectedReference,
      resoluionMode
    )
  };
}
function resolveModuleNameUsingGlobalCache(resolutionHost, moduleResolutionCache, moduleName, containingFile, compilerOptions, redirectedReference, mode) {
  const host = getModuleResolutionHost(resolutionHost);
  const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference, mode);
  if (!resolutionHost.getGlobalCache) {
    return primaryResult;
  }
  const globalCache = resolutionHost.getGlobalCache();
  if (globalCache !== void 0 && !isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && extensionIsTS(primaryResult.resolvedModule.extension))) {
    const { resolvedModule, failedLookupLocations, affectingLocations, resolutionDiagnostics } = loadModuleFromGlobalCache(
      Debug.checkDefined(resolutionHost.globalCacheResolutionModuleName)(moduleName),
      resolutionHost.projectName,
      compilerOptions,
      host,
      globalCache,
      moduleResolutionCache
    );
    if (resolvedModule) {
      primaryResult.resolvedModule = resolvedModule;
      primaryResult.failedLookupLocations = updateResolutionField(primaryResult.failedLookupLocations, failedLookupLocations);
      primaryResult.affectingLocations = updateResolutionField(primaryResult.affectingLocations, affectingLocations);
      primaryResult.resolutionDiagnostics = updateResolutionField(primaryResult.resolutionDiagnostics, resolutionDiagnostics);
      return primaryResult;
    }
  }
  return primaryResult;
}
function createResolutionCache(resolutionHost, rootDirForResolution, logChangesWhenResolvingModule) {
  let filesWithChangedSetOfUnresolvedImports;
  let filesWithInvalidatedResolutions;
  let filesWithInvalidatedNonRelativeUnresolvedImports;
  const nonRelativeExternalModuleResolutions = createMultiMap();
  const resolutionsWithFailedLookups = /* @__PURE__ */ new Set();
  const resolutionsWithOnlyAffectingLocations = /* @__PURE__ */ new Set();
  const resolvedFileToResolution = /* @__PURE__ */ new Map();
  const impliedFormatPackageJsons = /* @__PURE__ */ new Map();
  let hasChangedAutomaticTypeDirectiveNames = false;
  let affectingPathChecksForFile;
  let affectingPathChecks;
  let failedLookupChecks;
  let startsWithPathChecks;
  let isInDirectoryChecks;
  let allModuleAndTypeResolutionsAreInvalidated = false;
  const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory());
  const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
  const resolvedModuleNames = /* @__PURE__ */ new Map();
  const moduleResolutionCache = createModuleResolutionCache(
    getCurrentDirectory(),
    resolutionHost.getCanonicalFileName,
    resolutionHost.getCompilationSettings()
  );
  const resolvedTypeReferenceDirectives = /* @__PURE__ */ new Map();
  const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
    getCurrentDirectory(),
    resolutionHost.getCanonicalFileName,
    resolutionHost.getCompilationSettings(),
    moduleResolutionCache.getPackageJsonInfoCache(),
    moduleResolutionCache.optionsToRedirectsKey
  );
  const resolvedLibraries = /* @__PURE__ */ new Map();
  const libraryResolutionCache = createModuleResolutionCache(
    getCurrentDirectory(),
    resolutionHost.getCanonicalFileName,
    getOptionsForLibraryResolution(resolutionHost.getCompilationSettings()),
    moduleResolutionCache.getPackageJsonInfoCache()
  );
  const directoryWatchesOfFailedLookups = /* @__PURE__ */ new Map();
  const fileWatchesOfAffectingLocations = /* @__PURE__ */ new Map();
  const rootDir = getRootDirectoryOfResolutionCache(rootDirForResolution, getCurrentDirectory);
  const rootPath = resolutionHost.toPath(rootDir);
  const rootPathComponents = getPathComponents(rootPath);
  const isSymlinkCache = /* @__PURE__ */ new Map();
  const packageDirWatchers = /* @__PURE__ */ new Map();
  const dirPathToSymlinkPackageRefCount = /* @__PURE__ */ new Map();
  const typeRootsWatches = /* @__PURE__ */ new Map();
  return {
    rootDirForResolution,
    resolvedModuleNames,
    resolvedTypeReferenceDirectives,
    resolvedLibraries,
    resolvedFileToResolution,
    resolutionsWithFailedLookups,
    resolutionsWithOnlyAffectingLocations,
    directoryWatchesOfFailedLookups,
    fileWatchesOfAffectingLocations,
    packageDirWatchers,
    dirPathToSymlinkPackageRefCount,
    watchFailedLookupLocationsOfExternalModuleResolutions,
    getModuleResolutionCache: () => moduleResolutionCache,
    startRecordingFilesWithChangedResolutions,
    finishRecordingFilesWithChangedResolutions,
    // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
    // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
    startCachingPerDirectoryResolution,
    finishCachingPerDirectoryResolution,
    resolveModuleNameLiterals,
    resolveTypeReferenceDirectiveReferences,
    resolveLibrary: resolveLibrary2,
    resolveSingleModuleNameWithoutWatching,
    removeResolutionsFromProjectReferenceRedirects,
    removeResolutionsOfFile,
    hasChangedAutomaticTypeDirectiveNames: () => hasChangedAutomaticTypeDirectiveNames,
    invalidateResolutionOfFile,
    invalidateResolutionsOfFailedLookupLocations,
    setFilesWithInvalidatedNonRelativeUnresolvedImports,
    createHasInvalidatedResolutions,
    isFileWithInvalidatedNonRelativeUnresolvedImports,
    updateTypeRootsWatch,
    closeTypeRootsWatch,
    clear: clear2,
    onChangesAffectModuleResolution
  };
  function getResolvedModule(resolution) {
    return resolution.resolvedModule;
  }
  function getResolvedTypeReferenceDirective(resolution) {
    return resolution.resolvedTypeReferenceDirective;
  }
  function clear2() {
    clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
    clearMap(fileWatchesOfAffectingLocations, closeFileWatcherOf);
    isSymlinkCache.clear();
    packageDirWatchers.clear();
    dirPathToSymlinkPackageRefCount.clear();
    nonRelativeExternalModuleResolutions.clear();
    closeTypeRootsWatch();
    resolvedModuleNames.clear();
    resolvedTypeReferenceDirectives.clear();
    resolvedFileToResolution.clear();
    resolutionsWithFailedLookups.clear();
    resolutionsWithOnlyAffectingLocations.clear();
    failedLookupChecks = void 0;
    startsWithPathChecks = void 0;
    isInDirectoryChecks = void 0;
    affectingPathChecks = void 0;
    affectingPathChecksForFile = void 0;
    allModuleAndTypeResolutionsAreInvalidated = false;
    moduleResolutionCache.clear();
    typeReferenceDirectiveResolutionCache.clear();
    moduleResolutionCache.update(resolutionHost.getCompilationSettings());
    typeReferenceDirectiveResolutionCache.update(resolutionHost.getCompilationSettings());
    libraryResolutionCache.clear();
    impliedFormatPackageJsons.clear();
    resolvedLibraries.clear();
    hasChangedAutomaticTypeDirectiveNames = false;
  }
  function onChangesAffectModuleResolution() {
    allModuleAndTypeResolutionsAreInvalidated = true;
    moduleResolutionCache.clearAllExceptPackageJsonInfoCache();
    typeReferenceDirectiveResolutionCache.clearAllExceptPackageJsonInfoCache();
    moduleResolutionCache.update(resolutionHost.getCompilationSettings());
    typeReferenceDirectiveResolutionCache.update(resolutionHost.getCompilationSettings());
  }
  function startRecordingFilesWithChangedResolutions() {
    filesWithChangedSetOfUnresolvedImports = [];
  }
  function finishRecordingFilesWithChangedResolutions() {
    const collected = filesWithChangedSetOfUnresolvedImports;
    filesWithChangedSetOfUnresolvedImports = void 0;
    return collected;
  }
  function isFileWithInvalidatedNonRelativeUnresolvedImports(path) {
    if (!filesWithInvalidatedNonRelativeUnresolvedImports) {
      return false;
    }
    const value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path);
    return !!value && !!value.length;
  }
  function createHasInvalidatedResolutions(customHasInvalidatedResolutions, customHasInvalidatedLibResolutions) {
    invalidateResolutionsOfFailedLookupLocations();
    const collected = filesWithInvalidatedResolutions;
    filesWithInvalidatedResolutions = void 0;
    return {
      hasInvalidatedResolutions: (path) => customHasInvalidatedResolutions(path) || allModuleAndTypeResolutionsAreInvalidated || !!(collected == null ? void 0 : collected.has(path)) || isFileWithInvalidatedNonRelativeUnresolvedImports(path),
      hasInvalidatedLibResolutions: (libFileName) => {
        var _a;
        return customHasInvalidatedLibResolutions(libFileName) || !!((_a = resolvedLibraries == null ? void 0 : resolvedLibraries.get(libFileName)) == null ? void 0 : _a.isInvalidated);
      }
    };
  }
  function startCachingPerDirectoryResolution() {
    moduleResolutionCache.isReadonly = void 0;
    typeReferenceDirectiveResolutionCache.isReadonly = void 0;
    libraryResolutionCache.isReadonly = void 0;
    moduleResolutionCache.getPackageJsonInfoCache().isReadonly = void 0;
    moduleResolutionCache.clearAllExceptPackageJsonInfoCache();
    typeReferenceDirectiveResolutionCache.clearAllExceptPackageJsonInfoCache();
    libraryResolutionCache.clearAllExceptPackageJsonInfoCache();
    nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
    nonRelativeExternalModuleResolutions.clear();
    isSymlinkCache.clear();
  }
  function cleanupLibResolutionWatching(newProgram) {
    resolvedLibraries.forEach((resolution, libFileName) => {
      var _a;
      if (!((_a = newProgram == null ? void 0 : newProgram.resolvedLibReferences) == null ? void 0 : _a.has(libFileName))) {
        stopWatchFailedLookupLocationOfResolution(
          resolution,
          resolutionHost.toPath(getInferredLibraryNameResolveFrom(resolutionHost.getCompilationSettings(), getCurrentDirectory(), libFileName)),
          getResolvedModule
        );
        resolvedLibraries.delete(libFileName);
      }
    });
  }
  function finishCachingPerDirectoryResolution(newProgram, oldProgram) {
    filesWithInvalidatedNonRelativeUnresolvedImports = void 0;
    allModuleAndTypeResolutionsAreInvalidated = false;
    nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
    nonRelativeExternalModuleResolutions.clear();
    if (newProgram !== oldProgram) {
      cleanupLibResolutionWatching(newProgram);
      newProgram == null ? void 0 : newProgram.getSourceFiles().forEach((newFile) => {
        var _a;
        const expected = isExternalOrCommonJsModule(newFile) ? ((_a = newFile.packageJsonLocations) == null ? void 0 : _a.length) ?? 0 : 0;
        const existing = impliedFormatPackageJsons.get(newFile.resolvedPath) ?? emptyArray;
        for (let i = existing.length; i < expected; i++) {
          createFileWatcherOfAffectingLocation(
            newFile.packageJsonLocations[i],
            /*forResolution*/
            false
          );
        }
        if (existing.length > expected) {
          for (let i = expected; i < existing.length; i++) {
            fileWatchesOfAffectingLocations.get(existing[i]).files--;
          }
        }
        if (expected) impliedFormatPackageJsons.set(newFile.resolvedPath, newFile.packageJsonLocations);
        else impliedFormatPackageJsons.delete(newFile.resolvedPath);
      });
      impliedFormatPackageJsons.forEach((existing, path) => {
        const newFile = newProgram == null ? void 0 : newProgram.getSourceFileByPath(path);
        if (!newFile || newFile.resolvedPath !== path) {
          existing.forEach((location) => fileWatchesOfAffectingLocations.get(location).files--);
          impliedFormatPackageJsons.delete(path);
        }
      });
    }
    directoryWatchesOfFailedLookups.forEach(closeDirectoryWatchesOfFailedLookup);
    fileWatchesOfAffectingLocations.forEach(closeFileWatcherOfAffectingLocation);
    packageDirWatchers.forEach(closePackageDirWatcher);
    hasChangedAutomaticTypeDirectiveNames = false;
    moduleResolutionCache.isReadonly = true;
    typeReferenceDirectiveResolutionCache.isReadonly = true;
    libraryResolutionCache.isReadonly = true;
    moduleResolutionCache.getPackageJsonInfoCache().isReadonly = true;
    isSymlinkCache.clear();
  }
  function closePackageDirWatcher(watcher, packageDirPath) {
    if (watcher.dirPathToWatcher.size === 0) {
      packageDirWatchers.delete(packageDirPath);
    }
  }
  function closeDirectoryWatchesOfFailedLookup(watcher, path) {
    if (watcher.refCount === 0) {
      directoryWatchesOfFailedLookups.delete(path);
      watcher.watcher.close();
    }
  }
  function closeFileWatcherOfAffectingLocation(watcher, path) {
    var _a;
    if (watcher.files === 0 && watcher.resolutions === 0 && !((_a = watcher.symlinks) == null ? void 0 : _a.size)) {
      fileWatchesOfAffectingLocations.delete(path);
      watcher.watcher.close();
    }
  }
  function resolveNamesWithLocalCache({
    entries,
    containingFile,
    containingSourceFile,
    redirectedReference,
    options,
    perFileCache,
    reusedNames,
    loader,
    getResolutionWithResolvedFileName,
    deferWatchingNonRelativeResolution,
    shouldRetryResolution,
    logChanges
  }) {
    const path = resolutionHost.toPath(containingFile);
    const resolutionsInFile = perFileCache.get(path) || perFileCache.set(path, createModeAwareCache()).get(path);
    const resolvedModules = [];
    const hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
    const program = resolutionHost.getCurrentProgram();
    const oldRedirect = program && program.getResolvedProjectReferenceToRedirect(containingFile);
    const unmatchedRedirects = oldRedirect ? !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path : !!redirectedReference;
    const seenNamesInFile = createModeAwareCache();
    for (const entry of entries) {
      const name = loader.nameAndMode.getName(entry);
      const mode = loader.nameAndMode.getMode(entry, containingSourceFile, (redirectedReference == null ? void 0 : redirectedReference.commandLine.options) || options);
      let resolution = resolutionsInFile.get(name, mode);
      if (!seenNamesInFile.has(name, mode) && (allModuleAndTypeResolutionsAreInvalidated || unmatchedRedirects || !resolution || resolution.isInvalidated || // If the name is unresolved import that was invalidated, recalculate
      hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) {
        const existingResolution = resolution;
        resolution = loader.resolve(name, mode);
        if (resolutionHost.onDiscoveredSymlink && resolutionIsSymlink(resolution)) {
          resolutionHost.onDiscoveredSymlink();
        }
        resolutionsInFile.set(name, mode, resolution);
        if (resolution !== existingResolution) {
          watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName, deferWatchingNonRelativeResolution);
          if (existingResolution) {
            stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName);
          }
        }
        if (logChanges && filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) {
          filesWithChangedSetOfUnresolvedImports.push(path);
          logChanges = false;
        }
      } else {
        const host = getModuleResolutionHost(resolutionHost);
        if (isTraceEnabled(options, host) && !seenNamesInFile.has(name, mode)) {
          const resolved = getResolutionWithResolvedFileName(resolution);
          trace(
            host,
            perFileCache === resolvedModuleNames ? (resolved == null ? void 0 : resolved.resolvedFileName) ? resolved.packageId ? Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_not_resolved : (resolved == null ? void 0 : resolved.resolvedFileName) ? resolved.packageId ? Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_not_resolved,
            name,
            containingFile,
            resolved == null ? void 0 : resolved.resolvedFileName,
            (resolved == null ? void 0 : resolved.packageId) && packageIdToString(resolved.packageId)
          );
        }
      }
      Debug.assert(resolution !== void 0 && !resolution.isInvalidated);
      seenNamesInFile.set(name, mode, true);
      resolvedModules.push(resolution);
    }
    reusedNames == null ? void 0 : reusedNames.forEach(
      (entry) => seenNamesInFile.set(
        loader.nameAndMode.getName(entry),
        loader.nameAndMode.getMode(entry, containingSourceFile, (redirectedReference == null ? void 0 : redirectedReference.commandLine.options) || options),
        true
      )
    );
    if (resolutionsInFile.size() !== seenNamesInFile.size()) {
      resolutionsInFile.forEach((resolution, name, mode) => {
        if (!seenNamesInFile.has(name, mode)) {
          stopWatchFailedLookupLocationOfResolution(resolution, path, getResolutionWithResolvedFileName);
          resolutionsInFile.delete(name, mode);
        }
      });
    }
    return resolvedModules;
    function resolutionIsEqualTo(oldResolution, newResolution) {
      if (oldResolution === newResolution) {
        return true;
      }
      if (!oldResolution || !newResolution) {
        return false;
      }
      const oldResult = getResolutionWithResolvedFileName(oldResolution);
      const newResult = getResolutionWithResolvedFileName(newResolution);
      if (oldResult === newResult) {
        return true;
      }
      if (!oldResult || !newResult) {
        return false;
      }
      return oldResult.resolvedFileName === newResult.resolvedFileName;
    }
  }
  function resolveTypeReferenceDirectiveReferences(typeDirectiveReferences, containingFile, redirectedReference, options, containingSourceFile, reusedNames) {
    return resolveNamesWithLocalCache({
      entries: typeDirectiveReferences,
      containingFile,
      containingSourceFile,
      redirectedReference,
      options,
      reusedNames,
      perFileCache: resolvedTypeReferenceDirectives,
      loader: createTypeReferenceResolutionLoader(
        containingFile,
        redirectedReference,
        options,
        getModuleResolutionHost(resolutionHost),
        typeReferenceDirectiveResolutionCache
      ),
      getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective,
      shouldRetryResolution: (resolution) => resolution.resolvedTypeReferenceDirective === void 0,
      deferWatchingNonRelativeResolution: false
    });
  }
  function resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) {
    return resolveNamesWithLocalCache({
      entries: moduleLiterals,
      containingFile,
      containingSourceFile,
      redirectedReference,
      options,
      reusedNames,
      perFileCache: resolvedModuleNames,
      loader: createModuleResolutionLoaderUsingGlobalCache(
        containingFile,
        redirectedReference,
        options,
        resolutionHost,
        moduleResolutionCache
      ),
      getResolutionWithResolvedFileName: getResolvedModule,
      shouldRetryResolution: (resolution) => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension),
      logChanges: logChangesWhenResolvingModule,
      deferWatchingNonRelativeResolution: true
      // Defer non relative resolution watch because we could be using ambient modules
    });
  }
  function resolveLibrary2(libraryName, resolveFrom, options, libFileName) {
    const host = getModuleResolutionHost(resolutionHost);
    let resolution = resolvedLibraries == null ? void 0 : resolvedLibraries.get(libFileName);
    if (!resolution || resolution.isInvalidated) {
      const existingResolution = resolution;
      resolution = resolveLibrary(libraryName, resolveFrom, options, host, libraryResolutionCache);
      const path = resolutionHost.toPath(resolveFrom);
      watchFailedLookupLocationsOfExternalModuleResolutions(
        libraryName,
        resolution,
        path,
        getResolvedModule,
        /*deferWatchingNonRelativeResolution*/
        false
      );
      resolvedLibraries.set(libFileName, resolution);
      if (existingResolution) {
        stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolvedModule);
      }
    } else {
      if (isTraceEnabled(options, host)) {
        const resolved = getResolvedModule(resolution);
        trace(
          host,
          (resolved == null ? void 0 : resolved.resolvedFileName) ? resolved.packageId ? Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_not_resolved,
          libraryName,
          resolveFrom,
          resolved == null ? void 0 : resolved.resolvedFileName,
          (resolved == null ? void 0 : resolved.packageId) && packageIdToString(resolved.packageId)
        );
      }
    }
    return resolution;
  }
  function resolveSingleModuleNameWithoutWatching(moduleName, containingFile) {
    var _a, _b;
    const path = resolutionHost.toPath(containingFile);
    const resolutionsInFile = resolvedModuleNames.get(path);
    const resolution = resolutionsInFile == null ? void 0 : resolutionsInFile.get(
      moduleName,
      /*mode*/
      void 0
    );
    if (resolution && !resolution.isInvalidated) return resolution;
    const data = (_a = resolutionHost.beforeResolveSingleModuleNameWithoutWatching) == null ? void 0 : _a.call(resolutionHost, moduleResolutionCache);
    const host = getModuleResolutionHost(resolutionHost);
    const result = resolveModuleName(
      moduleName,
      containingFile,
      resolutionHost.getCompilationSettings(),
      host,
      moduleResolutionCache
    );
    (_b = resolutionHost.afterResolveSingleModuleNameWithoutWatching) == null ? void 0 : _b.call(resolutionHost, moduleResolutionCache, moduleName, containingFile, result, data);
    return result;
  }
  function isNodeModulesAtTypesDirectory(dirPath) {
    return endsWith(dirPath, "/node_modules/@types");
  }
  function watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, filePath, getResolutionWithResolvedFileName, deferWatchingNonRelativeResolution) {
    var _a;
    if (resolution.refCount) {
      resolution.refCount++;
      Debug.assertIsDefined(resolution.files);
    } else {
      resolution.refCount = 1;
      Debug.assert(!((_a = resolution.files) == null ? void 0 : _a.size));
      if (!deferWatchingNonRelativeResolution || isExternalModuleNameRelative(name)) {
        watchFailedLookupLocationOfResolution(resolution);
      } else {
        nonRelativeExternalModuleResolutions.add(name, resolution);
      }
      const resolved = getResolutionWithResolvedFileName(resolution);
      if (resolved && resolved.resolvedFileName) {
        const key = resolutionHost.toPath(resolved.resolvedFileName);
        let resolutions = resolvedFileToResolution.get(key);
        if (!resolutions) resolvedFileToResolution.set(key, resolutions = /* @__PURE__ */ new Set());
        resolutions.add(resolution);
      }
    }
    (resolution.files ?? (resolution.files = /* @__PURE__ */ new Set())).add(filePath);
  }
  function watchFailedLookupLocation(failedLookupLocation, setAtRoot) {
    const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
    const toWatch = getDirectoryToWatchFailedLookupLocation(
      failedLookupLocation,
      failedLookupLocationPath,
      rootDir,
      rootPath,
      rootPathComponents,
      getCurrentDirectory
    );
    if (toWatch) {
      const { dir, dirPath, nonRecursive, packageDir, packageDirPath } = toWatch;
      if (dirPath === rootPath) {
        Debug.assert(nonRecursive);
        Debug.assert(!packageDir);
        setAtRoot = true;
      } else {
        setDirectoryWatcher(dir, dirPath, packageDir, packageDirPath, nonRecursive);
      }
    }
    return setAtRoot;
  }
  function watchFailedLookupLocationOfResolution(resolution) {
    Debug.assert(!!resolution.refCount);
    const { failedLookupLocations, affectingLocations, alternateResult } = resolution;
    if (!(failedLookupLocations == null ? void 0 : failedLookupLocations.length) && !(affectingLocations == null ? void 0 : affectingLocations.length) && !alternateResult) return;
    if ((failedLookupLocations == null ? void 0 : failedLookupLocations.length) || alternateResult) resolutionsWithFailedLookups.add(resolution);
    let setAtRoot = false;
    if (failedLookupLocations) {
      for (const failedLookupLocation of failedLookupLocations) {
        setAtRoot = watchFailedLookupLocation(failedLookupLocation, setAtRoot);
      }
    }
    if (alternateResult) setAtRoot = watchFailedLookupLocation(alternateResult, setAtRoot);
    if (setAtRoot) {
      setDirectoryWatcher(
        rootDir,
        rootPath,
        /*packageDir*/
        void 0,
        /*packageDirPath*/
        void 0,
        /*nonRecursive*/
        true
      );
    }
    watchAffectingLocationsOfResolution(resolution, !(failedLookupLocations == null ? void 0 : failedLookupLocations.length) && !alternateResult);
  }
  function watchAffectingLocationsOfResolution(resolution, addToResolutionsWithOnlyAffectingLocations) {
    Debug.assert(!!resolution.refCount);
    const { affectingLocations } = resolution;
    if (!(affectingLocations == null ? void 0 : affectingLocations.length)) return;
    if (addToResolutionsWithOnlyAffectingLocations) resolutionsWithOnlyAffectingLocations.add(resolution);
    for (const affectingLocation of affectingLocations) {
      createFileWatcherOfAffectingLocation(
        affectingLocation,
        /*forResolution*/
        true
      );
    }
  }
  function createFileWatcherOfAffectingLocation(affectingLocation, forResolution) {
    const fileWatcher = fileWatchesOfAffectingLocations.get(affectingLocation);
    if (fileWatcher) {
      if (forResolution) fileWatcher.resolutions++;
      else fileWatcher.files++;
      return;
    }
    let locationToWatch = affectingLocation;
    let isSymlink = false;
    let symlinkWatcher;
    if (resolutionHost.realpath) {
      locationToWatch = resolutionHost.realpath(affectingLocation);
      if (affectingLocation !== locationToWatch) {
        isSymlink = true;
        symlinkWatcher = fileWatchesOfAffectingLocations.get(locationToWatch);
      }
    }
    const resolutions = forResolution ? 1 : 0;
    const files = forResolution ? 0 : 1;
    if (!isSymlink || !symlinkWatcher) {
      const watcher = {
        watcher: canWatchAffectingLocation(resolutionHost.toPath(locationToWatch)) ? resolutionHost.watchAffectingFileLocation(locationToWatch, (fileName, eventKind) => {
          cachedDirectoryStructureHost == null ? void 0 : cachedDirectoryStructureHost.addOrDeleteFile(fileName, resolutionHost.toPath(locationToWatch), eventKind);
          invalidateAffectingFileWatcher(locationToWatch, moduleResolutionCache.getPackageJsonInfoCache().getInternalMap());
          resolutionHost.scheduleInvalidateResolutionsOfFailedLookupLocations();
        }) : noopFileWatcher,
        resolutions: isSymlink ? 0 : resolutions,
        files: isSymlink ? 0 : files,
        symlinks: void 0
      };
      fileWatchesOfAffectingLocations.set(locationToWatch, watcher);
      if (isSymlink) symlinkWatcher = watcher;
    }
    if (isSymlink) {
      Debug.assert(!!symlinkWatcher);
      const watcher = {
        watcher: {
          close: () => {
            var _a;
            const symlinkWatcher2 = fileWatchesOfAffectingLocations.get(locationToWatch);
            if (((_a = symlinkWatcher2 == null ? void 0 : symlinkWatcher2.symlinks) == null ? void 0 : _a.delete(affectingLocation)) && !symlinkWatcher2.symlinks.size && !symlinkWatcher2.resolutions && !symlinkWatcher2.files) {
              fileWatchesOfAffectingLocations.delete(locationToWatch);
              symlinkWatcher2.watcher.close();
            }
          }
        },
        resolutions,
        files,
        symlinks: void 0
      };
      fileWatchesOfAffectingLocations.set(affectingLocation, watcher);
      (symlinkWatcher.symlinks ?? (symlinkWatcher.symlinks = /* @__PURE__ */ new Set())).add(affectingLocation);
    }
  }
  function invalidateAffectingFileWatcher(path, packageJsonMap) {
    var _a;
    const watcher = fileWatchesOfAffectingLocations.get(path);
    if (watcher == null ? void 0 : watcher.resolutions) (affectingPathChecks ?? (affectingPathChecks = /* @__PURE__ */ new Set())).add(path);
    if (watcher == null ? void 0 : watcher.files) (affectingPathChecksForFile ?? (affectingPathChecksForFile = /* @__PURE__ */ new Set())).add(path);
    (_a = watcher == null ? void 0 : watcher.symlinks) == null ? void 0 : _a.forEach((path2) => invalidateAffectingFileWatcher(path2, packageJsonMap));
    packageJsonMap == null ? void 0 : packageJsonMap.delete(resolutionHost.toPath(path));
  }
  function watchFailedLookupLocationOfNonRelativeModuleResolutions(resolutions, name) {
    const program = resolutionHost.getCurrentProgram();
    if (!program || !program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(name)) {
      resolutions.forEach(watchFailedLookupLocationOfResolution);
    } else {
      resolutions.forEach((resolution) => watchAffectingLocationsOfResolution(
        resolution,
        /*addToResolutionsWithOnlyAffectingLocations*/
        true
      ));
    }
  }
  function createDirectoryWatcherForPackageDir(dir, dirPath, packageDir, packageDirPath, nonRecursive) {
    Debug.assert(!nonRecursive);
    let isSymlink = isSymlinkCache.get(packageDirPath);
    let packageDirWatcher = packageDirWatchers.get(packageDirPath);
    if (isSymlink === void 0) {
      const realPath2 = resolutionHost.realpath(packageDir);
      isSymlink = realPath2 !== packageDir && resolutionHost.toPath(realPath2) !== packageDirPath;
      isSymlinkCache.set(packageDirPath, isSymlink);
      if (!packageDirWatcher) {
        packageDirWatchers.set(
          packageDirPath,
          packageDirWatcher = {
            dirPathToWatcher: /* @__PURE__ */ new Map(),
            isSymlink
          }
        );
      } else if (packageDirWatcher.isSymlink !== isSymlink) {
        packageDirWatcher.dirPathToWatcher.forEach((watcher) => {
          removeDirectoryWatcher(
            packageDirWatcher.isSymlink ? packageDirPath : dirPath,
            /*syncDirWatcherRemove*/
            false
          );
          watcher.watcher = createDirPathToWatcher();
        });
        packageDirWatcher.isSymlink = isSymlink;
      }
    } else {
      Debug.assertIsDefined(packageDirWatcher);
      Debug.assert(isSymlink === packageDirWatcher.isSymlink);
    }
    const forDirPath = packageDirWatcher.dirPathToWatcher.get(dirPath);
    if (forDirPath) {
      forDirPath.refCount++;
    } else {
      packageDirWatcher.dirPathToWatcher.set(dirPath, {
        watcher: createDirPathToWatcher(),
        refCount: 1
      });
      if (isSymlink) dirPathToSymlinkPackageRefCount.set(dirPath, (dirPathToSymlinkPackageRefCount.get(dirPath) ?? 0) + 1);
    }
    function createDirPathToWatcher() {
      return isSymlink ? createOrAddRefToDirectoryWatchOfFailedLookups(packageDir, packageDirPath, nonRecursive) : createOrAddRefToDirectoryWatchOfFailedLookups(dir, dirPath, nonRecursive);
    }
  }
  function setDirectoryWatcher(dir, dirPath, packageDir, packageDirPath, nonRecursive) {
    if (!packageDirPath || !resolutionHost.realpath) {
      createOrAddRefToDirectoryWatchOfFailedLookups(dir, dirPath, nonRecursive);
    } else {
      createDirectoryWatcherForPackageDir(dir, dirPath, packageDir, packageDirPath, nonRecursive);
    }
  }
  function createOrAddRefToDirectoryWatchOfFailedLookups(dir, dirPath, nonRecursive) {
    let dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
    if (dirWatcher) {
      Debug.assert(!!nonRecursive === !!dirWatcher.nonRecursive);
      dirWatcher.refCount++;
    } else {
      directoryWatchesOfFailedLookups.set(dirPath, dirWatcher = { watcher: createDirectoryWatcher(dir, dirPath, nonRecursive), refCount: 1, nonRecursive });
    }
    return dirWatcher;
  }
  function stopWatchFailedLookupLocation(failedLookupLocation, removeAtRoot, syncDirWatcherRemove) {
    const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
    const toWatch = getDirectoryToWatchFailedLookupLocation(
      failedLookupLocation,
      failedLookupLocationPath,
      rootDir,
      rootPath,
      rootPathComponents,
      getCurrentDirectory
    );
    if (toWatch) {
      const { dirPath, packageDirPath } = toWatch;
      if (dirPath === rootPath) {
        removeAtRoot = true;
      } else if (packageDirPath && resolutionHost.realpath) {
        const packageDirWatcher = packageDirWatchers.get(packageDirPath);
        const forDirPath = packageDirWatcher.dirPathToWatcher.get(dirPath);
        forDirPath.refCount--;
        if (forDirPath.refCount === 0) {
          removeDirectoryWatcher(packageDirWatcher.isSymlink ? packageDirPath : dirPath, syncDirWatcherRemove);
          packageDirWatcher.dirPathToWatcher.delete(dirPath);
          if (packageDirWatcher.isSymlink) {
            const refCount = dirPathToSymlinkPackageRefCount.get(dirPath) - 1;
            if (refCount === 0) {
              dirPathToSymlinkPackageRefCount.delete(dirPath);
            } else {
              dirPathToSymlinkPackageRefCount.set(dirPath, refCount);
            }
          }
          if (syncDirWatcherRemove) closePackageDirWatcher(packageDirWatcher, packageDirPath);
        }
      } else {
        removeDirectoryWatcher(dirPath, syncDirWatcherRemove);
      }
    }
    return removeAtRoot;
  }
  function stopWatchFailedLookupLocationOfResolution(resolution, filePath, getResolutionWithResolvedFileName, syncDirWatcherRemove) {
    Debug.checkDefined(resolution.files).delete(filePath);
    resolution.refCount--;
    if (resolution.refCount) {
      return;
    }
    const resolved = getResolutionWithResolvedFileName(resolution);
    if (resolved && resolved.resolvedFileName) {
      const key = resolutionHost.toPath(resolved.resolvedFileName);
      const resolutions = resolvedFileToResolution.get(key);
      if ((resolutions == null ? void 0 : resolutions.delete(resolution)) && !resolutions.size) resolvedFileToResolution.delete(key);
    }
    const { failedLookupLocations, affectingLocations, alternateResult } = resolution;
    if (resolutionsWithFailedLookups.delete(resolution)) {
      let removeAtRoot = false;
      if (failedLookupLocations) {
        for (const failedLookupLocation of failedLookupLocations) {
          removeAtRoot = stopWatchFailedLookupLocation(failedLookupLocation, removeAtRoot, syncDirWatcherRemove);
        }
      }
      if (alternateResult) removeAtRoot = stopWatchFailedLookupLocation(alternateResult, removeAtRoot, syncDirWatcherRemove);
      if (removeAtRoot) removeDirectoryWatcher(rootPath, syncDirWatcherRemove);
    } else if (affectingLocations == null ? void 0 : affectingLocations.length) {
      resolutionsWithOnlyAffectingLocations.delete(resolution);
    }
    if (affectingLocations) {
      for (const affectingLocation of affectingLocations) {
        const watcher = fileWatchesOfAffectingLocations.get(affectingLocation);
        watcher.resolutions--;
        if (syncDirWatcherRemove) closeFileWatcherOfAffectingLocation(watcher, affectingLocation);
      }
    }
  }
  function removeDirectoryWatcher(dirPath, syncDirWatcherRemove) {
    const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
    dirWatcher.refCount--;
    if (syncDirWatcherRemove) closeDirectoryWatchesOfFailedLookup(dirWatcher, dirPath);
  }
  function createDirectoryWatcher(directory, dirPath, nonRecursive) {
    return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, (fileOrDirectory) => {
      const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
      if (cachedDirectoryStructureHost) {
        cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
      }
      scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath);
    }, nonRecursive ? 0 /* None */ : 1 /* Recursive */);
  }
  function removeResolutionsOfFileFromCache(cache, filePath, getResolutionWithResolvedFileName, syncDirWatcherRemove) {
    const resolutions = cache.get(filePath);
    if (resolutions) {
      resolutions.forEach(
        (resolution) => stopWatchFailedLookupLocationOfResolution(
          resolution,
          filePath,
          getResolutionWithResolvedFileName,
          syncDirWatcherRemove
        )
      );
      cache.delete(filePath);
    }
  }
  function removeResolutionsFromProjectReferenceRedirects(filePath) {
    if (!fileExtensionIs(filePath, ".json" /* Json */)) return;
    const program = resolutionHost.getCurrentProgram();
    if (!program) return;
    const resolvedProjectReference = program.getResolvedProjectReferenceByPath(filePath);
    if (!resolvedProjectReference) return;
    resolvedProjectReference.commandLine.fileNames.forEach((f) => removeResolutionsOfFile(resolutionHost.toPath(f)));
  }
  function removeResolutionsOfFile(filePath, syncDirWatcherRemove) {
    removeResolutionsOfFileFromCache(resolvedModuleNames, filePath, getResolvedModule, syncDirWatcherRemove);
    removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath, getResolvedTypeReferenceDirective, syncDirWatcherRemove);
  }
  function invalidateResolutions(resolutions, canInvalidate) {
    if (!resolutions) return false;
    let invalidated = false;
    resolutions.forEach((resolution) => {
      if (resolution.isInvalidated || !canInvalidate(resolution)) return;
      resolution.isInvalidated = invalidated = true;
      for (const containingFilePath of Debug.checkDefined(resolution.files)) {
        (filesWithInvalidatedResolutions ?? (filesWithInvalidatedResolutions = /* @__PURE__ */ new Set())).add(containingFilePath);
        hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames || endsWith(containingFilePath, inferredTypesContainingFile);
      }
    });
    return invalidated;
  }
  function invalidateResolutionOfFile(filePath) {
    removeResolutionsOfFile(filePath);
    const prevHasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
    if (invalidateResolutions(resolvedFileToResolution.get(filePath), returnTrue) && hasChangedAutomaticTypeDirectiveNames && !prevHasChangedAutomaticTypeDirectiveNames) {
      resolutionHost.onChangedAutomaticTypeDirectiveNames();
    }
  }
  function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap) {
    Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === void 0);
    filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
  }
  function scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, isCreatingWatchedDirectory) {
    if (isCreatingWatchedDirectory) {
      (isInDirectoryChecks || (isInDirectoryChecks = /* @__PURE__ */ new Set())).add(fileOrDirectoryPath);
    } else {
      const updatedPath = removeIgnoredPath(fileOrDirectoryPath);
      if (!updatedPath) return false;
      fileOrDirectoryPath = updatedPath;
      if (resolutionHost.fileIsOpen(fileOrDirectoryPath)) {
        return false;
      }
      const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath);
      if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) || isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) {
        (failedLookupChecks || (failedLookupChecks = /* @__PURE__ */ new Set())).add(fileOrDirectoryPath);
        (startsWithPathChecks || (startsWithPathChecks = /* @__PURE__ */ new Set())).add(fileOrDirectoryPath);
      } else {
        if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
          return false;
        }
        if (fileExtensionIs(fileOrDirectoryPath, ".map")) {
          return false;
        }
        (failedLookupChecks || (failedLookupChecks = /* @__PURE__ */ new Set())).add(fileOrDirectoryPath);
        const packagePath = parseNodeModuleFromPath(
          fileOrDirectoryPath,
          /*isFolder*/
          true
        );
        if (packagePath) (startsWithPathChecks || (startsWithPathChecks = /* @__PURE__ */ new Set())).add(packagePath);
      }
    }
    resolutionHost.scheduleInvalidateResolutionsOfFailedLookupLocations();
  }
  function invalidatePackageJsonMap() {
    const packageJsonMap = moduleResolutionCache.getPackageJsonInfoCache().getInternalMap();
    if (packageJsonMap && (failedLookupChecks || startsWithPathChecks || isInDirectoryChecks)) {
      packageJsonMap.forEach((_value, path) => isInvalidatedFailedLookup(path) ? packageJsonMap.delete(path) : void 0);
    }
  }
  function invalidateResolutionsOfFailedLookupLocations() {
    var _a;
    if (allModuleAndTypeResolutionsAreInvalidated) {
      affectingPathChecksForFile = void 0;
      invalidatePackageJsonMap();
      if (failedLookupChecks || startsWithPathChecks || isInDirectoryChecks || affectingPathChecks) {
        invalidateResolutions(resolvedLibraries, canInvalidateFailedLookupResolution);
      }
      failedLookupChecks = void 0;
      startsWithPathChecks = void 0;
      isInDirectoryChecks = void 0;
      affectingPathChecks = void 0;
      return true;
    }
    let invalidated = false;
    if (affectingPathChecksForFile) {
      (_a = resolutionHost.getCurrentProgram()) == null ? void 0 : _a.getSourceFiles().forEach((f) => {
        if (some(f.packageJsonLocations, (location) => affectingPathChecksForFile.has(location))) {
          (filesWithInvalidatedResolutions ?? (filesWithInvalidatedResolutions = /* @__PURE__ */ new Set())).add(f.path);
          invalidated = true;
        }
      });
      affectingPathChecksForFile = void 0;
    }
    if (!failedLookupChecks && !startsWithPathChecks && !isInDirectoryChecks && !affectingPathChecks) {
      return invalidated;
    }
    invalidated = invalidateResolutions(resolutionsWithFailedLookups, canInvalidateFailedLookupResolution) || invalidated;
    invalidatePackageJsonMap();
    failedLookupChecks = void 0;
    startsWithPathChecks = void 0;
    isInDirectoryChecks = void 0;
    invalidated = invalidateResolutions(resolutionsWithOnlyAffectingLocations, canInvalidatedFailedLookupResolutionWithAffectingLocation) || invalidated;
    affectingPathChecks = void 0;
    return invalidated;
  }
  function canInvalidateFailedLookupResolution(resolution) {
    var _a;
    if (canInvalidatedFailedLookupResolutionWithAffectingLocation(resolution)) return true;
    if (!failedLookupChecks && !startsWithPathChecks && !isInDirectoryChecks) return false;
    return ((_a = resolution.failedLookupLocations) == null ? void 0 : _a.some((location) => isInvalidatedFailedLookup(resolutionHost.toPath(location)))) || !!resolution.alternateResult && isInvalidatedFailedLookup(resolutionHost.toPath(resolution.alternateResult));
  }
  function isInvalidatedFailedLookup(locationPath) {
    return (failedLookupChecks == null ? void 0 : failedLookupChecks.has(locationPath)) || firstDefinedIterator((startsWithPathChecks == null ? void 0 : startsWithPathChecks.keys()) || [], (fileOrDirectoryPath) => startsWith(locationPath, fileOrDirectoryPath) ? true : void 0) || firstDefinedIterator((isInDirectoryChecks == null ? void 0 : isInDirectoryChecks.keys()) || [], (dirPath) => locationPath.length > dirPath.length && startsWith(locationPath, dirPath) && (isDiskPathRoot(dirPath) || locationPath[dirPath.length] === directorySeparator) ? true : void 0);
  }
  function canInvalidatedFailedLookupResolutionWithAffectingLocation(resolution) {
    var _a;
    return !!affectingPathChecks && ((_a = resolution.affectingLocations) == null ? void 0 : _a.some((location) => affectingPathChecks.has(location)));
  }
  function closeTypeRootsWatch() {
    clearMap(typeRootsWatches, closeFileWatcher);
  }
  function createTypeRootsWatch(typeRoot) {
    return canWatchTypeRootPath(typeRoot) ? resolutionHost.watchTypeRootsDirectory(typeRoot, (fileOrDirectory) => {
      const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
      if (cachedDirectoryStructureHost) {
        cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
      }
      hasChangedAutomaticTypeDirectiveNames = true;
      resolutionHost.onChangedAutomaticTypeDirectiveNames();
      const dirPath = getDirectoryToWatchFailedLookupLocationFromTypeRoot(
        typeRoot,
        resolutionHost.toPath(typeRoot),
        rootPath,
        rootPathComponents,
        getCurrentDirectory,
        (dirPath2) => directoryWatchesOfFailedLookups.has(dirPath2) || dirPathToSymlinkPackageRefCount.has(dirPath2)
      );
      if (dirPath) {
        scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath);
      }
    }, 1 /* Recursive */) : noopFileWatcher;
  }
  function updateTypeRootsWatch() {
    const options = resolutionHost.getCompilationSettings();
    if (options.types) {
      closeTypeRootsWatch();
      return;
    }
    const typeRoots = getEffectiveTypeRoots(options, { getCurrentDirectory });
    if (typeRoots) {
      mutateMap(
        typeRootsWatches,
        new Set(typeRoots),
        {
          createNewValue: createTypeRootsWatch,
          onDeleteValue: closeFileWatcher
        }
      );
    } else {
      closeTypeRootsWatch();
    }
  }
  function canWatchTypeRootPath(typeRoot) {
    if (resolutionHost.getCompilationSettings().typeRoots) return true;
    return canWatchAtTypes(resolutionHost.toPath(typeRoot));
  }
}
function resolutionIsSymlink(resolution) {
  var _a, _b;
  return !!(((_a = resolution.resolvedModule) == null ? void 0 : _a.originalPath) || ((_b = resolution.resolvedTypeReferenceDirective) == null ? void 0 : _b.originalPath));
}

// src/compiler/watch.ts
var sysFormatDiagnosticsHost = sys ? {
  getCurrentDirectory: () => sys.getCurrentDirectory(),
  getNewLine: () => sys.newLine,
  getCanonicalFileName: createGetCanonicalFileName(sys.useCaseSensitiveFileNames)
} : void 0;
function createDiagnosticReporter(system, pretty) {
  const host = system === sys && sysFormatDiagnosticsHost ? sysFormatDiagnosticsHost : {
    getCurrentDirectory: () => system.getCurrentDirectory(),
    getNewLine: () => system.newLine,
    getCanonicalFileName: createGetCanonicalFileName(system.useCaseSensitiveFileNames)
  };
  if (!pretty) {
    return (diagnostic) => system.write(formatDiagnostic(diagnostic, host));
  }
  const diagnostics = new Array(1);
  return (diagnostic) => {
    diagnostics[0] = diagnostic;
    system.write(formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
    diagnostics[0] = void 0;
  };
}
function clearScreenIfNotWatchingForFileChanges(system, diagnostic, options) {
  if (system.clearScreen && !options.preserveWatchOutput && !options.extendedDiagnostics && !options.diagnostics && contains(screenStartingMessageCodes, diagnostic.code)) {
    system.clearScreen();
    return true;
  }
  return false;
}
var screenStartingMessageCodes = [
  Diagnostics.Starting_compilation_in_watch_mode.code,
  Diagnostics.File_change_detected_Starting_incremental_compilation.code
];
function getPlainDiagnosticFollowingNewLines(diagnostic, newLine) {
  return contains(screenStartingMessageCodes, diagnostic.code) ? newLine + newLine : newLine;
}
function getLocaleTimeString(system) {
  return !system.now ? (/* @__PURE__ */ new Date()).toLocaleTimeString() : (
    // On some systems / builds of Node, there's a non-breaking space between the time and AM/PM.
    // This branch is solely for testing, so just switch it to a normal space for baseline stability.
    // See:
    //     - https://github.com/nodejs/node/issues/45171
    //     - https://github.com/nodejs/node/issues/45753
    system.now().toLocaleTimeString("en-US", { timeZone: "UTC" }).replace("\u202F", " ")
  );
}
function createWatchStatusReporter(system, pretty) {
  return pretty ? (diagnostic, newLine, options) => {
    clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
    let output = `[${formatColorAndReset(getLocaleTimeString(system), "\x1B[90m" /* Grey */)}] `;
    output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine}`;
    system.write(output);
  } : (diagnostic, newLine, options) => {
    let output = "";
    if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) {
      output += newLine;
    }
    output += `${getLocaleTimeString(system)} - `;
    output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${getPlainDiagnosticFollowingNewLines(diagnostic, newLine)}`;
    system.write(output);
  };
}
function parseConfigFileWithSystem(configFileName, optionsToExtend, extendedConfigCache, watchOptionsToExtend, system, reportDiagnostic) {
  const host = system;
  host.onUnRecoverableConfigFileDiagnostic = (diagnostic) => reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic);
  const result = getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host, extendedConfigCache, watchOptionsToExtend);
  host.onUnRecoverableConfigFileDiagnostic = void 0;
  return result;
}
function getErrorCountForSummary(diagnostics) {
  return countWhere(diagnostics, (diagnostic) => diagnostic.category === 1 /* Error */);
}
function getFilesInErrorForSummary(diagnostics) {
  const filesInError = filter(diagnostics, (diagnostic) => diagnostic.category === 1 /* Error */).map(
    (errorDiagnostic) => {
      if (errorDiagnostic.file === void 0) return;
      return `${errorDiagnostic.file.fileName}`;
    }
  );
  return filesInError.map((fileName) => {
    if (fileName === void 0) {
      return void 0;
    }
    const diagnosticForFileName = find(diagnostics, (diagnostic) => diagnostic.file !== void 0 && diagnostic.file.fileName === fileName);
    if (diagnosticForFileName !== void 0) {
      const { line } = getLineAndCharacterOfPosition(diagnosticForFileName.file, diagnosticForFileName.start);
      return {
        fileName,
        line: line + 1
      };
    }
  });
}
function getWatchErrorSummaryDiagnosticMessage(errorCount) {
  return errorCount === 1 ? Diagnostics.Found_1_error_Watching_for_file_changes : Diagnostics.Found_0_errors_Watching_for_file_changes;
}
function prettyPathForFileError(error, cwd) {
  const line = formatColorAndReset(":" + error.line, "\x1B[90m" /* Grey */);
  if (pathIsAbsolute(error.fileName) && pathIsAbsolute(cwd)) {
    return getRelativePathFromDirectory(
      cwd,
      error.fileName,
      /*ignoreCase*/
      false
    ) + line;
  }
  return error.fileName + line;
}
function getErrorSummaryText(errorCount, filesInError, newLine, host) {
  if (errorCount === 0) return "";
  const nonNilFiles = filesInError.filter((fileInError) => fileInError !== void 0);
  const distinctFileNamesWithLines = nonNilFiles.map((fileInError) => `${fileInError.fileName}:${fileInError.line}`).filter((value, index, self) => self.indexOf(value) === index);
  const firstFileReference = nonNilFiles[0] && prettyPathForFileError(nonNilFiles[0], host.getCurrentDirectory());
  let messageAndArgs;
  if (errorCount === 1) {
    messageAndArgs = filesInError[0] !== void 0 ? [Diagnostics.Found_1_error_in_0, firstFileReference] : [Diagnostics.Found_1_error];
  } else {
    messageAndArgs = distinctFileNamesWithLines.length === 0 ? [Diagnostics.Found_0_errors, errorCount] : distinctFileNamesWithLines.length === 1 ? [Diagnostics.Found_0_errors_in_the_same_file_starting_at_Colon_1, errorCount, firstFileReference] : [Diagnostics.Found_0_errors_in_1_files, errorCount, distinctFileNamesWithLines.length];
  }
  const d = createCompilerDiagnostic(...messageAndArgs);
  const suffix = distinctFileNamesWithLines.length > 1 ? createTabularErrorsDisplay(nonNilFiles, host) : "";
  return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}${suffix}`;
}
function createTabularErrorsDisplay(filesInError, host) {
  const distinctFiles = filesInError.filter((value, index, self) => index === self.findIndex((file) => (file == null ? void 0 : file.fileName) === (value == null ? void 0 : value.fileName)));
  if (distinctFiles.length === 0) return "";
  const numberLength = (num) => Math.log(num) * Math.LOG10E + 1;
  const fileToErrorCount = distinctFiles.map((file) => [file, countWhere(filesInError, (fileInError) => fileInError.fileName === file.fileName)]);
  const maxErrors = fileToErrorCount.reduce((acc, value) => Math.max(acc, value[1] || 0), 0);
  const headerRow = Diagnostics.Errors_Files.message;
  const leftColumnHeadingLength = headerRow.split(" ")[0].length;
  const leftPaddingGoal = Math.max(leftColumnHeadingLength, numberLength(maxErrors));
  const headerPadding = Math.max(numberLength(maxErrors) - leftColumnHeadingLength, 0);
  let tabularData = "";
  tabularData += " ".repeat(headerPadding) + headerRow + "\n";
  fileToErrorCount.forEach((row) => {
    const [file, errorCount] = row;
    const errorCountDigitsLength = Math.log(errorCount) * Math.LOG10E + 1 | 0;
    const leftPadding = errorCountDigitsLength < leftPaddingGoal ? " ".repeat(leftPaddingGoal - errorCountDigitsLength) : "";
    const fileRef = prettyPathForFileError(file, host.getCurrentDirectory());
    tabularData += `${leftPadding}${errorCount}  ${fileRef}
`;
  });
  return tabularData;
}
function isBuilderProgram2(program) {
  return !!program.getState;
}
function listFiles(program, write) {
  const options = program.getCompilerOptions();
  if (options.explainFiles) {
    explainFiles(isBuilderProgram2(program) ? program.getProgram() : program, write);
  } else if (options.listFiles || options.listFilesOnly) {
    forEach(program.getSourceFiles(), (file) => {
      write(file.fileName);
    });
  }
}
function explainFiles(program, write) {
  var _a, _b;
  const reasons = program.getFileIncludeReasons();
  const relativeFileName = (fileName) => convertToRelativePath(fileName, program.getCurrentDirectory(), program.getCanonicalFileName);
  for (const file of program.getSourceFiles()) {
    write(`${toFileName(file, relativeFileName)}`);
    (_a = reasons.get(file.path)) == null ? void 0 : _a.forEach((reason) => write(`  ${fileIncludeReasonToDiagnostics(program, reason, relativeFileName).messageText}`));
    (_b = explainIfFileIsRedirectAndImpliedFormat(file, relativeFileName)) == null ? void 0 : _b.forEach((d) => write(`  ${d.messageText}`));
  }
}
function explainIfFileIsRedirectAndImpliedFormat(file, fileNameConvertor) {
  var _a;
  let result;
  if (file.path !== file.resolvedPath) {
    (result ?? (result = [])).push(chainDiagnosticMessages(
      /*details*/
      void 0,
      Diagnostics.File_is_output_of_project_reference_source_0,
      toFileName(file.originalFileName, fileNameConvertor)
    ));
  }
  if (file.redirectInfo) {
    (result ?? (result = [])).push(chainDiagnosticMessages(
      /*details*/
      void 0,
      Diagnostics.File_redirects_to_file_0,
      toFileName(file.redirectInfo.redirectTarget, fileNameConvertor)
    ));
  }
  if (isExternalOrCommonJsModule(file)) {
    switch (file.impliedNodeFormat) {
      case 99 /* ESNext */:
        if (file.packageJsonScope) {
          (result ?? (result = [])).push(chainDiagnosticMessages(
            /*details*/
            void 0,
            Diagnostics.File_is_ECMAScript_module_because_0_has_field_type_with_value_module,
            toFileName(last(file.packageJsonLocations), fileNameConvertor)
          ));
        }
        break;
      case 1 /* CommonJS */:
        if (file.packageJsonScope) {
          (result ?? (result = [])).push(chainDiagnosticMessages(
            /*details*/
            void 0,
            file.packageJsonScope.contents.packageJsonContent.type ? Diagnostics.File_is_CommonJS_module_because_0_has_field_type_whose_value_is_not_module : Diagnostics.File_is_CommonJS_module_because_0_does_not_have_field_type,
            toFileName(last(file.packageJsonLocations), fileNameConvertor)
          ));
        } else if ((_a = file.packageJsonLocations) == null ? void 0 : _a.length) {
          (result ?? (result = [])).push(chainDiagnosticMessages(
            /*details*/
            void 0,
            Diagnostics.File_is_CommonJS_module_because_package_json_was_not_found
          ));
        }
        break;
    }
  }
  return result;
}
function getMatchedFileSpec(program, fileName) {
  var _a;
  const configFile = program.getCompilerOptions().configFile;
  if (!((_a = configFile == null ? void 0 : configFile.configFileSpecs) == null ? void 0 : _a.validatedFilesSpec)) return void 0;
  const filePath = program.getCanonicalFileName(fileName);
  const basePath = getDirectoryPath(getNormalizedAbsolutePath(configFile.fileName, program.getCurrentDirectory()));
  const index = findIndex(configFile.configFileSpecs.validatedFilesSpec, (fileSpec) => program.getCanonicalFileName(getNormalizedAbsolutePath(fileSpec, basePath)) === filePath);
  return index !== -1 ? configFile.configFileSpecs.validatedFilesSpecBeforeSubstitution[index] : void 0;
}
function getMatchedIncludeSpec(program, fileName) {
  var _a, _b;
  const configFile = program.getCompilerOptions().configFile;
  if (!((_a = configFile == null ? void 0 : configFile.configFileSpecs) == null ? void 0 : _a.validatedIncludeSpecs)) return void 0;
  if (configFile.configFileSpecs.isDefaultIncludeSpec) return true;
  const isJsonFile = fileExtensionIs(fileName, ".json" /* Json */);
  const basePath = getDirectoryPath(getNormalizedAbsolutePath(configFile.fileName, program.getCurrentDirectory()));
  const useCaseSensitiveFileNames2 = program.useCaseSensitiveFileNames();
  const index = findIndex((_b = configFile == null ? void 0 : configFile.configFileSpecs) == null ? void 0 : _b.validatedIncludeSpecs, (includeSpec) => {
    if (isJsonFile && !endsWith(includeSpec, ".json" /* Json */)) return false;
    const pattern = getPatternFromSpec(includeSpec, basePath, "files");
    return !!pattern && getRegexFromPattern(`(${pattern})$`, useCaseSensitiveFileNames2).test(fileName);
  });
  return index !== -1 ? configFile.configFileSpecs.validatedIncludeSpecsBeforeSubstitution[index] : void 0;
}
function fileIncludeReasonToDiagnostics(program, reason, fileNameConvertor) {
  var _a, _b;
  const options = program.getCompilerOptions();
  if (isReferencedFile(reason)) {
    const referenceLocation = getReferencedFileLocation(program, reason);
    const referenceText = isReferenceFileLocation(referenceLocation) ? referenceLocation.file.text.substring(referenceLocation.pos, referenceLocation.end) : `"${referenceLocation.text}"`;
    let message;
    Debug.assert(isReferenceFileLocation(referenceLocation) || reason.kind === 3 /* Import */, "Only synthetic references are imports");
    switch (reason.kind) {
      case 3 /* Import */:
        if (isReferenceFileLocation(referenceLocation)) {
          message = referenceLocation.packageId ? Diagnostics.Imported_via_0_from_file_1_with_packageId_2 : Diagnostics.Imported_via_0_from_file_1;
        } else if (referenceLocation.text === externalHelpersModuleNameText) {
          message = referenceLocation.packageId ? Diagnostics.Imported_via_0_from_file_1_with_packageId_2_to_import_importHelpers_as_specified_in_compilerOptions : Diagnostics.Imported_via_0_from_file_1_to_import_importHelpers_as_specified_in_compilerOptions;
        } else {
          message = referenceLocation.packageId ? Diagnostics.Imported_via_0_from_file_1_with_packageId_2_to_import_jsx_and_jsxs_factory_functions : Diagnostics.Imported_via_0_from_file_1_to_import_jsx_and_jsxs_factory_functions;
        }
        break;
      case 4 /* ReferenceFile */:
        Debug.assert(!referenceLocation.packageId);
        message = Diagnostics.Referenced_via_0_from_file_1;
        break;
      case 5 /* TypeReferenceDirective */:
        message = referenceLocation.packageId ? Diagnostics.Type_library_referenced_via_0_from_file_1_with_packageId_2 : Diagnostics.Type_library_referenced_via_0_from_file_1;
        break;
      case 7 /* LibReferenceDirective */:
        Debug.assert(!referenceLocation.packageId);
        message = Diagnostics.Library_referenced_via_0_from_file_1;
        break;
      default:
        Debug.assertNever(reason);
    }
    return chainDiagnosticMessages(
      /*details*/
      void 0,
      message,
      referenceText,
      toFileName(referenceLocation.file, fileNameConvertor),
      referenceLocation.packageId && packageIdToString(referenceLocation.packageId)
    );
  }
  switch (reason.kind) {
    case 0 /* RootFile */:
      if (!((_a = options.configFile) == null ? void 0 : _a.configFileSpecs)) return chainDiagnosticMessages(
        /*details*/
        void 0,
        Diagnostics.Root_file_specified_for_compilation
      );
      const fileName = getNormalizedAbsolutePath(program.getRootFileNames()[reason.index], program.getCurrentDirectory());
      const matchedByFiles = getMatchedFileSpec(program, fileName);
      if (matchedByFiles) return chainDiagnosticMessages(
        /*details*/
        void 0,
        Diagnostics.Part_of_files_list_in_tsconfig_json
      );
      const matchedByInclude = getMatchedIncludeSpec(program, fileName);
      return isString(matchedByInclude) ? chainDiagnosticMessages(
        /*details*/
        void 0,
        Diagnostics.Matched_by_include_pattern_0_in_1,
        matchedByInclude,
        toFileName(options.configFile, fileNameConvertor)
      ) : (
        // Could be additional files specified as roots or matched by default include
        chainDiagnosticMessages(
          /*details*/
          void 0,
          matchedByInclude ? Diagnostics.Matched_by_default_include_pattern_Asterisk_Asterisk_Slash_Asterisk : Diagnostics.Root_file_specified_for_compilation
        )
      );
    case 1 /* SourceFromProjectReference */:
    case 2 /* OutputFromProjectReference */:
      const isOutput = reason.kind === 2 /* OutputFromProjectReference */;
      const referencedResolvedRef = Debug.checkDefined((_b = program.getResolvedProjectReferences()) == null ? void 0 : _b[reason.index]);
      return chainDiagnosticMessages(
        /*details*/
        void 0,
        options.outFile ? isOutput ? Diagnostics.Output_from_referenced_project_0_included_because_1_specified : Diagnostics.Source_from_referenced_project_0_included_because_1_specified : isOutput ? Diagnostics.Output_from_referenced_project_0_included_because_module_is_specified_as_none : Diagnostics.Source_from_referenced_project_0_included_because_module_is_specified_as_none,
        toFileName(referencedResolvedRef.sourceFile.fileName, fileNameConvertor),
        options.outFile ? "--outFile" : "--out"
      );
    case 8 /* AutomaticTypeDirectiveFile */: {
      const messageAndArgs = options.types ? reason.packageId ? [Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] : [Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions, reason.typeReference] : reason.packageId ? [Diagnostics.Entry_point_for_implicit_type_library_0_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] : [Diagnostics.Entry_point_for_implicit_type_library_0, reason.typeReference];
      return chainDiagnosticMessages(
        /*details*/
        void 0,
        ...messageAndArgs
      );
    }
    case 6 /* LibFile */: {
      if (reason.index !== void 0) return chainDiagnosticMessages(
        /*details*/
        void 0,
        Diagnostics.Library_0_specified_in_compilerOptions,
        options.lib[reason.index]
      );
      const target = getNameOfScriptTarget(getEmitScriptTarget(options));
      const messageAndArgs = target ? [Diagnostics.Default_library_for_target_0, target] : [Diagnostics.Default_library];
      return chainDiagnosticMessages(
        /*details*/
        void 0,
        ...messageAndArgs
      );
    }
    default:
      Debug.assertNever(reason);
  }
}
function toFileName(file, fileNameConvertor) {
  const fileName = isString(file) ? file : file.fileName;
  return fileNameConvertor ? fileNameConvertor(fileName) : fileName;
}
function emitFilesAndReportErrors(program, reportDiagnostic, write, reportSummary, writeFile2, cancellationToken, emitOnlyDtsFiles, customTransformers) {
  const isListFilesOnly = !!program.getCompilerOptions().listFilesOnly;
  const allDiagnostics = program.getConfigFileParsingDiagnostics().slice();
  const configFileParsingDiagnosticsLength = allDiagnostics.length;
  addRange(allDiagnostics, program.getSyntacticDiagnostics(
    /*sourceFile*/
    void 0,
    cancellationToken
  ));
  if (allDiagnostics.length === configFileParsingDiagnosticsLength) {
    addRange(allDiagnostics, program.getOptionsDiagnostics(cancellationToken));
    if (!isListFilesOnly) {
      addRange(allDiagnostics, program.getGlobalDiagnostics(cancellationToken));
      if (allDiagnostics.length === configFileParsingDiagnosticsLength) {
        addRange(allDiagnostics, program.getSemanticDiagnostics(
          /*sourceFile*/
          void 0,
          cancellationToken
        ));
      }
    }
  }
  const emitResult = isListFilesOnly ? { emitSkipped: true, diagnostics: emptyArray } : program.emit(
    /*targetSourceFile*/
    void 0,
    writeFile2,
    cancellationToken,
    emitOnlyDtsFiles,
    customTransformers
  );
  const { emittedFiles, diagnostics: emitDiagnostics } = emitResult;
  addRange(allDiagnostics, emitDiagnostics);
  const diagnostics = sortAndDeduplicateDiagnostics(allDiagnostics);
  diagnostics.forEach(reportDiagnostic);
  if (write) {
    const currentDir = program.getCurrentDirectory();
    forEach(emittedFiles, (file) => {
      const filepath = getNormalizedAbsolutePath(file, currentDir);
      write(`TSFILE: ${filepath}`);
    });
    listFiles(program, write);
  }
  if (reportSummary) {
    reportSummary(getErrorCountForSummary(diagnostics), getFilesInErrorForSummary(diagnostics));
  }
  return {
    emitResult,
    diagnostics
  };
}
function emitFilesAndReportErrorsAndGetExitStatus(program, reportDiagnostic, write, reportSummary, writeFile2, cancellationToken, emitOnlyDtsFiles, customTransformers) {
  const { emitResult, diagnostics } = emitFilesAndReportErrors(
    program,
    reportDiagnostic,
    write,
    reportSummary,
    writeFile2,
    cancellationToken,
    emitOnlyDtsFiles,
    customTransformers
  );
  if (emitResult.emitSkipped && diagnostics.length > 0) {
    return 1 /* DiagnosticsPresent_OutputsSkipped */;
  } else if (diagnostics.length > 0) {
    return 2 /* DiagnosticsPresent_OutputsGenerated */;
  }
  return 0 /* Success */;
}
var noopFileWatcher = { close: noop };
var returnNoopFileWatcher = () => noopFileWatcher;
function createWatchHost(system = sys, reportWatchStatus2) {
  const onWatchStatusChange = reportWatchStatus2 || createWatchStatusReporter(system);
  return {
    onWatchStatusChange,
    watchFile: maybeBind(system, system.watchFile) || returnNoopFileWatcher,
    watchDirectory: maybeBind(system, system.watchDirectory) || returnNoopFileWatcher,
    setTimeout: maybeBind(system, system.setTimeout) || noop,
    clearTimeout: maybeBind(system, system.clearTimeout) || noop
  };
}
var WatchType = {
  ConfigFile: "Config file",
  ExtendedConfigFile: "Extended config file",
  SourceFile: "Source file",
  MissingFile: "Missing file",
  WildcardDirectory: "Wild card directory",
  FailedLookupLocations: "Failed Lookup Locations",
  AffectingFileLocation: "File location affecting resolution",
  TypeRoots: "Type roots",
  ConfigFileOfReferencedProject: "Config file of referened project",
  ExtendedConfigOfReferencedProject: "Extended config file of referenced project",
  WildcardDirectoryOfReferencedProject: "Wild card directory of referenced project",
  PackageJson: "package.json file",
  ClosedScriptInfo: "Closed Script info",
  ConfigFileForInferredRoot: "Config file for the inferred project root",
  NodeModules: "node_modules for closed script infos and package.jsons affecting module specifier cache",
  MissingSourceMapFile: "Missing source map file",
  NoopConfigFileForInferredRoot: "Noop Config file for the inferred project root",
  MissingGeneratedFile: "Missing generated file",
  NodeModulesForModuleSpecifierCache: "node_modules for module specifier cache invalidation",
  TypingInstallerLocationFile: "File location for typing installer",
  TypingInstallerLocationDirectory: "Directory location for typing installer"
};
function createWatchFactory(host, options) {
  const watchLogLevel = host.trace ? options.extendedDiagnostics ? 2 /* Verbose */ : options.diagnostics ? 1 /* TriggerOnly */ : 0 /* None */ : 0 /* None */;
  const writeLog = watchLogLevel !== 0 /* None */ ? (s) => host.trace(s) : noop;
  const result = getWatchFactory(host, watchLogLevel, writeLog);
  result.writeLog = writeLog;
  return result;
}
function createCompilerHostFromProgramHost(host, getCompilerOptions, directoryStructureHost = host) {
  const useCaseSensitiveFileNames2 = host.useCaseSensitiveFileNames();
  const compilerHost = {
    getSourceFile: createGetSourceFile(
      (fileName, encoding) => !encoding ? compilerHost.readFile(fileName) : host.readFile(fileName, encoding),
      /*setParentNodes*/
      void 0
    ),
    getDefaultLibLocation: maybeBind(host, host.getDefaultLibLocation),
    getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),
    writeFile: createWriteFileMeasuringIO(
      (path, data, writeByteOrderMark) => host.writeFile(path, data, writeByteOrderMark),
      (path) => host.createDirectory(path),
      (path) => host.directoryExists(path)
    ),
    getCurrentDirectory: memoize(() => host.getCurrentDirectory()),
    useCaseSensitiveFileNames: () => useCaseSensitiveFileNames2,
    getCanonicalFileName: createGetCanonicalFileName(useCaseSensitiveFileNames2),
    getNewLine: () => getNewLineCharacter(getCompilerOptions()),
    fileExists: (f) => host.fileExists(f),
    readFile: (f) => host.readFile(f),
    trace: maybeBind(host, host.trace),
    directoryExists: maybeBind(directoryStructureHost, directoryStructureHost.directoryExists),
    getDirectories: maybeBind(directoryStructureHost, directoryStructureHost.getDirectories),
    realpath: maybeBind(host, host.realpath),
    getEnvironmentVariable: maybeBind(host, host.getEnvironmentVariable) || (() => ""),
    createHash: maybeBind(host, host.createHash),
    readDirectory: maybeBind(host, host.readDirectory),
    storeSignatureInfo: host.storeSignatureInfo,
    jsDocParsingMode: host.jsDocParsingMode
  };
  return compilerHost;
}
function getSourceFileVersionAsHashFromText(host, text) {
  if (text.match(sourceMapCommentRegExpDontCareLineStart)) {
    let lineEnd = text.length;
    let lineStart = lineEnd;
    for (let pos = lineEnd - 1; pos >= 0; pos--) {
      const ch = text.charCodeAt(pos);
      switch (ch) {
        case 10 /* lineFeed */:
          if (pos && text.charCodeAt(pos - 1) === 13 /* carriageReturn */) {
            pos--;
          }
        case 13 /* carriageReturn */:
          break;
        default:
          if (ch < 127 /* maxAsciiCharacter */ || !isLineBreak(ch)) {
            lineStart = pos;
            continue;
          }
          break;
      }
      const line = text.substring(lineStart, lineEnd);
      if (line.match(sourceMapCommentRegExp)) {
        text = text.substring(0, lineStart);
        break;
      } else if (!line.match(whitespaceOrMapCommentRegExp)) {
        break;
      }
      lineEnd = lineStart;
    }
  }
  return (host.createHash || generateDjb2Hash)(text);
}
function setGetSourceFileAsHashVersioned(compilerHost) {
  const originalGetSourceFile = compilerHost.getSourceFile;
  compilerHost.getSourceFile = (...args) => {
    const result = originalGetSourceFile.call(compilerHost, ...args);
    if (result) {
      result.version = getSourceFileVersionAsHashFromText(compilerHost, result.text);
    }
    return result;
  };
}
function createProgramHost(system, createProgram2) {
  const getDefaultLibLocation = memoize(() => getDirectoryPath(normalizePath(system.getExecutingFilePath())));
  return {
    useCaseSensitiveFileNames: () => system.useCaseSensitiveFileNames,
    getNewLine: () => system.newLine,
    getCurrentDirectory: memoize(() => system.getCurrentDirectory()),
    getDefaultLibLocation,
    getDefaultLibFileName: (options) => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options)),
    fileExists: (path) => system.fileExists(path),
    readFile: (path, encoding) => system.readFile(path, encoding),
    directoryExists: (path) => system.directoryExists(path),
    getDirectories: (path) => system.getDirectories(path),
    readDirectory: (path, extensions, exclude, include, depth) => system.readDirectory(path, extensions, exclude, include, depth),
    realpath: maybeBind(system, system.realpath),
    getEnvironmentVariable: maybeBind(system, system.getEnvironmentVariable),
    trace: (s) => system.write(s + system.newLine),
    createDirectory: (path) => system.createDirectory(path),
    writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
    createHash: maybeBind(system, system.createHash),
    createProgram: createProgram2 || createEmitAndSemanticDiagnosticsBuilderProgram,
    storeSignatureInfo: system.storeSignatureInfo,
    now: maybeBind(system, system.now)
  };
}
function createWatchCompilerHost(system = sys, createProgram2, reportDiagnostic, reportWatchStatus2) {
  const write = (s) => system.write(s + system.newLine);
  const result = createProgramHost(system, createProgram2);
  copyProperties(result, createWatchHost(system, reportWatchStatus2));
  result.afterProgramCreate = (builderProgram) => {
    const compilerOptions = builderProgram.getCompilerOptions();
    const newLine = getNewLineCharacter(compilerOptions);
    emitFilesAndReportErrors(
      builderProgram,
      reportDiagnostic,
      write,
      (errorCount) => result.onWatchStatusChange(
        createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(errorCount), errorCount),
        newLine,
        compilerOptions,
        errorCount
      )
    );
  };
  return result;
}
function reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic) {
  reportDiagnostic(diagnostic);
  system.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
}
function createWatchCompilerHostOfConfigFile({
  configFileName,
  optionsToExtend,
  watchOptionsToExtend,
  extraFileExtensions,
  system,
  createProgram: createProgram2,
  reportDiagnostic,
  reportWatchStatus: reportWatchStatus2
}) {
  const diagnosticReporter = reportDiagnostic || createDiagnosticReporter(system);
  const host = createWatchCompilerHost(system, createProgram2, diagnosticReporter, reportWatchStatus2);
  host.onUnRecoverableConfigFileDiagnostic = (diagnostic) => reportUnrecoverableDiagnostic(system, diagnosticReporter, diagnostic);
  host.configFileName = configFileName;
  host.optionsToExtend = optionsToExtend;
  host.watchOptionsToExtend = watchOptionsToExtend;
  host.extraFileExtensions = extraFileExtensions;
  return host;
}
function createWatchCompilerHostOfFilesAndCompilerOptions({
  rootFiles,
  options,
  watchOptions,
  projectReferences,
  system,
  createProgram: createProgram2,
  reportDiagnostic,
  reportWatchStatus: reportWatchStatus2
}) {
  const host = createWatchCompilerHost(system, createProgram2, reportDiagnostic || createDiagnosticReporter(system), reportWatchStatus2);
  host.rootFiles = rootFiles;
  host.options = options;
  host.watchOptions = watchOptions;
  host.projectReferences = projectReferences;
  return host;
}
function performIncrementalCompilation(input) {
  const system = input.system || sys;
  const host = input.host || (input.host = createIncrementalCompilerHost(input.options, system));
  const builderProgram = createIncrementalProgram(input);
  const exitStatus = emitFilesAndReportErrorsAndGetExitStatus(
    builderProgram,
    input.reportDiagnostic || createDiagnosticReporter(system),
    (s) => host.trace && host.trace(s),
    input.reportErrorSummary || input.options.pretty ? (errorCount, filesInError) => system.write(getErrorSummaryText(errorCount, filesInError, system.newLine, host)) : void 0
  );
  if (input.afterProgramEmitAndDiagnostics) input.afterProgramEmitAndDiagnostics(builderProgram);
  return exitStatus;
}

// src/compiler/watchPublic.ts
function readBuilderProgram(compilerOptions, host) {
  const buildInfoPath = getTsBuildInfoEmitOutputFilePath(compilerOptions);
  if (!buildInfoPath) return void 0;
  let buildInfo;
  if (host.getBuildInfo) {
    buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);
  } else {
    const content = host.readFile(buildInfoPath);
    if (!content) return void 0;
    buildInfo = getBuildInfo(buildInfoPath, content);
  }
  if (!buildInfo || buildInfo.version !== version || !buildInfo.program) return void 0;
  return createBuilderProgramUsingProgramBuildInfo(buildInfo, buildInfoPath, host);
}
function createIncrementalCompilerHost(options, system = sys) {
  const host = createCompilerHostWorker(
    options,
    /*setParentNodes*/
    void 0,
    system
  );
  host.createHash = maybeBind(system, system.createHash);
  host.storeSignatureInfo = system.storeSignatureInfo;
  setGetSourceFileAsHashVersioned(host);
  changeCompilerHostLikeToUseCache(host, (fileName) => toPath(fileName, host.getCurrentDirectory(), host.getCanonicalFileName));
  return host;
}
function createIncrementalProgram({
  rootNames,
  options,
  configFileParsingDiagnostics,
  projectReferences,
  host,
  createProgram: createProgram2
}) {
  host = host || createIncrementalCompilerHost(options);
  createProgram2 = createProgram2 || createEmitAndSemanticDiagnosticsBuilderProgram;
  const oldProgram = readBuilderProgram(options, host);
  return createProgram2(rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences);
}
function createWatchProgram(host) {
  let builderProgram;
  let updateLevel;
  let missingFilesMap;
  let watchedWildcardDirectories;
  let timerToUpdateProgram;
  let timerToInvalidateFailedLookupResolutions;
  let parsedConfigs;
  let sharedExtendedConfigFileWatchers;
  let extendedConfigCache = host.extendedConfigCache;
  let reportFileChangeDetectedOnCreateProgram = false;
  const sourceFilesCache = /* @__PURE__ */ new Map();
  let missingFilePathsRequestedForRelease;
  let hasChangedCompilerOptions = false;
  const useCaseSensitiveFileNames2 = host.useCaseSensitiveFileNames();
  const currentDirectory = host.getCurrentDirectory();
  const { configFileName, optionsToExtend: optionsToExtendForConfigFile = {}, watchOptionsToExtend, extraFileExtensions, createProgram: createProgram2 } = host;
  let { rootFiles: rootFileNames, options: compilerOptions, watchOptions, projectReferences } = host;
  let wildcardDirectories;
  let configFileParsingDiagnostics;
  let canConfigFileJsonReportNoInputFiles = false;
  let hasChangedConfigFileParsingErrors = false;
  const cachedDirectoryStructureHost = configFileName === void 0 ? void 0 : createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames2);
  const directoryStructureHost = cachedDirectoryStructureHost || host;
  const parseConfigFileHost = parseConfigHostFromCompilerHostLike(host, directoryStructureHost);
  let newLine = updateNewLine();
  if (configFileName && host.configFileParsingResult) {
    setConfigFileParsingResult(host.configFileParsingResult);
    newLine = updateNewLine();
  }
  reportWatchDiagnostic(Diagnostics.Starting_compilation_in_watch_mode);
  if (configFileName && !host.configFileParsingResult) {
    newLine = getNewLineCharacter(optionsToExtendForConfigFile);
    Debug.assert(!rootFileNames);
    parseConfigFile2();
    newLine = updateNewLine();
  }
  Debug.assert(compilerOptions);
  Debug.assert(rootFileNames);
  const { watchFile: watchFile2, watchDirectory, writeLog } = createWatchFactory(host, compilerOptions);
  const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames2);
  writeLog(`Current directory: ${currentDirectory} CaseSensitiveFileNames: ${useCaseSensitiveFileNames2}`);
  let configFileWatcher;
  if (configFileName) {
    configFileWatcher = watchFile2(configFileName, scheduleProgramReload, 2e3 /* High */, watchOptions, WatchType.ConfigFile);
  }
  const compilerHost = createCompilerHostFromProgramHost(host, () => compilerOptions, directoryStructureHost);
  setGetSourceFileAsHashVersioned(compilerHost);
  const getNewSourceFile = compilerHost.getSourceFile;
  compilerHost.getSourceFile = (fileName, ...args) => getVersionedSourceFileByPath(fileName, toPath3(fileName), ...args);
  compilerHost.getSourceFileByPath = getVersionedSourceFileByPath;
  compilerHost.getNewLine = () => newLine;
  compilerHost.fileExists = fileExists;
  compilerHost.onReleaseOldSourceFile = onReleaseOldSourceFile;
  compilerHost.onReleaseParsedCommandLine = onReleaseParsedCommandLine;
  compilerHost.toPath = toPath3;
  compilerHost.getCompilationSettings = () => compilerOptions;
  compilerHost.useSourceOfProjectReferenceRedirect = maybeBind(host, host.useSourceOfProjectReferenceRedirect);
  compilerHost.watchDirectoryOfFailedLookupLocation = (dir, cb, flags) => watchDirectory(dir, cb, flags, watchOptions, WatchType.FailedLookupLocations);
  compilerHost.watchAffectingFileLocation = (file, cb) => watchFile2(file, cb, 2e3 /* High */, watchOptions, WatchType.AffectingFileLocation);
  compilerHost.watchTypeRootsDirectory = (dir, cb, flags) => watchDirectory(dir, cb, flags, watchOptions, WatchType.TypeRoots);
  compilerHost.getCachedDirectoryStructureHost = () => cachedDirectoryStructureHost;
  compilerHost.scheduleInvalidateResolutionsOfFailedLookupLocations = scheduleInvalidateResolutionsOfFailedLookupLocations;
  compilerHost.onInvalidatedResolution = scheduleProgramUpdate;
  compilerHost.onChangedAutomaticTypeDirectiveNames = scheduleProgramUpdate;
  compilerHost.fileIsOpen = returnFalse;
  compilerHost.getCurrentProgram = getCurrentProgram;
  compilerHost.writeLog = writeLog;
  compilerHost.getParsedCommandLine = getParsedCommandLine;
  const resolutionCache = createResolutionCache(
    compilerHost,
    configFileName ? getDirectoryPath(getNormalizedAbsolutePath(configFileName, currentDirectory)) : currentDirectory,
    /*logChangesWhenResolvingModule*/
    false
  );
  compilerHost.resolveModuleNameLiterals = maybeBind(host, host.resolveModuleNameLiterals);
  compilerHost.resolveModuleNames = maybeBind(host, host.resolveModuleNames);
  if (!compilerHost.resolveModuleNameLiterals && !compilerHost.resolveModuleNames) {
    compilerHost.resolveModuleNameLiterals = resolutionCache.resolveModuleNameLiterals.bind(resolutionCache);
  }
  compilerHost.resolveTypeReferenceDirectiveReferences = maybeBind(host, host.resolveTypeReferenceDirectiveReferences);
  compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives);
  if (!compilerHost.resolveTypeReferenceDirectiveReferences && !compilerHost.resolveTypeReferenceDirectives) {
    compilerHost.resolveTypeReferenceDirectiveReferences = resolutionCache.resolveTypeReferenceDirectiveReferences.bind(resolutionCache);
  }
  compilerHost.resolveLibrary = !host.resolveLibrary ? resolutionCache.resolveLibrary.bind(resolutionCache) : host.resolveLibrary.bind(host);
  compilerHost.getModuleResolutionCache = host.resolveModuleNameLiterals || host.resolveModuleNames ? maybeBind(host, host.getModuleResolutionCache) : () => resolutionCache.getModuleResolutionCache();
  const userProvidedResolution = !!host.resolveModuleNameLiterals || !!host.resolveTypeReferenceDirectiveReferences || !!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
  const customHasInvalidatedResolutions = userProvidedResolution ? maybeBind(host, host.hasInvalidatedResolutions) || returnTrue : returnFalse;
  const customHasInvalidLibResolutions = host.resolveLibrary ? maybeBind(host, host.hasInvalidatedLibResolutions) || returnTrue : returnFalse;
  builderProgram = readBuilderProgram(compilerOptions, compilerHost);
  synchronizeProgram();
  watchConfigFileWildCardDirectories();
  if (configFileName) updateExtendedConfigFilesWatches(toPath3(configFileName), compilerOptions, watchOptions, WatchType.ExtendedConfigFile);
  return configFileName ? { getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, close, getResolutionCache } : { getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, updateRootFileNames, close, getResolutionCache };
  function close() {
    clearInvalidateResolutionsOfFailedLookupLocations();
    resolutionCache.clear();
    clearMap(sourceFilesCache, (value) => {
      if (value && value.fileWatcher) {
        value.fileWatcher.close();
        value.fileWatcher = void 0;
      }
    });
    if (configFileWatcher) {
      configFileWatcher.close();
      configFileWatcher = void 0;
    }
    extendedConfigCache == null ? void 0 : extendedConfigCache.clear();
    extendedConfigCache = void 0;
    if (sharedExtendedConfigFileWatchers) {
      clearMap(sharedExtendedConfigFileWatchers, closeFileWatcherOf);
      sharedExtendedConfigFileWatchers = void 0;
    }
    if (watchedWildcardDirectories) {
      clearMap(watchedWildcardDirectories, closeFileWatcherOf);
      watchedWildcardDirectories = void 0;
    }
    if (missingFilesMap) {
      clearMap(missingFilesMap, closeFileWatcher);
      missingFilesMap = void 0;
    }
    if (parsedConfigs) {
      clearMap(parsedConfigs, (config) => {
        var _a;
        (_a = config.watcher) == null ? void 0 : _a.close();
        config.watcher = void 0;
        if (config.watchedDirectories) clearMap(config.watchedDirectories, closeFileWatcherOf);
        config.watchedDirectories = void 0;
      });
      parsedConfigs = void 0;
    }
    builderProgram = void 0;
  }
  function getResolutionCache() {
    return resolutionCache;
  }
  function getCurrentBuilderProgram() {
    return builderProgram;
  }
  function getCurrentProgram() {
    return builderProgram && builderProgram.getProgramOrUndefined();
  }
  function synchronizeProgram() {
    writeLog(`Synchronizing program`);
    Debug.assert(compilerOptions);
    Debug.assert(rootFileNames);
    clearInvalidateResolutionsOfFailedLookupLocations();
    const program = getCurrentBuilderProgram();
    if (hasChangedCompilerOptions) {
      newLine = updateNewLine();
      if (program && changesAffectModuleResolution(program.getCompilerOptions(), compilerOptions)) {
        resolutionCache.onChangesAffectModuleResolution();
      }
    }
    const { hasInvalidatedResolutions, hasInvalidatedLibResolutions } = resolutionCache.createHasInvalidatedResolutions(customHasInvalidatedResolutions, customHasInvalidLibResolutions);
    const {
      originalReadFile,
      originalFileExists,
      originalDirectoryExists,
      originalCreateDirectory,
      originalWriteFile,
      readFileWithCache
    } = changeCompilerHostLikeToUseCache(compilerHost, toPath3);
    if (isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, (path) => getSourceVersion(path, readFileWithCache), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasInvalidatedLibResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
      if (hasChangedConfigFileParsingErrors) {
        if (reportFileChangeDetectedOnCreateProgram) {
          reportWatchDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation);
        }
        builderProgram = createProgram2(
          /*rootNames*/
          void 0,
          /*options*/
          void 0,
          compilerHost,
          builderProgram,
          configFileParsingDiagnostics,
          projectReferences
        );
        hasChangedConfigFileParsingErrors = false;
      }
    } else {
      if (reportFileChangeDetectedOnCreateProgram) {
        reportWatchDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation);
      }
      createNewProgram(hasInvalidatedResolutions, hasInvalidatedLibResolutions);
    }
    reportFileChangeDetectedOnCreateProgram = false;
    if (host.afterProgramCreate && program !== builderProgram) {
      host.afterProgramCreate(builderProgram);
    }
    compilerHost.readFile = originalReadFile;
    compilerHost.fileExists = originalFileExists;
    compilerHost.directoryExists = originalDirectoryExists;
    compilerHost.createDirectory = originalCreateDirectory;
    compilerHost.writeFile = originalWriteFile;
    return builderProgram;
  }
  function createNewProgram(hasInvalidatedResolutions, hasInvalidatedLibResolutions) {
    writeLog("CreatingProgramWith::");
    writeLog(`  roots: ${JSON.stringify(rootFileNames)}`);
    writeLog(`  options: ${JSON.stringify(compilerOptions)}`);
    if (projectReferences) writeLog(`  projectReferences: ${JSON.stringify(projectReferences)}`);
    const needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !getCurrentProgram();
    hasChangedCompilerOptions = false;
    hasChangedConfigFileParsingErrors = false;
    resolutionCache.startCachingPerDirectoryResolution();
    compilerHost.hasInvalidatedResolutions = hasInvalidatedResolutions;
    compilerHost.hasInvalidatedLibResolutions = hasInvalidatedLibResolutions;
    compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
    const oldProgram = getCurrentProgram();
    builderProgram = createProgram2(rootFileNames, compilerOptions, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
    resolutionCache.finishCachingPerDirectoryResolution(builderProgram.getProgram(), oldProgram);
    updateMissingFilePathsWatch(
      builderProgram.getProgram(),
      missingFilesMap || (missingFilesMap = /* @__PURE__ */ new Map()),
      watchMissingFilePath
    );
    if (needsUpdateInTypeRootWatch) {
      resolutionCache.updateTypeRootsWatch();
    }
    if (missingFilePathsRequestedForRelease) {
      for (const missingFilePath of missingFilePathsRequestedForRelease) {
        if (!missingFilesMap.has(missingFilePath)) {
          sourceFilesCache.delete(missingFilePath);
        }
      }
      missingFilePathsRequestedForRelease = void 0;
    }
  }
  function updateRootFileNames(files) {
    Debug.assert(!configFileName, "Cannot update root file names with config file watch mode");
    rootFileNames = files;
    scheduleProgramUpdate();
  }
  function updateNewLine() {
    return getNewLineCharacter(compilerOptions || optionsToExtendForConfigFile);
  }
  function toPath3(fileName) {
    return toPath(fileName, currentDirectory, getCanonicalFileName);
  }
  function isFileMissingOnHost(hostSourceFile) {
    return typeof hostSourceFile === "boolean";
  }
  function isFilePresenceUnknownOnHost(hostSourceFile) {
    return typeof hostSourceFile.version === "boolean";
  }
  function fileExists(fileName) {
    const path = toPath3(fileName);
    if (isFileMissingOnHost(sourceFilesCache.get(path))) {
      return false;
    }
    return directoryStructureHost.fileExists(fileName);
  }
  function getVersionedSourceFileByPath(fileName, path, languageVersionOrOptions, onError, shouldCreateNewSourceFile) {
    const hostSourceFile = sourceFilesCache.get(path);
    if (isFileMissingOnHost(hostSourceFile)) {
      return void 0;
    }
    const impliedNodeFormat = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions.impliedNodeFormat : void 0;
    if (hostSourceFile === void 0 || shouldCreateNewSourceFile || isFilePresenceUnknownOnHost(hostSourceFile) || hostSourceFile.sourceFile.impliedNodeFormat !== impliedNodeFormat) {
      const sourceFile = getNewSourceFile(fileName, languageVersionOrOptions, onError);
      if (hostSourceFile) {
        if (sourceFile) {
          hostSourceFile.sourceFile = sourceFile;
          hostSourceFile.version = sourceFile.version;
          if (!hostSourceFile.fileWatcher) {
            hostSourceFile.fileWatcher = watchFilePath(path, fileName, onSourceFileChange, 250 /* Low */, watchOptions, WatchType.SourceFile);
          }
        } else {
          if (hostSourceFile.fileWatcher) {
            hostSourceFile.fileWatcher.close();
          }
          sourceFilesCache.set(path, false);
        }
      } else {
        if (sourceFile) {
          const fileWatcher = watchFilePath(path, fileName, onSourceFileChange, 250 /* Low */, watchOptions, WatchType.SourceFile);
          sourceFilesCache.set(path, { sourceFile, version: sourceFile.version, fileWatcher });
        } else {
          sourceFilesCache.set(path, false);
        }
      }
      return sourceFile;
    }
    return hostSourceFile.sourceFile;
  }
  function nextSourceFileVersion(path) {
    const hostSourceFile = sourceFilesCache.get(path);
    if (hostSourceFile !== void 0) {
      if (isFileMissingOnHost(hostSourceFile)) {
        sourceFilesCache.set(path, { version: false });
      } else {
        hostSourceFile.version = false;
      }
    }
  }
  function getSourceVersion(path, readFileWithCache) {
    const hostSourceFile = sourceFilesCache.get(path);
    if (!hostSourceFile) return void 0;
    if (hostSourceFile.version) return hostSourceFile.version;
    const text = readFileWithCache(path);
    return text !== void 0 ? getSourceFileVersionAsHashFromText(compilerHost, text) : void 0;
  }
  function onReleaseOldSourceFile(oldSourceFile, _oldOptions, hasSourceFileByPath) {
    const hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.resolvedPath);
    if (hostSourceFileInfo !== void 0) {
      if (isFileMissingOnHost(hostSourceFileInfo)) {
        (missingFilePathsRequestedForRelease || (missingFilePathsRequestedForRelease = [])).push(oldSourceFile.path);
      } else if (hostSourceFileInfo.sourceFile === oldSourceFile) {
        if (hostSourceFileInfo.fileWatcher) {
          hostSourceFileInfo.fileWatcher.close();
        }
        sourceFilesCache.delete(oldSourceFile.resolvedPath);
        if (!hasSourceFileByPath) {
          resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
        }
      }
    }
  }
  function reportWatchDiagnostic(message) {
    if (host.onWatchStatusChange) {
      host.onWatchStatusChange(createCompilerDiagnostic(message), newLine, compilerOptions || optionsToExtendForConfigFile);
    }
  }
  function hasChangedAutomaticTypeDirectiveNames() {
    return resolutionCache.hasChangedAutomaticTypeDirectiveNames();
  }
  function clearInvalidateResolutionsOfFailedLookupLocations() {
    if (!timerToInvalidateFailedLookupResolutions) return false;
    host.clearTimeout(timerToInvalidateFailedLookupResolutions);
    timerToInvalidateFailedLookupResolutions = void 0;
    return true;
  }
  function scheduleInvalidateResolutionsOfFailedLookupLocations() {
    if (!host.setTimeout || !host.clearTimeout) {
      return resolutionCache.invalidateResolutionsOfFailedLookupLocations();
    }
    const pending = clearInvalidateResolutionsOfFailedLookupLocations();
    writeLog(`Scheduling invalidateFailedLookup${pending ? ", Cancelled earlier one" : ""}`);
    timerToInvalidateFailedLookupResolutions = host.setTimeout(invalidateResolutionsOfFailedLookup, 250, "timerToInvalidateFailedLookupResolutions");
  }
  function invalidateResolutionsOfFailedLookup() {
    timerToInvalidateFailedLookupResolutions = void 0;
    if (resolutionCache.invalidateResolutionsOfFailedLookupLocations()) {
      scheduleProgramUpdate();
    }
  }
  function scheduleProgramUpdate() {
    if (!host.setTimeout || !host.clearTimeout) {
      return;
    }
    if (timerToUpdateProgram) {
      host.clearTimeout(timerToUpdateProgram);
    }
    writeLog("Scheduling update");
    timerToUpdateProgram = host.setTimeout(updateProgramWithWatchStatus, 250, "timerToUpdateProgram");
  }
  function scheduleProgramReload() {
    Debug.assert(!!configFileName);
    updateLevel = 2 /* Full */;
    scheduleProgramUpdate();
  }
  function updateProgramWithWatchStatus() {
    timerToUpdateProgram = void 0;
    reportFileChangeDetectedOnCreateProgram = true;
    updateProgram();
  }
  function updateProgram() {
    var _a, _b, _c, _d;
    switch (updateLevel) {
      case 1 /* RootNamesAndUpdate */:
        (_a = perfLogger) == null ? void 0 : _a.logStartUpdateProgram("PartialConfigReload");
        reloadFileNamesFromConfigFile();
        break;
      case 2 /* Full */:
        (_b = perfLogger) == null ? void 0 : _b.logStartUpdateProgram("FullConfigReload");
        reloadConfigFile();
        break;
      default:
        (_c = perfLogger) == null ? void 0 : _c.logStartUpdateProgram("SynchronizeProgram");
        synchronizeProgram();
        break;
    }
    (_d = perfLogger) == null ? void 0 : _d.logStopUpdateProgram("Done");
    return getCurrentBuilderProgram();
  }
  function reloadFileNamesFromConfigFile() {
    writeLog("Reloading new file names and options");
    Debug.assert(compilerOptions);
    Debug.assert(configFileName);
    updateLevel = 0 /* Update */;
    rootFileNames = getFileNamesFromConfigSpecs(compilerOptions.configFile.configFileSpecs, getNormalizedAbsolutePath(getDirectoryPath(configFileName), currentDirectory), compilerOptions, parseConfigFileHost, extraFileExtensions);
    if (updateErrorForNoInputFiles(rootFileNames, getNormalizedAbsolutePath(configFileName, currentDirectory), compilerOptions.configFile.configFileSpecs, configFileParsingDiagnostics, canConfigFileJsonReportNoInputFiles)) {
      hasChangedConfigFileParsingErrors = true;
    }
    synchronizeProgram();
  }
  function reloadConfigFile() {
    Debug.assert(configFileName);
    writeLog(`Reloading config file: ${configFileName}`);
    updateLevel = 0 /* Update */;
    if (cachedDirectoryStructureHost) {
      cachedDirectoryStructureHost.clearCache();
    }
    parseConfigFile2();
    hasChangedCompilerOptions = true;
    synchronizeProgram();
    watchConfigFileWildCardDirectories();
    updateExtendedConfigFilesWatches(toPath3(configFileName), compilerOptions, watchOptions, WatchType.ExtendedConfigFile);
  }
  function parseConfigFile2() {
    Debug.assert(configFileName);
    setConfigFileParsingResult(
      getParsedCommandLineOfConfigFile(
        configFileName,
        optionsToExtendForConfigFile,
        parseConfigFileHost,
        extendedConfigCache || (extendedConfigCache = /* @__PURE__ */ new Map()),
        watchOptionsToExtend,
        extraFileExtensions
      )
    );
  }
  function setConfigFileParsingResult(configFileParseResult) {
    rootFileNames = configFileParseResult.fileNames;
    compilerOptions = configFileParseResult.options;
    watchOptions = configFileParseResult.watchOptions;
    projectReferences = configFileParseResult.projectReferences;
    wildcardDirectories = configFileParseResult.wildcardDirectories;
    configFileParsingDiagnostics = getConfigFileParsingDiagnostics(configFileParseResult).slice();
    canConfigFileJsonReportNoInputFiles = canJsonReportNoInputFiles(configFileParseResult.raw);
    hasChangedConfigFileParsingErrors = true;
  }
  function getParsedCommandLine(configFileName2) {
    const configPath = toPath3(configFileName2);
    let config = parsedConfigs == null ? void 0 : parsedConfigs.get(configPath);
    if (config) {
      if (!config.updateLevel) return config.parsedCommandLine;
      if (config.parsedCommandLine && config.updateLevel === 1 /* RootNamesAndUpdate */ && !host.getParsedCommandLine) {
        writeLog("Reloading new file names and options");
        Debug.assert(compilerOptions);
        const fileNames = getFileNamesFromConfigSpecs(
          config.parsedCommandLine.options.configFile.configFileSpecs,
          getNormalizedAbsolutePath(getDirectoryPath(configFileName2), currentDirectory),
          compilerOptions,
          parseConfigFileHost
        );
        config.parsedCommandLine = { ...config.parsedCommandLine, fileNames };
        config.updateLevel = void 0;
        return config.parsedCommandLine;
      }
    }
    writeLog(`Loading config file: ${configFileName2}`);
    const parsedCommandLine = host.getParsedCommandLine ? host.getParsedCommandLine(configFileName2) : getParsedCommandLineFromConfigFileHost(configFileName2);
    if (config) {
      config.parsedCommandLine = parsedCommandLine;
      config.updateLevel = void 0;
    } else {
      (parsedConfigs || (parsedConfigs = /* @__PURE__ */ new Map())).set(configPath, config = { parsedCommandLine });
    }
    watchReferencedProject(configFileName2, configPath, config);
    return parsedCommandLine;
  }
  function getParsedCommandLineFromConfigFileHost(configFileName2) {
    const onUnRecoverableConfigFileDiagnostic = parseConfigFileHost.onUnRecoverableConfigFileDiagnostic;
    parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = noop;
    const parsedCommandLine = getParsedCommandLineOfConfigFile(
      configFileName2,
      /*optionsToExtend*/
      void 0,
      parseConfigFileHost,
      extendedConfigCache || (extendedConfigCache = /* @__PURE__ */ new Map()),
      watchOptionsToExtend
    );
    parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = onUnRecoverableConfigFileDiagnostic;
    return parsedCommandLine;
  }
  function onReleaseParsedCommandLine(fileName) {
    var _a;
    const path = toPath3(fileName);
    const config = parsedConfigs == null ? void 0 : parsedConfigs.get(path);
    if (!config) return;
    parsedConfigs.delete(path);
    if (config.watchedDirectories) clearMap(config.watchedDirectories, closeFileWatcherOf);
    (_a = config.watcher) == null ? void 0 : _a.close();
    clearSharedExtendedConfigFileWatcher(path, sharedExtendedConfigFileWatchers);
  }
  function watchFilePath(path, file, callback, pollingInterval, options, watchType) {
    return watchFile2(file, (fileName, eventKind) => callback(fileName, eventKind, path), pollingInterval, options, watchType);
  }
  function onSourceFileChange(fileName, eventKind, path) {
    updateCachedSystemWithFile(fileName, path, eventKind);
    if (eventKind === 2 /* Deleted */ && sourceFilesCache.has(path)) {
      resolutionCache.invalidateResolutionOfFile(path);
    }
    nextSourceFileVersion(path);
    scheduleProgramUpdate();
  }
  function updateCachedSystemWithFile(fileName, path, eventKind) {
    if (cachedDirectoryStructureHost) {
      cachedDirectoryStructureHost.addOrDeleteFile(fileName, path, eventKind);
    }
  }
  function watchMissingFilePath(missingFilePath, missingFileName) {
    return (parsedConfigs == null ? void 0 : parsedConfigs.has(missingFilePath)) ? noopFileWatcher : watchFilePath(
      missingFilePath,
      missingFileName,
      onMissingFileChange,
      500 /* Medium */,
      watchOptions,
      WatchType.MissingFile
    );
  }
  function onMissingFileChange(fileName, eventKind, missingFilePath) {
    updateCachedSystemWithFile(fileName, missingFilePath, eventKind);
    if (eventKind === 0 /* Created */ && missingFilesMap.has(missingFilePath)) {
      missingFilesMap.get(missingFilePath).close();
      missingFilesMap.delete(missingFilePath);
      nextSourceFileVersion(missingFilePath);
      scheduleProgramUpdate();
    }
  }
  function watchConfigFileWildCardDirectories() {
    updateWatchingWildcardDirectories(
      watchedWildcardDirectories || (watchedWildcardDirectories = /* @__PURE__ */ new Map()),
      wildcardDirectories,
      watchWildcardDirectory
    );
  }
  function watchWildcardDirectory(directory, flags) {
    return watchDirectory(
      directory,
      (fileOrDirectory) => {
        Debug.assert(configFileName);
        Debug.assert(compilerOptions);
        const fileOrDirectoryPath = toPath3(fileOrDirectory);
        if (cachedDirectoryStructureHost) {
          cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
        }
        nextSourceFileVersion(fileOrDirectoryPath);
        if (isIgnoredFileFromWildCardWatching({
          watchedDirPath: toPath3(directory),
          fileOrDirectory,
          fileOrDirectoryPath,
          configFileName,
          extraFileExtensions,
          options: compilerOptions,
          program: getCurrentBuilderProgram() || rootFileNames,
          currentDirectory,
          useCaseSensitiveFileNames: useCaseSensitiveFileNames2,
          writeLog,
          toPath: toPath3
        })) return;
        if (updateLevel !== 2 /* Full */) {
          updateLevel = 1 /* RootNamesAndUpdate */;
          scheduleProgramUpdate();
        }
      },
      flags,
      watchOptions,
      WatchType.WildcardDirectory
    );
  }
  function updateExtendedConfigFilesWatches(forProjectPath, options, watchOptions2, watchType) {
    updateSharedExtendedConfigFileWatcher(
      forProjectPath,
      options,
      sharedExtendedConfigFileWatchers || (sharedExtendedConfigFileWatchers = /* @__PURE__ */ new Map()),
      (extendedConfigFileName, extendedConfigFilePath) => watchFile2(
        extendedConfigFileName,
        (_fileName, eventKind) => {
          var _a;
          updateCachedSystemWithFile(extendedConfigFileName, extendedConfigFilePath, eventKind);
          if (extendedConfigCache) cleanExtendedConfigCache(extendedConfigCache, extendedConfigFilePath, toPath3);
          const projects = (_a = sharedExtendedConfigFileWatchers.get(extendedConfigFilePath)) == null ? void 0 : _a.projects;
          if (!(projects == null ? void 0 : projects.size)) return;
          projects.forEach((projectPath) => {
            if (configFileName && toPath3(configFileName) === projectPath) {
              updateLevel = 2 /* Full */;
            } else {
              const config = parsedConfigs == null ? void 0 : parsedConfigs.get(projectPath);
              if (config) config.updateLevel = 2 /* Full */;
              resolutionCache.removeResolutionsFromProjectReferenceRedirects(projectPath);
            }
            scheduleProgramUpdate();
          });
        },
        2e3 /* High */,
        watchOptions2,
        watchType
      ),
      toPath3
    );
  }
  function watchReferencedProject(configFileName2, configPath, commandLine) {
    var _a, _b, _c, _d;
    commandLine.watcher || (commandLine.watcher = watchFile2(
      configFileName2,
      (_fileName, eventKind) => {
        updateCachedSystemWithFile(configFileName2, configPath, eventKind);
        const config = parsedConfigs == null ? void 0 : parsedConfigs.get(configPath);
        if (config) config.updateLevel = 2 /* Full */;
        resolutionCache.removeResolutionsFromProjectReferenceRedirects(configPath);
        scheduleProgramUpdate();
      },
      2e3 /* High */,
      ((_a = commandLine.parsedCommandLine) == null ? void 0 : _a.watchOptions) || watchOptions,
      WatchType.ConfigFileOfReferencedProject
    ));
    updateWatchingWildcardDirectories(
      commandLine.watchedDirectories || (commandLine.watchedDirectories = /* @__PURE__ */ new Map()),
      (_b = commandLine.parsedCommandLine) == null ? void 0 : _b.wildcardDirectories,
      (directory, flags) => {
        var _a2;
        return watchDirectory(
          directory,
          (fileOrDirectory) => {
            const fileOrDirectoryPath = toPath3(fileOrDirectory);
            if (cachedDirectoryStructureHost) {
              cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
            }
            nextSourceFileVersion(fileOrDirectoryPath);
            const config = parsedConfigs == null ? void 0 : parsedConfigs.get(configPath);
            if (!(config == null ? void 0 : config.parsedCommandLine)) return;
            if (isIgnoredFileFromWildCardWatching({
              watchedDirPath: toPath3(directory),
              fileOrDirectory,
              fileOrDirectoryPath,
              configFileName: configFileName2,
              options: config.parsedCommandLine.options,
              program: config.parsedCommandLine.fileNames,
              currentDirectory,
              useCaseSensitiveFileNames: useCaseSensitiveFileNames2,
              writeLog,
              toPath: toPath3
            })) return;
            if (config.updateLevel !== 2 /* Full */) {
              config.updateLevel = 1 /* RootNamesAndUpdate */;
              scheduleProgramUpdate();
            }
          },
          flags,
          ((_a2 = commandLine.parsedCommandLine) == null ? void 0 : _a2.watchOptions) || watchOptions,
          WatchType.WildcardDirectoryOfReferencedProject
        );
      }
    );
    updateExtendedConfigFilesWatches(
      configPath,
      (_c = commandLine.parsedCommandLine) == null ? void 0 : _c.options,
      ((_d = commandLine.parsedCommandLine) == null ? void 0 : _d.watchOptions) || watchOptions,
      WatchType.ExtendedConfigOfReferencedProject
    );
  }
}

// src/compiler/tsbuild.ts
function resolveConfigFileProjectName(project) {
  if (fileExtensionIs(project, ".json" /* Json */)) {
    return project;
  }
  return combinePaths(project, "tsconfig.json");
}

// src/compiler/tsbuildPublic.ts
var minimumDate = /* @__PURE__ */ new Date(-864e13);
var maximumDate = /* @__PURE__ */ new Date(864e13);
function getOrCreateValueFromConfigFileMap(configFileMap, resolved, createT) {
  const existingValue = configFileMap.get(resolved);
  let newValue;
  if (!existingValue) {
    newValue = createT();
    configFileMap.set(resolved, newValue);
  }
  return existingValue || newValue;
}
function getOrCreateValueMapFromConfigFileMap(configFileMap, resolved) {
  return getOrCreateValueFromConfigFileMap(configFileMap, resolved, () => /* @__PURE__ */ new Map());
}
function getCurrentTime(host) {
  return host.now ? host.now() : /* @__PURE__ */ new Date();
}
function isCircularBuildOrder(buildOrder) {
  return !!buildOrder && !!buildOrder.buildOrder;
}
function getBuildOrderFromAnyBuildOrder(anyBuildOrder) {
  return isCircularBuildOrder(anyBuildOrder) ? anyBuildOrder.buildOrder : anyBuildOrder;
}
function createBuilderStatusReporter(system, pretty) {
  return (diagnostic) => {
    let output = pretty ? `[${formatColorAndReset(getLocaleTimeString(system), "\x1B[90m" /* Grey */)}] ` : `${getLocaleTimeString(system)} - `;
    output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${system.newLine + system.newLine}`;
    system.write(output);
  };
}
function createSolutionBuilderHostBase(system, createProgram2, reportDiagnostic, reportSolutionBuilderStatus) {
  const host = createProgramHost(system, createProgram2);
  host.getModifiedTime = system.getModifiedTime ? (path) => system.getModifiedTime(path) : returnUndefined;
  host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime(path, date) : noop;
  host.deleteFile = system.deleteFile ? (path) => system.deleteFile(path) : noop;
  host.reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system);
  host.reportSolutionBuilderStatus = reportSolutionBuilderStatus || createBuilderStatusReporter(system);
  host.now = maybeBind(system, system.now);
  return host;
}
function createSolutionBuilderHost(system = sys, createProgram2, reportDiagnostic, reportSolutionBuilderStatus, reportErrorSummary2) {
  const host = createSolutionBuilderHostBase(system, createProgram2, reportDiagnostic, reportSolutionBuilderStatus);
  host.reportErrorSummary = reportErrorSummary2;
  return host;
}
function createSolutionBuilderWithWatchHost(system = sys, createProgram2, reportDiagnostic, reportSolutionBuilderStatus, reportWatchStatus2) {
  const host = createSolutionBuilderHostBase(system, createProgram2, reportDiagnostic, reportSolutionBuilderStatus);
  const watchHost = createWatchHost(system, reportWatchStatus2);
  copyProperties(host, watchHost);
  return host;
}
function getCompilerOptionsOfBuildOptions(buildOptions) {
  const result = {};
  commonOptionsWithBuild.forEach((option) => {
    if (hasProperty(buildOptions, option.name)) result[option.name] = buildOptions[option.name];
  });
  return result;
}
function createSolutionBuilder(host, rootNames, defaultOptions) {
  return createSolutionBuilderWorker(
    /*watch*/
    false,
    host,
    rootNames,
    defaultOptions
  );
}
function createSolutionBuilderWithWatch(host, rootNames, defaultOptions, baseWatchOptions) {
  return createSolutionBuilderWorker(
    /*watch*/
    true,
    host,
    rootNames,
    defaultOptions,
    baseWatchOptions
  );
}
function createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions) {
  const host = hostOrHostWithWatch;
  const hostWithWatch = hostOrHostWithWatch;
  const baseCompilerOptions = getCompilerOptionsOfBuildOptions(options);
  const compilerHost = createCompilerHostFromProgramHost(host, () => state.projectCompilerOptions);
  setGetSourceFileAsHashVersioned(compilerHost);
  compilerHost.getParsedCommandLine = (fileName) => parseConfigFile(state, fileName, toResolvedConfigFilePath(state, fileName));
  compilerHost.resolveModuleNameLiterals = maybeBind(host, host.resolveModuleNameLiterals);
  compilerHost.resolveTypeReferenceDirectiveReferences = maybeBind(host, host.resolveTypeReferenceDirectiveReferences);
  compilerHost.resolveLibrary = maybeBind(host, host.resolveLibrary);
  compilerHost.resolveModuleNames = maybeBind(host, host.resolveModuleNames);
  compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives);
  compilerHost.getModuleResolutionCache = maybeBind(host, host.getModuleResolutionCache);
  let moduleResolutionCache, typeReferenceDirectiveResolutionCache;
  if (!compilerHost.resolveModuleNameLiterals && !compilerHost.resolveModuleNames) {
    moduleResolutionCache = createModuleResolutionCache(compilerHost.getCurrentDirectory(), compilerHost.getCanonicalFileName);
    compilerHost.resolveModuleNameLiterals = (moduleNames, containingFile, redirectedReference, options2, containingSourceFile) => loadWithModeAwareCache(
      moduleNames,
      containingFile,
      redirectedReference,
      options2,
      containingSourceFile,
      host,
      moduleResolutionCache,
      createModuleResolutionLoader
    );
    compilerHost.getModuleResolutionCache = () => moduleResolutionCache;
  }
  if (!compilerHost.resolveTypeReferenceDirectiveReferences && !compilerHost.resolveTypeReferenceDirectives) {
    typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
      compilerHost.getCurrentDirectory(),
      compilerHost.getCanonicalFileName,
      /*options*/
      void 0,
      moduleResolutionCache == null ? void 0 : moduleResolutionCache.getPackageJsonInfoCache(),
      moduleResolutionCache == null ? void 0 : moduleResolutionCache.optionsToRedirectsKey
    );
    compilerHost.resolveTypeReferenceDirectiveReferences = (typeDirectiveNames, containingFile, redirectedReference, options2, containingSourceFile) => loadWithModeAwareCache(
      typeDirectiveNames,
      containingFile,
      redirectedReference,
      options2,
      containingSourceFile,
      host,
      typeReferenceDirectiveResolutionCache,
      createTypeReferenceResolutionLoader
    );
  }
  let libraryResolutionCache;
  if (!compilerHost.resolveLibrary) {
    libraryResolutionCache = createModuleResolutionCache(
      compilerHost.getCurrentDirectory(),
      compilerHost.getCanonicalFileName,
      /*options*/
      void 0,
      moduleResolutionCache == null ? void 0 : moduleResolutionCache.getPackageJsonInfoCache()
    );
    compilerHost.resolveLibrary = (libraryName, resolveFrom, options2) => resolveLibrary(
      libraryName,
      resolveFrom,
      options2,
      host,
      libraryResolutionCache
    );
  }
  compilerHost.getBuildInfo = (fileName, configFilePath) => getBuildInfo3(
    state,
    fileName,
    toResolvedConfigFilePath(state, configFilePath),
    /*modifiedTime*/
    void 0
  );
  const { watchFile: watchFile2, watchDirectory, writeLog } = createWatchFactory(hostWithWatch, options);
  const state = {
    host,
    hostWithWatch,
    parseConfigFileHost: parseConfigHostFromCompilerHostLike(host),
    write: maybeBind(host, host.trace),
    // State of solution
    options,
    baseCompilerOptions,
    rootNames,
    baseWatchOptions,
    resolvedConfigFilePaths: /* @__PURE__ */ new Map(),
    configFileCache: /* @__PURE__ */ new Map(),
    projectStatus: /* @__PURE__ */ new Map(),
    extendedConfigCache: /* @__PURE__ */ new Map(),
    buildInfoCache: /* @__PURE__ */ new Map(),
    outputTimeStamps: /* @__PURE__ */ new Map(),
    builderPrograms: /* @__PURE__ */ new Map(),
    diagnostics: /* @__PURE__ */ new Map(),
    projectPendingBuild: /* @__PURE__ */ new Map(),
    projectErrorsReported: /* @__PURE__ */ new Map(),
    compilerHost,
    moduleResolutionCache,
    typeReferenceDirectiveResolutionCache,
    libraryResolutionCache,
    // Mutable state
    buildOrder: void 0,
    readFileWithCache: (f) => host.readFile(f),
    projectCompilerOptions: baseCompilerOptions,
    cache: void 0,
    allProjectBuildPending: true,
    needsSummary: true,
    watchAllProjectsPending: watch,
    // Watch state
    watch,
    allWatchedWildcardDirectories: /* @__PURE__ */ new Map(),
    allWatchedInputFiles: /* @__PURE__ */ new Map(),
    allWatchedConfigFiles: /* @__PURE__ */ new Map(),
    allWatchedExtendedConfigFiles: /* @__PURE__ */ new Map(),
    allWatchedPackageJsonFiles: /* @__PURE__ */ new Map(),
    filesWatched: /* @__PURE__ */ new Map(),
    lastCachedPackageJsonLookups: /* @__PURE__ */ new Map(),
    timerToBuildInvalidatedProject: void 0,
    reportFileChangeDetected: false,
    watchFile: watchFile2,
    watchDirectory,
    writeLog
  };
  return state;
}
function toPath2(state, fileName) {
  return toPath(fileName, state.compilerHost.getCurrentDirectory(), state.compilerHost.getCanonicalFileName);
}
function toResolvedConfigFilePath(state, fileName) {
  const { resolvedConfigFilePaths } = state;
  const path = resolvedConfigFilePaths.get(fileName);
  if (path !== void 0) return path;
  const resolvedPath = toPath2(state, fileName);
  resolvedConfigFilePaths.set(fileName, resolvedPath);
  return resolvedPath;
}
function isParsedCommandLine(entry) {
  return !!entry.options;
}
function getCachedParsedConfigFile(state, configFilePath) {
  const value = state.configFileCache.get(configFilePath);
  return value && isParsedCommandLine(value) ? value : void 0;
}
function parseConfigFile(state, configFileName, configFilePath) {
  const { configFileCache } = state;
  const value = configFileCache.get(configFilePath);
  if (value) {
    return isParsedCommandLine(value) ? value : void 0;
  }
  mark("SolutionBuilder::beforeConfigFileParsing");
  let diagnostic;
  const { parseConfigFileHost, baseCompilerOptions, baseWatchOptions, extendedConfigCache, host } = state;
  let parsed;
  if (host.getParsedCommandLine) {
    parsed = host.getParsedCommandLine(configFileName);
    if (!parsed) diagnostic = createCompilerDiagnostic(Diagnostics.File_0_not_found, configFileName);
  } else {
    parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = (d) => diagnostic = d;
    parsed = getParsedCommandLineOfConfigFile(configFileName, baseCompilerOptions, parseConfigFileHost, extendedConfigCache, baseWatchOptions);
    parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = noop;
  }
  configFileCache.set(configFilePath, parsed || diagnostic);
  mark("SolutionBuilder::afterConfigFileParsing");
  measure("SolutionBuilder::Config file parsing", "SolutionBuilder::beforeConfigFileParsing", "SolutionBuilder::afterConfigFileParsing");
  return parsed;
}
function resolveProjectName(state, name) {
  return resolveConfigFileProjectName(resolvePath(state.compilerHost.getCurrentDirectory(), name));
}
function createBuildOrder(state, roots) {
  const temporaryMarks = /* @__PURE__ */ new Map();
  const permanentMarks = /* @__PURE__ */ new Map();
  const circularityReportStack = [];
  let buildOrder;
  let circularDiagnostics;
  for (const root of roots) {
    visit(root);
  }
  return circularDiagnostics ? { buildOrder: buildOrder || emptyArray, circularDiagnostics } : buildOrder || emptyArray;
  function visit(configFileName, inCircularContext) {
    const projPath = toResolvedConfigFilePath(state, configFileName);
    if (permanentMarks.has(projPath)) return;
    if (temporaryMarks.has(projPath)) {
      if (!inCircularContext) {
        (circularDiagnostics || (circularDiagnostics = [])).push(
          createCompilerDiagnostic(
            Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0,
            circularityReportStack.join("\r\n")
          )
        );
      }
      return;
    }
    temporaryMarks.set(projPath, true);
    circularityReportStack.push(configFileName);
    const parsed = parseConfigFile(state, configFileName, projPath);
    if (parsed && parsed.projectReferences) {
      for (const ref of parsed.projectReferences) {
        const resolvedRefPath = resolveProjectName(state, ref.path);
        visit(resolvedRefPath, inCircularContext || ref.circular);
      }
    }
    circularityReportStack.pop();
    permanentMarks.set(projPath, true);
    (buildOrder || (buildOrder = [])).push(configFileName);
  }
}
function getBuildOrder(state) {
  return state.buildOrder || createStateBuildOrder(state);
}
function createStateBuildOrder(state) {
  const buildOrder = createBuildOrder(state, state.rootNames.map((f) => resolveProjectName(state, f)));
  state.resolvedConfigFilePaths.clear();
  const currentProjects = new Set(
    getBuildOrderFromAnyBuildOrder(buildOrder).map(
      (resolved) => toResolvedConfigFilePath(state, resolved)
    )
  );
  const noopOnDelete = { onDeleteValue: noop };
  mutateMapSkippingNewValues(state.configFileCache, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.projectStatus, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.builderPrograms, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.diagnostics, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.projectPendingBuild, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.projectErrorsReported, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.buildInfoCache, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.outputTimeStamps, currentProjects, noopOnDelete);
  mutateMapSkippingNewValues(state.lastCachedPackageJsonLookups, currentProjects, noopOnDelete);
  if (state.watch) {
    mutateMapSkippingNewValues(
      state.allWatchedConfigFiles,
      currentProjects,
      { onDeleteValue: closeFileWatcher }
    );
    state.allWatchedExtendedConfigFiles.forEach((watcher) => {
      watcher.projects.forEach((project) => {
        if (!currentProjects.has(project)) {
          watcher.projects.delete(project);
        }
      });
      watcher.close();
    });
    mutateMapSkippingNewValues(
      state.allWatchedWildcardDirectories,
      currentProjects,
      { onDeleteValue: (existingMap) => existingMap.forEach(closeFileWatcherOf) }
    );
    mutateMapSkippingNewValues(
      state.allWatchedInputFiles,
      currentProjects,
      { onDeleteValue: (existingMap) => existingMap.forEach(closeFileWatcher) }
    );
    mutateMapSkippingNewValues(
      state.allWatchedPackageJsonFiles,
      currentProjects,
      { onDeleteValue: (existingMap) => existingMap.forEach(closeFileWatcher) }
    );
  }
  return state.buildOrder = buildOrder;
}
function getBuildOrderFor(state, project, onlyReferences) {
  const resolvedProject = project && resolveProjectName(state, project);
  const buildOrderFromState = getBuildOrder(state);
  if (isCircularBuildOrder(buildOrderFromState)) return buildOrderFromState;
  if (resolvedProject) {
    const projectPath = toResolvedConfigFilePath(state, resolvedProject);
    const projectIndex = findIndex(
      buildOrderFromState,
      (configFileName) => toResolvedConfigFilePath(state, configFileName) === projectPath
    );
    if (projectIndex === -1) return void 0;
  }
  const buildOrder = resolvedProject ? createBuildOrder(state, [resolvedProject]) : buildOrderFromState;
  Debug.assert(!isCircularBuildOrder(buildOrder));
  Debug.assert(!onlyReferences || resolvedProject !== void 0);
  Debug.assert(!onlyReferences || buildOrder[buildOrder.length - 1] === resolvedProject);
  return onlyReferences ? buildOrder.slice(0, buildOrder.length - 1) : buildOrder;
}
function enableCache(state) {
  if (state.cache) {
    disableCache(state);
  }
  const { compilerHost, host } = state;
  const originalReadFileWithCache = state.readFileWithCache;
  const originalGetSourceFile = compilerHost.getSourceFile;
  const {
    originalReadFile,
    originalFileExists,
    originalDirectoryExists,
    originalCreateDirectory,
    originalWriteFile,
    getSourceFileWithCache,
    readFileWithCache
  } = changeCompilerHostLikeToUseCache(
    host,
    (fileName) => toPath2(state, fileName),
    (...args) => originalGetSourceFile.call(compilerHost, ...args)
  );
  state.readFileWithCache = readFileWithCache;
  compilerHost.getSourceFile = getSourceFileWithCache;
  state.cache = {
    originalReadFile,
    originalFileExists,
    originalDirectoryExists,
    originalCreateDirectory,
    originalWriteFile,
    originalReadFileWithCache,
    originalGetSourceFile
  };
}
function disableCache(state) {
  if (!state.cache) return;
  const { cache, host, compilerHost, extendedConfigCache, moduleResolutionCache, typeReferenceDirectiveResolutionCache, libraryResolutionCache } = state;
  host.readFile = cache.originalReadFile;
  host.fileExists = cache.originalFileExists;
  host.directoryExists = cache.originalDirectoryExists;
  host.createDirectory = cache.originalCreateDirectory;
  host.writeFile = cache.originalWriteFile;
  compilerHost.getSourceFile = cache.originalGetSourceFile;
  state.readFileWithCache = cache.originalReadFileWithCache;
  extendedConfigCache.clear();
  moduleResolutionCache == null ? void 0 : moduleResolutionCache.clear();
  typeReferenceDirectiveResolutionCache == null ? void 0 : typeReferenceDirectiveResolutionCache.clear();
  libraryResolutionCache == null ? void 0 : libraryResolutionCache.clear();
  state.cache = void 0;
}
function clearProjectStatus(state, resolved) {
  state.projectStatus.delete(resolved);
  state.diagnostics.delete(resolved);
}
function addProjToQueue({ projectPendingBuild }, proj, updateLevel) {
  const value = projectPendingBuild.get(proj);
  if (value === void 0) {
    projectPendingBuild.set(proj, updateLevel);
  } else if (value < updateLevel) {
    projectPendingBuild.set(proj, updateLevel);
  }
}
function setupInitialBuild(state, cancellationToken) {
  if (!state.allProjectBuildPending) return;
  state.allProjectBuildPending = false;
  if (state.options.watch) reportWatchStatus(state, Diagnostics.Starting_compilation_in_watch_mode);
  enableCache(state);
  const buildOrder = getBuildOrderFromAnyBuildOrder(getBuildOrder(state));
  buildOrder.forEach(
    (configFileName) => state.projectPendingBuild.set(
      toResolvedConfigFilePath(state, configFileName),
      0 /* Update */
    )
  );
  if (cancellationToken) {
    cancellationToken.throwIfCancellationRequested();
  }
}
function doneInvalidatedProject(state, projectPath) {
  state.projectPendingBuild.delete(projectPath);
  return state.diagnostics.has(projectPath) ? 1 /* DiagnosticsPresent_OutputsSkipped */ : 0 /* Success */;
}
function createUpdateOutputFileStampsProject(state, project, projectPath, config, buildOrder) {
  let updateOutputFileStampsPending = true;
  return {
    kind: 1 /* UpdateOutputFileStamps */,
    project,
    projectPath,
    buildOrder,
    getCompilerOptions: () => config.options,
    getCurrentDirectory: () => state.compilerHost.getCurrentDirectory(),
    updateOutputFileStatmps: () => {
      updateOutputTimestamps(state, config, projectPath);
      updateOutputFileStampsPending = false;
    },
    done: () => {
      if (updateOutputFileStampsPending) {
        updateOutputTimestamps(state, config, projectPath);
      }
      mark("SolutionBuilder::Timestamps only updates");
      return doneInvalidatedProject(state, projectPath);
    }
  };
}
function createBuildOrUpdateInvalidedProject(state, project, projectPath, projectIndex, config, buildOrder) {
  let step = 0 /* CreateProgram */;
  let program;
  let buildResult;
  return {
    kind: 0 /* Build */,
    project,
    projectPath,
    buildOrder,
    getCompilerOptions: () => config.options,
    getCurrentDirectory: () => state.compilerHost.getCurrentDirectory(),
    getBuilderProgram: () => withProgramOrUndefined(identity),
    getProgram: () => withProgramOrUndefined(
      (program2) => program2.getProgramOrUndefined()
    ),
    getSourceFile: (fileName) => withProgramOrUndefined(
      (program2) => program2.getSourceFile(fileName)
    ),
    getSourceFiles: () => withProgramOrEmptyArray(
      (program2) => program2.getSourceFiles()
    ),
    getOptionsDiagnostics: (cancellationToken) => withProgramOrEmptyArray(
      (program2) => program2.getOptionsDiagnostics(cancellationToken)
    ),
    getGlobalDiagnostics: (cancellationToken) => withProgramOrEmptyArray(
      (program2) => program2.getGlobalDiagnostics(cancellationToken)
    ),
    getConfigFileParsingDiagnostics: () => withProgramOrEmptyArray(
      (program2) => program2.getConfigFileParsingDiagnostics()
    ),
    getSyntacticDiagnostics: (sourceFile, cancellationToken) => withProgramOrEmptyArray(
      (program2) => program2.getSyntacticDiagnostics(sourceFile, cancellationToken)
    ),
    getAllDependencies: (sourceFile) => withProgramOrEmptyArray(
      (program2) => program2.getAllDependencies(sourceFile)
    ),
    getSemanticDiagnostics: (sourceFile, cancellationToken) => withProgramOrEmptyArray(
      (program2) => program2.getSemanticDiagnostics(sourceFile, cancellationToken)
    ),
    getSemanticDiagnosticsOfNextAffectedFile: (cancellationToken, ignoreSourceFile) => withProgramOrUndefined(
      (program2) => program2.getSemanticDiagnosticsOfNextAffectedFile && program2.getSemanticDiagnosticsOfNextAffectedFile(cancellationToken, ignoreSourceFile)
    ),
    emit: (targetSourceFile, writeFile2, cancellationToken, emitOnlyDtsFiles, customTransformers) => {
      if (targetSourceFile || emitOnlyDtsFiles) {
        return withProgramOrUndefined(
          (program2) => {
            var _a, _b;
            return program2.emit(targetSourceFile, writeFile2, cancellationToken, emitOnlyDtsFiles, customTransformers || ((_b = (_a = state.host).getCustomTransformers) == null ? void 0 : _b.call(_a, project)));
          }
        );
      }
      executeSteps(2 /* SemanticDiagnostics */, cancellationToken);
      if (step === 4 /* EmitBuildInfo */) {
        return emitBuildInfo(writeFile2, cancellationToken);
      }
      if (step !== 3 /* Emit */) return void 0;
      return emit(writeFile2, cancellationToken, customTransformers);
    },
    done
  };
  function done(cancellationToken, writeFile2, customTransformers) {
    executeSteps(6 /* Done */, cancellationToken, writeFile2, customTransformers);
    mark("SolutionBuilder::Projects built");
    return doneInvalidatedProject(state, projectPath);
  }
  function withProgramOrUndefined(action) {
    executeSteps(0 /* CreateProgram */);
    return program && action(program);
  }
  function withProgramOrEmptyArray(action) {
    return withProgramOrUndefined(action) || emptyArray;
  }
  function createProgram2() {
    var _a, _b, _c;
    Debug.assert(program === void 0);
    if (state.options.dry) {
      reportStatus(state, Diagnostics.A_non_dry_build_would_build_project_0, project);
      buildResult = 1 /* Success */;
      step = 5 /* QueueReferencingProjects */;
      return;
    }
    if (state.options.verbose) reportStatus(state, Diagnostics.Building_project_0, project);
    if (config.fileNames.length === 0) {
      reportAndStoreErrors(state, projectPath, getConfigFileParsingDiagnostics(config));
      buildResult = 0 /* None */;
      step = 5 /* QueueReferencingProjects */;
      return;
    }
    const { host, compilerHost } = state;
    state.projectCompilerOptions = config.options;
    (_a = state.moduleResolutionCache) == null ? void 0 : _a.update(config.options);
    (_b = state.typeReferenceDirectiveResolutionCache) == null ? void 0 : _b.update(config.options);
    program = host.createProgram(
      config.fileNames,
      config.options,
      compilerHost,
      getOldProgram(state, projectPath, config),
      getConfigFileParsingDiagnostics(config),
      config.projectReferences
    );
    if (state.watch) {
      const internalMap = (_c = state.moduleResolutionCache) == null ? void 0 : _c.getPackageJsonInfoCache().getInternalMap();
      state.lastCachedPackageJsonLookups.set(
        projectPath,
        internalMap && new Set(arrayFrom(
          internalMap.values(),
          (data) => state.host.realpath && (isPackageJsonInfo(data) || data.directoryExists) ? state.host.realpath(combinePaths(data.packageDirectory, "package.json")) : combinePaths(data.packageDirectory, "package.json")
        ))
      );
      state.builderPrograms.set(projectPath, program);
    }
    step++;
  }
  function handleDiagnostics(diagnostics, errorFlags, errorType) {
    if (diagnostics.length) {
      ({ buildResult, step } = buildErrors(
        state,
        projectPath,
        program,
        config,
        diagnostics,
        errorFlags,
        errorType
      ));
    } else {
      step++;
    }
  }
  function getSyntaxDiagnostics(cancellationToken) {
    Debug.assertIsDefined(program);
    handleDiagnostics(
      [
        ...program.getConfigFileParsingDiagnostics(),
        ...program.getOptionsDiagnostics(cancellationToken),
        ...program.getGlobalDiagnostics(cancellationToken),
        ...program.getSyntacticDiagnostics(
          /*sourceFile*/
          void 0,
          cancellationToken
        )
      ],
      8 /* SyntaxErrors */,
      "Syntactic"
    );
  }
  function getSemanticDiagnostics(cancellationToken) {
    handleDiagnostics(
      Debug.checkDefined(program).getSemanticDiagnostics(
        /*sourceFile*/
        void 0,
        cancellationToken
      ),
      16 /* TypeErrors */,
      "Semantic"
    );
  }
  function emit(writeFileCallback, cancellationToken, customTransformers) {
    var _a, _b, _c;
    Debug.assertIsDefined(program);
    Debug.assert(step === 3 /* Emit */);
    const saved = program.saveEmitState();
    let declDiagnostics;
    const reportDeclarationDiagnostics = (d) => (declDiagnostics || (declDiagnostics = [])).push(d);
    const outputFiles = [];
    const { emitResult } = emitFilesAndReportErrors(
      program,
      reportDeclarationDiagnostics,
      /*write*/
      void 0,
      /*reportSummary*/
      void 0,
      (name, text, writeByteOrderMark, _onError, _sourceFiles, data) => outputFiles.push({ name, text, writeByteOrderMark, data }),
      cancellationToken,
      /*emitOnlyDtsFiles*/
      false,
      customTransformers || ((_b = (_a = state.host).getCustomTransformers) == null ? void 0 : _b.call(_a, project))
    );
    if (declDiagnostics) {
      program.restoreEmitState(saved);
      ({ buildResult, step } = buildErrors(
        state,
        projectPath,
        program,
        config,
        declDiagnostics,
        32 /* DeclarationEmitErrors */,
        "Declaration file"
      ));
      return {
        emitSkipped: true,
        diagnostics: emitResult.diagnostics
      };
    }
    const { host, compilerHost } = state;
    const resultFlags = ((_c = program.hasChangedEmitSignature) == null ? void 0 : _c.call(program)) ? 0 /* None */ : 2 /* DeclarationOutputUnchanged */;
    const emitterDiagnostics = createDiagnosticCollection();
    const emittedOutputs = /* @__PURE__ */ new Map();
    const options = program.getCompilerOptions();
    const isIncremental = isIncrementalCompilation(options);
    let outputTimeStampMap;
    let now;
    outputFiles.forEach(({ name, text, writeByteOrderMark, data }) => {
      const path = toPath2(state, name);
      emittedOutputs.set(toPath2(state, name), name);
      if (data == null ? void 0 : data.buildInfo) setBuildInfo(state, data.buildInfo, projectPath, options, resultFlags);
      const modifiedTime = (data == null ? void 0 : data.differsOnlyInMap) ? getModifiedTime(state.host, name) : void 0;
      writeFile(writeFileCallback ? { writeFile: writeFileCallback } : compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
      if (data == null ? void 0 : data.differsOnlyInMap) state.host.setModifiedTime(name, modifiedTime);
      else if (!isIncremental && state.watch) {
        (outputTimeStampMap || (outputTimeStampMap = getOutputTimeStampMap(state, projectPath))).set(path, now || (now = getCurrentTime(state.host)));
      }
    });
    finishEmit(
      emitterDiagnostics,
      emittedOutputs,
      outputFiles.length ? outputFiles[0].name : getFirstProjectOutput(config, !host.useCaseSensitiveFileNames()),
      resultFlags
    );
    return emitResult;
  }
  function emitBuildInfo(writeFileCallback, cancellationToken) {
    Debug.assertIsDefined(program);
    Debug.assert(step === 4 /* EmitBuildInfo */);
    const emitResult = program.emitBuildInfo((name, text, writeByteOrderMark, onError, sourceFiles, data) => {
      if (data == null ? void 0 : data.buildInfo) setBuildInfo(state, data.buildInfo, projectPath, program.getCompilerOptions(), 2 /* DeclarationOutputUnchanged */);
      if (writeFileCallback) writeFileCallback(name, text, writeByteOrderMark, onError, sourceFiles, data);
      else state.compilerHost.writeFile(name, text, writeByteOrderMark, onError, sourceFiles, data);
    }, cancellationToken);
    if (emitResult.diagnostics.length) {
      reportErrors(state, emitResult.diagnostics);
      state.diagnostics.set(projectPath, [...state.diagnostics.get(projectPath), ...emitResult.diagnostics]);
      buildResult = 64 /* EmitErrors */ & buildResult;
    }
    if (emitResult.emittedFiles && state.write) {
      emitResult.emittedFiles.forEach((name) => listEmittedFile(state, config, name));
    }
    afterProgramDone(state, program);
    step = 5 /* QueueReferencingProjects */;
    return emitResult;
  }
  function finishEmit(emitterDiagnostics, emittedOutputs, oldestOutputFileName, resultFlags) {
    const emitDiagnostics = emitterDiagnostics.getDiagnostics();
    if (emitDiagnostics.length) {
      ({ buildResult, step } = buildErrors(
        state,
        projectPath,
        program,
        config,
        emitDiagnostics,
        64 /* EmitErrors */,
        "Emit"
      ));
      return emitDiagnostics;
    }
    if (state.write) {
      emittedOutputs.forEach((name) => listEmittedFile(state, config, name));
    }
    updateOutputTimestampsWorker(state, config, projectPath, Diagnostics.Updating_unchanged_output_timestamps_of_project_0, emittedOutputs);
    state.diagnostics.delete(projectPath);
    state.projectStatus.set(projectPath, {
      type: 1 /* UpToDate */,
      oldestOutputFileName
    });
    afterProgramDone(state, program);
    step = 5 /* QueueReferencingProjects */;
    buildResult = resultFlags;
    return emitDiagnostics;
  }
  function executeSteps(till, cancellationToken, writeFile2, customTransformers) {
    while (step <= till && step < 6 /* Done */) {
      const currentStep = step;
      switch (step) {
        case 0 /* CreateProgram */:
          createProgram2();
          break;
        case 1 /* SyntaxDiagnostics */:
          getSyntaxDiagnostics(cancellationToken);
          break;
        case 2 /* SemanticDiagnostics */:
          getSemanticDiagnostics(cancellationToken);
          break;
        case 3 /* Emit */:
          emit(writeFile2, cancellationToken, customTransformers);
          break;
        case 4 /* EmitBuildInfo */:
          emitBuildInfo(writeFile2, cancellationToken);
          break;
        case 5 /* QueueReferencingProjects */:
          queueReferencingProjects(state, project, projectPath, projectIndex, config, buildOrder, Debug.checkDefined(buildResult));
          step++;
          break;
        case 6 /* Done */:
        default:
          assertType(step);
      }
      Debug.assert(step > currentStep);
    }
  }
}
function getNextInvalidatedProjectCreateInfo(state, buildOrder, reportQueue) {
  if (!state.projectPendingBuild.size) return void 0;
  if (isCircularBuildOrder(buildOrder)) return void 0;
  const { options, projectPendingBuild } = state;
  for (let projectIndex = 0; projectIndex < buildOrder.length; projectIndex++) {
    const project = buildOrder[projectIndex];
    const projectPath = toResolvedConfigFilePath(state, project);
    const updateLevel = state.projectPendingBuild.get(projectPath);
    if (updateLevel === void 0) continue;
    if (reportQueue) {
      reportQueue = false;
      reportBuildQueue(state, buildOrder);
    }
    const config = parseConfigFile(state, project, projectPath);
    if (!config) {
      reportParseConfigFileDiagnostic(state, projectPath);
      projectPendingBuild.delete(projectPath);
      continue;
    }
    if (updateLevel === 2 /* Full */) {
      watchConfigFile(state, project, projectPath, config);
      watchExtendedConfigFiles(state, projectPath, config);
      watchWildCardDirectories(state, project, projectPath, config);
      watchInputFiles(state, project, projectPath, config);
      watchPackageJsonFiles(state, project, projectPath, config);
    } else if (updateLevel === 1 /* RootNamesAndUpdate */) {
      config.fileNames = getFileNamesFromConfigSpecs(config.options.configFile.configFileSpecs, getDirectoryPath(project), config.options, state.parseConfigFileHost);
      updateErrorForNoInputFiles(config.fileNames, project, config.options.configFile.configFileSpecs, config.errors, canJsonReportNoInputFiles(config.raw));
      watchInputFiles(state, project, projectPath, config);
      watchPackageJsonFiles(state, project, projectPath, config);
    }
    const status = getUpToDateStatus(state, config, projectPath);
    if (!options.force) {
      if (status.type === 1 /* UpToDate */) {
        verboseReportProjectStatus(state, project, status);
        reportAndStoreErrors(state, projectPath, getConfigFileParsingDiagnostics(config));
        projectPendingBuild.delete(projectPath);
        if (options.dry) {
          reportStatus(state, Diagnostics.Project_0_is_up_to_date, project);
        }
        continue;
      }
      if (status.type === 2 /* UpToDateWithUpstreamTypes */ || status.type === 14 /* UpToDateWithInputFileText */) {
        reportAndStoreErrors(state, projectPath, getConfigFileParsingDiagnostics(config));
        return {
          kind: 1 /* UpdateOutputFileStamps */,
          status,
          project,
          projectPath,
          projectIndex,
          config
        };
      }
    }
    if (status.type === 11 /* UpstreamBlocked */) {
      verboseReportProjectStatus(state, project, status);
      reportAndStoreErrors(state, projectPath, getConfigFileParsingDiagnostics(config));
      projectPendingBuild.delete(projectPath);
      if (options.verbose) {
        reportStatus(
          state,
          status.upstreamProjectBlocked ? Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_was_not_built : Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors,
          project,
          status.upstreamProjectName
        );
      }
      continue;
    }
    if (status.type === 15 /* ContainerOnly */) {
      verboseReportProjectStatus(state, project, status);
      reportAndStoreErrors(state, projectPath, getConfigFileParsingDiagnostics(config));
      projectPendingBuild.delete(projectPath);
      continue;
    }
    return {
      kind: 0 /* Build */,
      status,
      project,
      projectPath,
      projectIndex,
      config
    };
  }
  return void 0;
}
function createInvalidatedProjectWithInfo(state, info, buildOrder) {
  verboseReportProjectStatus(state, info.project, info.status);
  return info.kind !== 1 /* UpdateOutputFileStamps */ ? createBuildOrUpdateInvalidedProject(
    state,
    info.project,
    info.projectPath,
    info.projectIndex,
    info.config,
    buildOrder
  ) : createUpdateOutputFileStampsProject(
    state,
    info.project,
    info.projectPath,
    info.config,
    buildOrder
  );
}
function getNextInvalidatedProject(state, buildOrder, reportQueue) {
  const info = getNextInvalidatedProjectCreateInfo(state, buildOrder, reportQueue);
  if (!info) return info;
  return createInvalidatedProjectWithInfo(state, info, buildOrder);
}
function listEmittedFile({ write }, proj, file) {
  if (write && proj.options.listEmittedFiles) {
    write(`TSFILE: ${file}`);
  }
}
function getOldProgram({ options, builderPrograms, compilerHost }, proj, parsed) {
  if (options.force) return void 0;
  const value = builderPrograms.get(proj);
  if (value) return value;
  return readBuilderProgram(parsed.options, compilerHost);
}
function afterProgramDone(state, program) {
  if (program) {
    if (state.write) listFiles(program, state.write);
    if (state.host.afterProgramEmitAndDiagnostics) {
      state.host.afterProgramEmitAndDiagnostics(program);
    }
    program.releaseProgram();
  }
  state.projectCompilerOptions = state.baseCompilerOptions;
}
function buildErrors(state, resolvedPath, program, config, diagnostics, buildResult, errorType) {
  const canEmitBuildInfo = program && !program.getCompilerOptions().outFile;
  reportAndStoreErrors(state, resolvedPath, diagnostics);
  state.projectStatus.set(resolvedPath, { type: 0 /* Unbuildable */, reason: `${errorType} errors` });
  if (canEmitBuildInfo) return { buildResult, step: 4 /* EmitBuildInfo */ };
  afterProgramDone(state, program);
  return { buildResult, step: 5 /* QueueReferencingProjects */ };
}
function isFileWatcherWithModifiedTime(value) {
  return !!value.watcher;
}
function getModifiedTime2(state, fileName) {
  const path = toPath2(state, fileName);
  const existing = state.filesWatched.get(path);
  if (state.watch && !!existing) {
    if (!isFileWatcherWithModifiedTime(existing)) return existing;
    if (existing.modifiedTime) return existing.modifiedTime;
  }
  const result = getModifiedTime(state.host, fileName);
  if (state.watch) {
    if (existing) existing.modifiedTime = result;
    else state.filesWatched.set(path, result);
  }
  return result;
}
function watchFile(state, file, callback, pollingInterval, options, watchType, project) {
  const path = toPath2(state, file);
  const existing = state.filesWatched.get(path);
  if (existing && isFileWatcherWithModifiedTime(existing)) {
    existing.callbacks.push(callback);
  } else {
    const watcher = state.watchFile(
      file,
      (fileName, eventKind, modifiedTime) => {
        const existing2 = Debug.checkDefined(state.filesWatched.get(path));
        Debug.assert(isFileWatcherWithModifiedTime(existing2));
        existing2.modifiedTime = modifiedTime;
        existing2.callbacks.forEach((cb) => cb(fileName, eventKind, modifiedTime));
      },
      pollingInterval,
      options,
      watchType,
      project
    );
    state.filesWatched.set(path, { callbacks: [callback], watcher, modifiedTime: existing });
  }
  return {
    close: () => {
      const existing2 = Debug.checkDefined(state.filesWatched.get(path));
      Debug.assert(isFileWatcherWithModifiedTime(existing2));
      if (existing2.callbacks.length === 1) {
        state.filesWatched.delete(path);
        closeFileWatcherOf(existing2);
      } else {
        unorderedRemoveItem(existing2.callbacks, callback);
      }
    }
  };
}
function getOutputTimeStampMap(state, resolvedConfigFilePath) {
  if (!state.watch) return void 0;
  let result = state.outputTimeStamps.get(resolvedConfigFilePath);
  if (!result) state.outputTimeStamps.set(resolvedConfigFilePath, result = /* @__PURE__ */ new Map());
  return result;
}
function setBuildInfo(state, buildInfo, resolvedConfigPath, options, resultFlags) {
  const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
  const existing = getBuildInfoCacheEntry(state, buildInfoPath, resolvedConfigPath);
  const modifiedTime = getCurrentTime(state.host);
  if (existing) {
    existing.buildInfo = buildInfo;
    existing.modifiedTime = modifiedTime;
    if (!(resultFlags & 2 /* DeclarationOutputUnchanged */)) existing.latestChangedDtsTime = modifiedTime;
  } else {
    state.buildInfoCache.set(resolvedConfigPath, {
      path: toPath2(state, buildInfoPath),
      buildInfo,
      modifiedTime,
      latestChangedDtsTime: resultFlags & 2 /* DeclarationOutputUnchanged */ ? void 0 : modifiedTime
    });
  }
}
function getBuildInfoCacheEntry(state, buildInfoPath, resolvedConfigPath) {
  const path = toPath2(state, buildInfoPath);
  const existing = state.buildInfoCache.get(resolvedConfigPath);
  return (existing == null ? void 0 : existing.path) === path ? existing : void 0;
}
function getBuildInfo3(state, buildInfoPath, resolvedConfigPath, modifiedTime) {
  const path = toPath2(state, buildInfoPath);
  const existing = state.buildInfoCache.get(resolvedConfigPath);
  if (existing !== void 0 && existing.path === path) {
    return existing.buildInfo || void 0;
  }
  const value = state.readFileWithCache(buildInfoPath);
  const buildInfo = value ? getBuildInfo(buildInfoPath, value) : void 0;
  state.buildInfoCache.set(resolvedConfigPath, { path, buildInfo: buildInfo || false, modifiedTime: modifiedTime || missingFileModifiedTime });
  return buildInfo;
}
function checkConfigFileUpToDateStatus(state, configFile, oldestOutputFileTime, oldestOutputFileName) {
  const tsconfigTime = getModifiedTime2(state, configFile);
  if (oldestOutputFileTime < tsconfigTime) {
    return {
      type: 5 /* OutOfDateWithSelf */,
      outOfDateOutputFileName: oldestOutputFileName,
      newerInputFileName: configFile
    };
  }
}
function getUpToDateStatusWorker(state, project, resolvedPath) {
  var _a, _b, _c, _d;
  if (!project.fileNames.length && !canJsonReportNoInputFiles(project.raw)) {
    return {
      type: 15 /* ContainerOnly */
    };
  }
  let referenceStatuses;
  const force = !!state.options.force;
  if (project.projectReferences) {
    state.projectStatus.set(resolvedPath, { type: 12 /* ComputingUpstream */ });
    for (const ref of project.projectReferences) {
      const resolvedRef = resolveProjectReferencePath(ref);
      const resolvedRefPath = toResolvedConfigFilePath(state, resolvedRef);
      const resolvedConfig = parseConfigFile(state, resolvedRef, resolvedRefPath);
      const refStatus = getUpToDateStatus(state, resolvedConfig, resolvedRefPath);
      if (refStatus.type === 12 /* ComputingUpstream */ || refStatus.type === 15 /* ContainerOnly */) {
        continue;
      }
      if (refStatus.type === 0 /* Unbuildable */ || refStatus.type === 11 /* UpstreamBlocked */) {
        return {
          type: 11 /* UpstreamBlocked */,
          upstreamProjectName: ref.path,
          upstreamProjectBlocked: refStatus.type === 11 /* UpstreamBlocked */
        };
      }
      if (refStatus.type !== 1 /* UpToDate */) {
        return {
          type: 10 /* UpstreamOutOfDate */,
          upstreamProjectName: ref.path
        };
      }
      if (!force) (referenceStatuses || (referenceStatuses = [])).push({ ref, refStatus, resolvedRefPath, resolvedConfig });
    }
  }
  if (force) return { type: 16 /* ForceBuild */ };
  const { host } = state;
  const buildInfoPath = getTsBuildInfoEmitOutputFilePath(project.options);
  let oldestOutputFileName;
  let oldestOutputFileTime = maximumDate;
  let buildInfoTime;
  let buildInfoProgram;
  let buildInfoVersionMap;
  if (buildInfoPath) {
    const buildInfoCacheEntry2 = getBuildInfoCacheEntry(state, buildInfoPath, resolvedPath);
    buildInfoTime = (buildInfoCacheEntry2 == null ? void 0 : buildInfoCacheEntry2.modifiedTime) || getModifiedTime(host, buildInfoPath);
    if (buildInfoTime === missingFileModifiedTime) {
      if (!buildInfoCacheEntry2) {
        state.buildInfoCache.set(resolvedPath, {
          path: toPath2(state, buildInfoPath),
          buildInfo: false,
          modifiedTime: buildInfoTime
        });
      }
      return {
        type: 3 /* OutputMissing */,
        missingOutputFileName: buildInfoPath
      };
    }
    const buildInfo = getBuildInfo3(state, buildInfoPath, resolvedPath, buildInfoTime);
    if (!buildInfo) {
      return {
        type: 4 /* ErrorReadingFile */,
        fileName: buildInfoPath
      };
    }
    if (buildInfo.program && buildInfo.version !== version) {
      return {
        type: 13 /* TsVersionOutputOfDate */,
        version: buildInfo.version
      };
    }
    if (buildInfo.program) {
      if (((_a = buildInfo.program.changeFileSet) == null ? void 0 : _a.length) || (!project.options.noEmit ? ((_b = buildInfo.program.affectedFilesPendingEmit) == null ? void 0 : _b.length) || ((_c = buildInfo.program.emitDiagnosticsPerFile) == null ? void 0 : _c.length) : (_d = buildInfo.program.semanticDiagnosticsPerFile) == null ? void 0 : _d.length)) {
        return {
          type: 7 /* OutOfDateBuildInfo */,
          buildInfoFile: buildInfoPath
        };
      }
      if (!project.options.noEmit && getPendingEmitKind(project.options, buildInfo.program.options || {})) {
        return {
          type: 8 /* OutOfDateOptions */,
          buildInfoFile: buildInfoPath
        };
      }
      buildInfoProgram = buildInfo.program;
    }
    oldestOutputFileTime = buildInfoTime;
    oldestOutputFileName = buildInfoPath;
  }
  let newestInputFileName = void 0;
  let newestInputFileTime = minimumDate;
  let pseudoInputUpToDate = false;
  const seenRoots = /* @__PURE__ */ new Set();
  for (const inputFile of project.fileNames) {
    const inputTime = getModifiedTime2(state, inputFile);
    if (inputTime === missingFileModifiedTime) {
      return {
        type: 0 /* Unbuildable */,
        reason: `${inputFile} does not exist`
      };
    }
    const inputPath = buildInfoProgram ? toPath2(state, inputFile) : void 0;
    if (buildInfoTime && buildInfoTime < inputTime) {
      let version2;
      let currentVersion;
      if (buildInfoProgram) {
        if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath, host);
        const resolvedInputPath = buildInfoVersionMap.roots.get(inputPath);
        version2 = buildInfoVersionMap.fileInfos.get(resolvedInputPath ?? inputPath);
        const text = version2 ? state.readFileWithCache(resolvedInputPath ?? inputFile) : void 0;
        currentVersion = text !== void 0 ? getSourceFileVersionAsHashFromText(host, text) : void 0;
        if (version2 && version2 === currentVersion) pseudoInputUpToDate = true;
      }
      if (!version2 || version2 !== currentVersion) {
        return {
          type: 5 /* OutOfDateWithSelf */,
          outOfDateOutputFileName: buildInfoPath,
          newerInputFileName: inputFile
        };
      }
    }
    if (inputTime > newestInputFileTime) {
      newestInputFileName = inputFile;
      newestInputFileTime = inputTime;
    }
    if (buildInfoProgram) seenRoots.add(inputPath);
  }
  if (buildInfoProgram) {
    if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath, host);
    const existingRoot = forEachEntry(
      buildInfoVersionMap.roots,
      // File was root file when project was built but its not any more
      (_resolved, existingRoot2) => !seenRoots.has(existingRoot2) ? existingRoot2 : void 0
    );
    if (existingRoot) {
      return {
        type: 9 /* OutOfDateRoots */,
        buildInfoFile: buildInfoPath,
        inputFile: existingRoot
      };
    }
  }
  if (!buildInfoPath) {
    const outputs = getAllProjectOutputs(project, !host.useCaseSensitiveFileNames());
    const outputTimeStampMap = getOutputTimeStampMap(state, resolvedPath);
    for (const output of outputs) {
      const path = toPath2(state, output);
      let outputTime = outputTimeStampMap == null ? void 0 : outputTimeStampMap.get(path);
      if (!outputTime) {
        outputTime = getModifiedTime(state.host, output);
        outputTimeStampMap == null ? void 0 : outputTimeStampMap.set(path, outputTime);
      }
      if (outputTime === missingFileModifiedTime) {
        return {
          type: 3 /* OutputMissing */,
          missingOutputFileName: output
        };
      }
      if (outputTime < newestInputFileTime) {
        return {
          type: 5 /* OutOfDateWithSelf */,
          outOfDateOutputFileName: output,
          newerInputFileName: newestInputFileName
        };
      }
      if (outputTime < oldestOutputFileTime) {
        oldestOutputFileTime = outputTime;
        oldestOutputFileName = output;
      }
    }
  }
  const buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath);
  let pseudoUpToDate = false;
  if (referenceStatuses) {
    for (const { ref, refStatus, resolvedConfig, resolvedRefPath } of referenceStatuses) {
      if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) {
        continue;
      }
      if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) {
        return {
          type: 6 /* OutOfDateWithUpstream */,
          outOfDateOutputFileName: buildInfoPath,
          newerProjectName: ref.path
        };
      }
      const newestDeclarationFileContentChangedTime = getLatestChangedDtsTime(state, resolvedConfig.options, resolvedRefPath);
      if (newestDeclarationFileContentChangedTime && newestDeclarationFileContentChangedTime <= oldestOutputFileTime) {
        pseudoUpToDate = true;
        continue;
      }
      Debug.assert(oldestOutputFileName !== void 0, "Should have an oldest output filename here");
      return {
        type: 6 /* OutOfDateWithUpstream */,
        outOfDateOutputFileName: oldestOutputFileName,
        newerProjectName: ref.path
      };
    }
  }
  const configStatus = checkConfigFileUpToDateStatus(state, project.options.configFilePath, oldestOutputFileTime, oldestOutputFileName);
  if (configStatus) return configStatus;
  const extendedConfigStatus = forEach(project.options.configFile.extendedSourceFiles || emptyArray, (configFile) => checkConfigFileUpToDateStatus(state, configFile, oldestOutputFileTime, oldestOutputFileName));
  if (extendedConfigStatus) return extendedConfigStatus;
  const packageJsonLookups = state.lastCachedPackageJsonLookups.get(resolvedPath);
  const dependentPackageFileStatus = packageJsonLookups && forEachKey(
    packageJsonLookups,
    (path) => checkConfigFileUpToDateStatus(state, path, oldestOutputFileTime, oldestOutputFileName)
  );
  if (dependentPackageFileStatus) return dependentPackageFileStatus;
  return {
    type: pseudoUpToDate ? 2 /* UpToDateWithUpstreamTypes */ : pseudoInputUpToDate ? 14 /* UpToDateWithInputFileText */ : 1 /* UpToDate */,
    newestInputFileTime,
    newestInputFileName,
    oldestOutputFileName
  };
}
function hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath) {
  const refBuildInfo = state.buildInfoCache.get(resolvedRefPath);
  return refBuildInfo.path === buildInfoCacheEntry.path;
}
function getUpToDateStatus(state, project, resolvedPath) {
  if (project === void 0) {
    return { type: 0 /* Unbuildable */, reason: "File deleted mid-build" };
  }
  const prior = state.projectStatus.get(resolvedPath);
  if (prior !== void 0) {
    return prior;
  }
  mark("SolutionBuilder::beforeUpToDateCheck");
  const actual = getUpToDateStatusWorker(state, project, resolvedPath);
  mark("SolutionBuilder::afterUpToDateCheck");
  measure("SolutionBuilder::Up-to-date check", "SolutionBuilder::beforeUpToDateCheck", "SolutionBuilder::afterUpToDateCheck");
  state.projectStatus.set(resolvedPath, actual);
  return actual;
}
function updateOutputTimestampsWorker(state, proj, projectPath, verboseMessage, skipOutputs) {
  if (proj.options.noEmit) return;
  let now;
  const buildInfoPath = getTsBuildInfoEmitOutputFilePath(proj.options);
  if (buildInfoPath) {
    if (!(skipOutputs == null ? void 0 : skipOutputs.has(toPath2(state, buildInfoPath)))) {
      if (!!state.options.verbose) reportStatus(state, verboseMessage, proj.options.configFilePath);
      state.host.setModifiedTime(buildInfoPath, now = getCurrentTime(state.host));
      getBuildInfoCacheEntry(state, buildInfoPath, projectPath).modifiedTime = now;
    }
    state.outputTimeStamps.delete(projectPath);
    return;
  }
  const { host } = state;
  const outputs = getAllProjectOutputs(proj, !host.useCaseSensitiveFileNames());
  const outputTimeStampMap = getOutputTimeStampMap(state, projectPath);
  const modifiedOutputs = outputTimeStampMap ? /* @__PURE__ */ new Set() : void 0;
  if (!skipOutputs || outputs.length !== skipOutputs.size) {
    let reportVerbose = !!state.options.verbose;
    for (const file of outputs) {
      const path = toPath2(state, file);
      if (skipOutputs == null ? void 0 : skipOutputs.has(path)) continue;
      if (reportVerbose) {
        reportVerbose = false;
        reportStatus(state, verboseMessage, proj.options.configFilePath);
      }
      host.setModifiedTime(file, now || (now = getCurrentTime(state.host)));
      if (outputTimeStampMap) {
        outputTimeStampMap.set(path, now);
        modifiedOutputs.add(path);
      }
    }
  }
  outputTimeStampMap == null ? void 0 : outputTimeStampMap.forEach((_value, key) => {
    if (!(skipOutputs == null ? void 0 : skipOutputs.has(key)) && !modifiedOutputs.has(key)) outputTimeStampMap.delete(key);
  });
}
function getLatestChangedDtsTime(state, options, resolvedConfigPath) {
  if (!options.composite) return void 0;
  const entry = Debug.checkDefined(state.buildInfoCache.get(resolvedConfigPath));
  if (entry.latestChangedDtsTime !== void 0) return entry.latestChangedDtsTime || void 0;
  const latestChangedDtsTime = entry.buildInfo && entry.buildInfo.program && entry.buildInfo.program.latestChangedDtsFile ? state.host.getModifiedTime(getNormalizedAbsolutePath(entry.buildInfo.program.latestChangedDtsFile, getDirectoryPath(entry.path))) : void 0;
  entry.latestChangedDtsTime = latestChangedDtsTime || false;
  return latestChangedDtsTime;
}
function updateOutputTimestamps(state, proj, resolvedPath) {
  if (state.options.dry) {
    return reportStatus(state, Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath);
  }
  updateOutputTimestampsWorker(state, proj, resolvedPath, Diagnostics.Updating_output_timestamps_of_project_0);
  state.projectStatus.set(resolvedPath, {
    type: 1 /* UpToDate */,
    oldestOutputFileName: getFirstProjectOutput(proj, !state.host.useCaseSensitiveFileNames())
  });
}
function queueReferencingProjects(state, project, projectPath, projectIndex, config, buildOrder, buildResult) {
  if (buildResult & 124 /* AnyErrors */) return;
  if (!config.options.composite) return;
  for (let index = projectIndex + 1; index < buildOrder.length; index++) {
    const nextProject = buildOrder[index];
    const nextProjectPath = toResolvedConfigFilePath(state, nextProject);
    if (state.projectPendingBuild.has(nextProjectPath)) continue;
    const nextProjectConfig = parseConfigFile(state, nextProject, nextProjectPath);
    if (!nextProjectConfig || !nextProjectConfig.projectReferences) continue;
    for (const ref of nextProjectConfig.projectReferences) {
      const resolvedRefPath = resolveProjectName(state, ref.path);
      if (toResolvedConfigFilePath(state, resolvedRefPath) !== projectPath) continue;
      const status = state.projectStatus.get(nextProjectPath);
      if (status) {
        switch (status.type) {
          case 1 /* UpToDate */:
            if (buildResult & 2 /* DeclarationOutputUnchanged */) {
              status.type = 2 /* UpToDateWithUpstreamTypes */;
              break;
            }
          case 14 /* UpToDateWithInputFileText */:
          case 2 /* UpToDateWithUpstreamTypes */:
            if (!(buildResult & 2 /* DeclarationOutputUnchanged */)) {
              state.projectStatus.set(nextProjectPath, {
                type: 6 /* OutOfDateWithUpstream */,
                outOfDateOutputFileName: status.oldestOutputFileName,
                newerProjectName: project
              });
            }
            break;
          case 11 /* UpstreamBlocked */:
            if (toResolvedConfigFilePath(state, resolveProjectName(state, status.upstreamProjectName)) === projectPath) {
              clearProjectStatus(state, nextProjectPath);
            }
            break;
        }
      }
      addProjToQueue(state, nextProjectPath, 0 /* Update */);
      break;
    }
  }
}
function build(state, project, cancellationToken, writeFile2, getCustomTransformers, onlyReferences) {
  mark("SolutionBuilder::beforeBuild");
  const result = buildWorker(state, project, cancellationToken, writeFile2, getCustomTransformers, onlyReferences);
  mark("SolutionBuilder::afterBuild");
  measure("SolutionBuilder::Build", "SolutionBuilder::beforeBuild", "SolutionBuilder::afterBuild");
  return result;
}
function buildWorker(state, project, cancellationToken, writeFile2, getCustomTransformers, onlyReferences) {
  const buildOrder = getBuildOrderFor(state, project, onlyReferences);
  if (!buildOrder) return 3 /* InvalidProject_OutputsSkipped */;
  setupInitialBuild(state, cancellationToken);
  let reportQueue = true;
  let successfulProjects = 0;
  while (true) {
    const invalidatedProject = getNextInvalidatedProject(state, buildOrder, reportQueue);
    if (!invalidatedProject) break;
    reportQueue = false;
    invalidatedProject.done(cancellationToken, writeFile2, getCustomTransformers == null ? void 0 : getCustomTransformers(invalidatedProject.project));
    if (!state.diagnostics.has(invalidatedProject.projectPath)) successfulProjects++;
  }
  disableCache(state);
  reportErrorSummary(state, buildOrder);
  startWatching(state, buildOrder);
  return isCircularBuildOrder(buildOrder) ? 4 /* ProjectReferenceCycle_OutputsSkipped */ : !buildOrder.some((p) => state.diagnostics.has(toResolvedConfigFilePath(state, p))) ? 0 /* Success */ : successfulProjects ? 2 /* DiagnosticsPresent_OutputsGenerated */ : 1 /* DiagnosticsPresent_OutputsSkipped */;
}
function clean(state, project, onlyReferences) {
  mark("SolutionBuilder::beforeClean");
  const result = cleanWorker(state, project, onlyReferences);
  mark("SolutionBuilder::afterClean");
  measure("SolutionBuilder::Clean", "SolutionBuilder::beforeClean", "SolutionBuilder::afterClean");
  return result;
}
function cleanWorker(state, project, onlyReferences) {
  const buildOrder = getBuildOrderFor(state, project, onlyReferences);
  if (!buildOrder) return 3 /* InvalidProject_OutputsSkipped */;
  if (isCircularBuildOrder(buildOrder)) {
    reportErrors(state, buildOrder.circularDiagnostics);
    return 4 /* ProjectReferenceCycle_OutputsSkipped */;
  }
  const { options, host } = state;
  const filesToDelete = options.dry ? [] : void 0;
  for (const proj of buildOrder) {
    const resolvedPath = toResolvedConfigFilePath(state, proj);
    const parsed = parseConfigFile(state, proj, resolvedPath);
    if (parsed === void 0) {
      reportParseConfigFileDiagnostic(state, resolvedPath);
      continue;
    }
    const outputs = getAllProjectOutputs(parsed, !host.useCaseSensitiveFileNames());
    if (!outputs.length) continue;
    const inputFileNames = new Set(parsed.fileNames.map((f) => toPath2(state, f)));
    for (const output of outputs) {
      if (inputFileNames.has(toPath2(state, output))) continue;
      if (host.fileExists(output)) {
        if (filesToDelete) {
          filesToDelete.push(output);
        } else {
          host.deleteFile(output);
          invalidateProject(state, resolvedPath, 0 /* Update */);
        }
      }
    }
  }
  if (filesToDelete) {
    reportStatus(state, Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map((f) => `\r
 * ${f}`).join(""));
  }
  return 0 /* Success */;
}
function invalidateProject(state, resolved, updateLevel) {
  if (state.host.getParsedCommandLine && updateLevel === 1 /* RootNamesAndUpdate */) {
    updateLevel = 2 /* Full */;
  }
  if (updateLevel === 2 /* Full */) {
    state.configFileCache.delete(resolved);
    state.buildOrder = void 0;
  }
  state.needsSummary = true;
  clearProjectStatus(state, resolved);
  addProjToQueue(state, resolved, updateLevel);
  enableCache(state);
}
function invalidateProjectAndScheduleBuilds(state, resolvedPath, updateLevel) {
  state.reportFileChangeDetected = true;
  invalidateProject(state, resolvedPath, updateLevel);
  scheduleBuildInvalidatedProject(
    state,
    250,
    /*changeDetected*/
    true
  );
}
function scheduleBuildInvalidatedProject(state, time, changeDetected) {
  const { hostWithWatch } = state;
  if (!hostWithWatch.setTimeout || !hostWithWatch.clearTimeout) {
    return;
  }
  if (state.timerToBuildInvalidatedProject) {
    hostWithWatch.clearTimeout(state.timerToBuildInvalidatedProject);
  }
  state.timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildNextInvalidatedProject, time, "timerToBuildInvalidatedProject", state, changeDetected);
}
function buildNextInvalidatedProject(_timeoutType, state, changeDetected) {
  mark("SolutionBuilder::beforeBuild");
  const buildOrder = buildNextInvalidatedProjectWorker(state, changeDetected);
  mark("SolutionBuilder::afterBuild");
  measure("SolutionBuilder::Build", "SolutionBuilder::beforeBuild", "SolutionBuilder::afterBuild");
  if (buildOrder) reportErrorSummary(state, buildOrder);
}
function buildNextInvalidatedProjectWorker(state, changeDetected) {
  state.timerToBuildInvalidatedProject = void 0;
  if (state.reportFileChangeDetected) {
    state.reportFileChangeDetected = false;
    state.projectErrorsReported.clear();
    reportWatchStatus(state, Diagnostics.File_change_detected_Starting_incremental_compilation);
  }
  let projectsBuilt = 0;
  const buildOrder = getBuildOrder(state);
  const invalidatedProject = getNextInvalidatedProject(
    state,
    buildOrder,
    /*reportQueue*/
    false
  );
  if (invalidatedProject) {
    invalidatedProject.done();
    projectsBuilt++;
    while (state.projectPendingBuild.size) {
      if (state.timerToBuildInvalidatedProject) return;
      const info = getNextInvalidatedProjectCreateInfo(
        state,
        buildOrder,
        /*reportQueue*/
        false
      );
      if (!info) break;
      if (info.kind !== 1 /* UpdateOutputFileStamps */ && (changeDetected || projectsBuilt === 5)) {
        scheduleBuildInvalidatedProject(
          state,
          100,
          /*changeDetected*/
          false
        );
        return;
      }
      const project = createInvalidatedProjectWithInfo(state, info, buildOrder);
      project.done();
      if (info.kind !== 1 /* UpdateOutputFileStamps */) projectsBuilt++;
    }
  }
  disableCache(state);
  return buildOrder;
}
function watchConfigFile(state, resolved, resolvedPath, parsed) {
  if (!state.watch || state.allWatchedConfigFiles.has(resolvedPath)) return;
  state.allWatchedConfigFiles.set(
    resolvedPath,
    watchFile(
      state,
      resolved,
      () => invalidateProjectAndScheduleBuilds(state, resolvedPath, 2 /* Full */),
      2e3 /* High */,
      parsed == null ? void 0 : parsed.watchOptions,
      WatchType.ConfigFile,
      resolved
    )
  );
}
function watchExtendedConfigFiles(state, resolvedPath, parsed) {
  updateSharedExtendedConfigFileWatcher(
    resolvedPath,
    parsed == null ? void 0 : parsed.options,
    state.allWatchedExtendedConfigFiles,
    (extendedConfigFileName, extendedConfigFilePath) => watchFile(
      state,
      extendedConfigFileName,
      () => {
        var _a;
        return (_a = state.allWatchedExtendedConfigFiles.get(extendedConfigFilePath)) == null ? void 0 : _a.projects.forEach((projectConfigFilePath) => invalidateProjectAndScheduleBuilds(state, projectConfigFilePath, 2 /* Full */));
      },
      2e3 /* High */,
      parsed == null ? void 0 : parsed.watchOptions,
      WatchType.ExtendedConfigFile
    ),
    (fileName) => toPath2(state, fileName)
  );
}
function watchWildCardDirectories(state, resolved, resolvedPath, parsed) {
  if (!state.watch) return;
  updateWatchingWildcardDirectories(
    getOrCreateValueMapFromConfigFileMap(state.allWatchedWildcardDirectories, resolvedPath),
    parsed.wildcardDirectories,
    (dir, flags) => state.watchDirectory(
      dir,
      (fileOrDirectory) => {
        var _a;
        if (isIgnoredFileFromWildCardWatching({
          watchedDirPath: toPath2(state, dir),
          fileOrDirectory,
          fileOrDirectoryPath: toPath2(state, fileOrDirectory),
          configFileName: resolved,
          currentDirectory: state.compilerHost.getCurrentDirectory(),
          options: parsed.options,
          program: state.builderPrograms.get(resolvedPath) || ((_a = getCachedParsedConfigFile(state, resolvedPath)) == null ? void 0 : _a.fileNames),
          useCaseSensitiveFileNames: state.parseConfigFileHost.useCaseSensitiveFileNames,
          writeLog: (s) => state.writeLog(s),
          toPath: (fileName) => toPath2(state, fileName)
        })) return;
        invalidateProjectAndScheduleBuilds(state, resolvedPath, 1 /* RootNamesAndUpdate */);
      },
      flags,
      parsed == null ? void 0 : parsed.watchOptions,
      WatchType.WildcardDirectory,
      resolved
    )
  );
}
function watchInputFiles(state, resolved, resolvedPath, parsed) {
  if (!state.watch) return;
  mutateMap(
    getOrCreateValueMapFromConfigFileMap(state.allWatchedInputFiles, resolvedPath),
    new Set(parsed.fileNames),
    {
      createNewValue: (input) => watchFile(
        state,
        input,
        () => invalidateProjectAndScheduleBuilds(state, resolvedPath, 0 /* Update */),
        250 /* Low */,
        parsed == null ? void 0 : parsed.watchOptions,
        WatchType.SourceFile,
        resolved
      ),
      onDeleteValue: closeFileWatcher
    }
  );
}
function watchPackageJsonFiles(state, resolved, resolvedPath, parsed) {
  if (!state.watch || !state.lastCachedPackageJsonLookups) return;
  mutateMap(
    getOrCreateValueMapFromConfigFileMap(state.allWatchedPackageJsonFiles, resolvedPath),
    state.lastCachedPackageJsonLookups.get(resolvedPath),
    {
      createNewValue: (input) => watchFile(
        state,
        input,
        () => invalidateProjectAndScheduleBuilds(state, resolvedPath, 0 /* Update */),
        2e3 /* High */,
        parsed == null ? void 0 : parsed.watchOptions,
        WatchType.PackageJson,
        resolved
      ),
      onDeleteValue: closeFileWatcher
    }
  );
}
function startWatching(state, buildOrder) {
  if (!state.watchAllProjectsPending) return;
  mark("SolutionBuilder::beforeWatcherCreation");
  state.watchAllProjectsPending = false;
  for (const resolved of getBuildOrderFromAnyBuildOrder(buildOrder)) {
    const resolvedPath = toResolvedConfigFilePath(state, resolved);
    const cfg = parseConfigFile(state, resolved, resolvedPath);
    watchConfigFile(state, resolved, resolvedPath, cfg);
    watchExtendedConfigFiles(state, resolvedPath, cfg);
    if (cfg) {
      watchWildCardDirectories(state, resolved, resolvedPath, cfg);
      watchInputFiles(state, resolved, resolvedPath, cfg);
      watchPackageJsonFiles(state, resolved, resolvedPath, cfg);
    }
  }
  mark("SolutionBuilder::afterWatcherCreation");
  measure("SolutionBuilder::Watcher creation", "SolutionBuilder::beforeWatcherCreation", "SolutionBuilder::afterWatcherCreation");
}
function stopWatching(state) {
  clearMap(state.allWatchedConfigFiles, closeFileWatcher);
  clearMap(state.allWatchedExtendedConfigFiles, closeFileWatcherOf);
  clearMap(state.allWatchedWildcardDirectories, (watchedWildcardDirectories) => clearMap(watchedWildcardDirectories, closeFileWatcherOf));
  clearMap(state.allWatchedInputFiles, (watchedWildcardDirectories) => clearMap(watchedWildcardDirectories, closeFileWatcher));
  clearMap(state.allWatchedPackageJsonFiles, (watchedPacageJsonFiles) => clearMap(watchedPacageJsonFiles, closeFileWatcher));
}
function createSolutionBuilderWorker(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions) {
  const state = createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions);
  return {
    build: (project, cancellationToken, writeFile2, getCustomTransformers) => build(state, project, cancellationToken, writeFile2, getCustomTransformers),
    clean: (project) => clean(state, project),
    buildReferences: (project, cancellationToken, writeFile2, getCustomTransformers) => build(
      state,
      project,
      cancellationToken,
      writeFile2,
      getCustomTransformers,
      /*onlyReferences*/
      true
    ),
    cleanReferences: (project) => clean(
      state,
      project,
      /*onlyReferences*/
      true
    ),
    getNextInvalidatedProject: (cancellationToken) => {
      setupInitialBuild(state, cancellationToken);
      return getNextInvalidatedProject(
        state,
        getBuildOrder(state),
        /*reportQueue*/
        false
      );
    },
    getBuildOrder: () => getBuildOrder(state),
    getUpToDateStatusOfProject: (project) => {
      const configFileName = resolveProjectName(state, project);
      const configFilePath = toResolvedConfigFilePath(state, configFileName);
      return getUpToDateStatus(state, parseConfigFile(state, configFileName, configFilePath), configFilePath);
    },
    invalidateProject: (configFilePath, updateLevel) => invalidateProject(state, configFilePath, updateLevel || 0 /* Update */),
    close: () => stopWatching(state)
  };
}
function relName(state, path) {
  return convertToRelativePath(path, state.compilerHost.getCurrentDirectory(), state.compilerHost.getCanonicalFileName);
}
function reportStatus(state, message, ...args) {
  state.host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args));
}
function reportWatchStatus(state, message, ...args) {
  var _a, _b;
  (_b = (_a = state.hostWithWatch).onWatchStatusChange) == null ? void 0 : _b.call(_a, createCompilerDiagnostic(message, ...args), state.host.getNewLine(), state.baseCompilerOptions);
}
function reportErrors({ host }, errors) {
  errors.forEach((err) => host.reportDiagnostic(err));
}
function reportAndStoreErrors(state, proj, errors) {
  reportErrors(state, errors);
  state.projectErrorsReported.set(proj, true);
  if (errors.length) {
    state.diagnostics.set(proj, errors);
  }
}
function reportParseConfigFileDiagnostic(state, proj) {
  reportAndStoreErrors(state, proj, [state.configFileCache.get(proj)]);
}
function reportErrorSummary(state, buildOrder) {
  if (!state.needsSummary) return;
  state.needsSummary = false;
  const canReportSummary = state.watch || !!state.host.reportErrorSummary;
  const { diagnostics } = state;
  let totalErrors = 0;
  let filesInError = [];
  if (isCircularBuildOrder(buildOrder)) {
    reportBuildQueue(state, buildOrder.buildOrder);
    reportErrors(state, buildOrder.circularDiagnostics);
    if (canReportSummary) totalErrors += getErrorCountForSummary(buildOrder.circularDiagnostics);
    if (canReportSummary) filesInError = [...filesInError, ...getFilesInErrorForSummary(buildOrder.circularDiagnostics)];
  } else {
    buildOrder.forEach((project) => {
      const projectPath = toResolvedConfigFilePath(state, project);
      if (!state.projectErrorsReported.has(projectPath)) {
        reportErrors(state, diagnostics.get(projectPath) || emptyArray);
      }
    });
    if (canReportSummary) diagnostics.forEach((singleProjectErrors) => totalErrors += getErrorCountForSummary(singleProjectErrors));
    if (canReportSummary) diagnostics.forEach((singleProjectErrors) => [...filesInError, ...getFilesInErrorForSummary(singleProjectErrors)]);
  }
  if (state.watch) {
    reportWatchStatus(state, getWatchErrorSummaryDiagnosticMessage(totalErrors), totalErrors);
  } else if (state.host.reportErrorSummary) {
    state.host.reportErrorSummary(totalErrors, filesInError);
  }
}
function reportBuildQueue(state, buildQueue) {
  if (state.options.verbose) {
    reportStatus(state, Diagnostics.Projects_in_this_build_Colon_0, buildQueue.map((s) => "\r\n    * " + relName(state, s)).join(""));
  }
}
function reportUpToDateStatus(state, configFileName, status) {
  switch (status.type) {
    case 5 /* OutOfDateWithSelf */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_output_1_is_older_than_input_2,
        relName(state, configFileName),
        relName(state, status.outOfDateOutputFileName),
        relName(state, status.newerInputFileName)
      );
    case 6 /* OutOfDateWithUpstream */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_output_1_is_older_than_input_2,
        relName(state, configFileName),
        relName(state, status.outOfDateOutputFileName),
        relName(state, status.newerProjectName)
      );
    case 3 /* OutputMissing */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
        relName(state, configFileName),
        relName(state, status.missingOutputFileName)
      );
    case 4 /* ErrorReadingFile */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_there_was_error_reading_file_1,
        relName(state, configFileName),
        relName(state, status.fileName)
      );
    case 7 /* OutOfDateBuildInfo */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_some_of_the_changes_were_not_emitted,
        relName(state, configFileName),
        relName(state, status.buildInfoFile)
      );
    case 8 /* OutOfDateOptions */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_buildinfo_file_1_indicates_there_is_change_in_compilerOptions,
        relName(state, configFileName),
        relName(state, status.buildInfoFile)
      );
    case 9 /* OutOfDateRoots */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_file_2_was_root_file_of_compilation_but_not_any_more,
        relName(state, configFileName),
        relName(state, status.buildInfoFile),
        relName(state, status.inputFile)
      );
    case 1 /* UpToDate */:
      if (status.newestInputFileTime !== void 0) {
        return reportStatus(
          state,
          Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_output_2,
          relName(state, configFileName),
          relName(state, status.newestInputFileName || ""),
          relName(state, status.oldestOutputFileName || "")
        );
      }
      break;
    case 2 /* UpToDateWithUpstreamTypes */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies,
        relName(state, configFileName)
      );
    case 14 /* UpToDateWithInputFileText */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_up_to_date_but_needs_to_update_timestamps_of_output_files_that_are_older_than_input_files,
        relName(state, configFileName)
      );
    case 10 /* UpstreamOutOfDate */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date,
        relName(state, configFileName),
        relName(state, status.upstreamProjectName)
      );
    case 11 /* UpstreamBlocked */:
      return reportStatus(
        state,
        status.upstreamProjectBlocked ? Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_was_not_built : Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors,
        relName(state, configFileName),
        relName(state, status.upstreamProjectName)
      );
    case 0 /* Unbuildable */:
      return reportStatus(
        state,
        Diagnostics.Failed_to_parse_file_0_Colon_1,
        relName(state, configFileName),
        status.reason
      );
    case 13 /* TsVersionOutputOfDate */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2,
        relName(state, configFileName),
        status.version,
        version
      );
    case 16 /* ForceBuild */:
      return reportStatus(
        state,
        Diagnostics.Project_0_is_being_forcibly_rebuilt,
        relName(state, configFileName)
      );
    case 15 /* ContainerOnly */:
    case 12 /* ComputingUpstream */:
      break;
    default:
      assertType(status);
  }
}
function verboseReportProjectStatus(state, configFileName, status) {
  if (state.options.verbose) {
    reportUpToDateStatus(state, configFileName, status);
  }
}

// src/compiler/executeCommandLine.ts
function countLines(program) {
  const counts2 = getCountsMap();
  forEach(program.getSourceFiles(), (file) => {
    const key = getCountKey(program, file);
    const lineCount = getLineStarts(file).length;
    counts2.set(key, counts2.get(key) + lineCount);
  });
  return counts2;
}
function getCountsMap() {
  const counts2 = /* @__PURE__ */ new Map();
  counts2.set("Library", 0);
  counts2.set("Definitions", 0);
  counts2.set("TypeScript", 0);
  counts2.set("JavaScript", 0);
  counts2.set("JSON", 0);
  counts2.set("Other", 0);
  return counts2;
}
function getCountKey(program, file) {
  if (program.isSourceFileDefaultLibrary(file)) {
    return "Library";
  } else if (file.isDeclarationFile) {
    return "Definitions";
  }
  const path = file.path;
  if (fileExtensionIsOneOf(path, supportedTSExtensionsFlat)) {
    return "TypeScript";
  } else if (fileExtensionIsOneOf(path, supportedJSExtensionsFlat)) {
    return "JavaScript";
  } else if (fileExtensionIs(path, ".json" /* Json */)) {
    return "JSON";
  } else {
    return "Other";
  }
}
function updateReportDiagnostic(sys2, existing, options) {
  return shouldBePretty(sys2, options) ? createDiagnosticReporter(
    sys2,
    /*pretty*/
    true
  ) : existing;
}
function defaultIsPretty(sys2) {
  return !!sys2.writeOutputIsTTY && sys2.writeOutputIsTTY() && !sys2.getEnvironmentVariable("NO_COLOR");
}
function shouldBePretty(sys2, options) {
  if (!options || typeof options.pretty === "undefined") {
    return defaultIsPretty(sys2);
  }
  return options.pretty;
}
function getOptionsForHelp(commandLine) {
  return !!commandLine.options.all ? sort(optionDeclarations, (a, b) => compareStringsCaseInsensitive(a.name, b.name)) : filter(optionDeclarations.slice(), (v) => !!v.showInSimplifiedHelpView);
}
function printVersion(sys2) {
  sys2.write(getDiagnosticText(Diagnostics.Version_0, version) + sys2.newLine);
}
function createColors(sys2) {
  const showColors = defaultIsPretty(sys2);
  if (!showColors) {
    return {
      bold: (str) => str,
      blue: (str) => str,
      blueBackground: (str) => str,
      brightWhite: (str) => str
    };
  }
  function bold(str) {
    return `\x1B[1m${str}\x1B[22m`;
  }
  const isWindows = sys2.getEnvironmentVariable("OS") && sys2.getEnvironmentVariable("OS").toLowerCase().includes("windows");
  const isWindowsTerminal = sys2.getEnvironmentVariable("WT_SESSION");
  const isVSCode = sys2.getEnvironmentVariable("TERM_PROGRAM") && sys2.getEnvironmentVariable("TERM_PROGRAM") === "vscode";
  function blue(str) {
    if (isWindows && !isWindowsTerminal && !isVSCode) {
      return brightWhite(str);
    }
    return `\x1B[94m${str}\x1B[39m`;
  }
  const supportsRicherColors = sys2.getEnvironmentVariable("COLORTERM") === "truecolor" || sys2.getEnvironmentVariable("TERM") === "xterm-256color";
  function blueBackground(str) {
    if (supportsRicherColors) {
      return `\x1B[48;5;68m${str}\x1B[39;49m`;
    } else {
      return `\x1B[44m${str}\x1B[39;49m`;
    }
  }
  function brightWhite(str) {
    return `\x1B[97m${str}\x1B[39m`;
  }
  return {
    bold,
    blue,
    brightWhite,
    blueBackground
  };
}
function getDisplayNameTextOfOption(option) {
  return `--${option.name}${option.shortName ? `, -${option.shortName}` : ""}`;
}
function generateOptionOutput(sys2, option, rightAlignOfLeft, leftAlignOfRight) {
  var _a;
  const text = [];
  const colors = createColors(sys2);
  const name = getDisplayNameTextOfOption(option);
  const valueCandidates = getValueCandidate(option);
  const defaultValueDescription = typeof option.defaultValueDescription === "object" ? getDiagnosticText(option.defaultValueDescription) : formatDefaultValue(
    option.defaultValueDescription,
    option.type === "list" || option.type === "listOrElement" ? option.element.type : option.type
  );
  const terminalWidth = ((_a = sys2.getWidthOfTerminal) == null ? void 0 : _a.call(sys2)) ?? 0;
  if (terminalWidth >= 80) {
    let description = "";
    if (option.description) {
      description = getDiagnosticText(option.description);
    }
    text.push(...getPrettyOutput(
      name,
      description,
      rightAlignOfLeft,
      leftAlignOfRight,
      terminalWidth,
      /*colorLeft*/
      true
    ), sys2.newLine);
    if (showAdditionalInfoOutput(valueCandidates, option)) {
      if (valueCandidates) {
        text.push(...getPrettyOutput(
          valueCandidates.valueType,
          valueCandidates.possibleValues,
          rightAlignOfLeft,
          leftAlignOfRight,
          terminalWidth,
          /*colorLeft*/
          false
        ), sys2.newLine);
      }
      if (defaultValueDescription) {
        text.push(...getPrettyOutput(
          getDiagnosticText(Diagnostics.default_Colon),
          defaultValueDescription,
          rightAlignOfLeft,
          leftAlignOfRight,
          terminalWidth,
          /*colorLeft*/
          false
        ), sys2.newLine);
      }
    }
    text.push(sys2.newLine);
  } else {
    text.push(colors.blue(name), sys2.newLine);
    if (option.description) {
      const description = getDiagnosticText(option.description);
      text.push(description);
    }
    text.push(sys2.newLine);
    if (showAdditionalInfoOutput(valueCandidates, option)) {
      if (valueCandidates) {
        text.push(`${valueCandidates.valueType} ${valueCandidates.possibleValues}`);
      }
      if (defaultValueDescription) {
        if (valueCandidates) text.push(sys2.newLine);
        const diagType = getDiagnosticText(Diagnostics.default_Colon);
        text.push(`${diagType} ${defaultValueDescription}`);
      }
      text.push(sys2.newLine);
    }
    text.push(sys2.newLine);
  }
  return text;
  function formatDefaultValue(defaultValue, type) {
    return defaultValue !== void 0 && typeof type === "object" ? arrayFrom(type.entries()).filter(([, value]) => value === defaultValue).map(([name2]) => name2).join("/") : String(defaultValue);
  }
  function showAdditionalInfoOutput(valueCandidates2, option2) {
    const ignoreValues = ["string"];
    const ignoredDescriptions = [void 0, "false", "n/a"];
    const defaultValueDescription2 = option2.defaultValueDescription;
    if (option2.category === Diagnostics.Command_line_Options) return false;
    if (contains(ignoreValues, valueCandidates2 == null ? void 0 : valueCandidates2.possibleValues) && contains(ignoredDescriptions, defaultValueDescription2)) {
      return false;
    }
    return true;
  }
  function getPrettyOutput(left, right, rightAlignOfLeft2, leftAlignOfRight2, terminalWidth2, colorLeft) {
    const res = [];
    let isFirstLine = true;
    let remainRight = right;
    const rightCharacterNumber = terminalWidth2 - leftAlignOfRight2;
    while (remainRight.length > 0) {
      let curLeft = "";
      if (isFirstLine) {
        curLeft = left.padStart(rightAlignOfLeft2);
        curLeft = curLeft.padEnd(leftAlignOfRight2);
        curLeft = colorLeft ? colors.blue(curLeft) : curLeft;
      } else {
        curLeft = "".padStart(leftAlignOfRight2);
      }
      const curRight = remainRight.substr(0, rightCharacterNumber);
      remainRight = remainRight.slice(rightCharacterNumber);
      res.push(`${curLeft}${curRight}`);
      isFirstLine = false;
    }
    return res;
  }
  function getValueCandidate(option2) {
    if (option2.type === "object") {
      return void 0;
    }
    return {
      valueType: getValueType(option2),
      possibleValues: getPossibleValues(option2)
    };
    function getValueType(option3) {
      Debug.assert(option3.type !== "listOrElement");
      switch (option3.type) {
        case "string":
        case "number":
        case "boolean":
          return getDiagnosticText(Diagnostics.type_Colon);
        case "list":
          return getDiagnosticText(Diagnostics.one_or_more_Colon);
        default:
          return getDiagnosticText(Diagnostics.one_of_Colon);
      }
    }
    function getPossibleValues(option3) {
      let possibleValues;
      switch (option3.type) {
        case "string":
        case "number":
        case "boolean":
          possibleValues = option3.type;
          break;
        case "list":
        case "listOrElement":
          possibleValues = getPossibleValues(option3.element);
          break;
        case "object":
          possibleValues = "";
          break;
        default:
          const inverted = {};
          option3.type.forEach((value, name2) => {
            var _a2;
            if (!((_a2 = option3.deprecatedKeys) == null ? void 0 : _a2.has(name2))) {
              (inverted[value] || (inverted[value] = [])).push(name2);
            }
          });
          return Object.entries(inverted).map(([, synonyms]) => synonyms.join("/")).join(", ");
      }
      return possibleValues;
    }
  }
}
function generateGroupOptionOutput(sys2, optionsList) {
  let maxLength = 0;
  for (const option of optionsList) {
    const curLength = getDisplayNameTextOfOption(option).length;
    maxLength = maxLength > curLength ? maxLength : curLength;
  }
  const rightAlignOfLeftPart = maxLength + 2;
  const leftAlignOfRightPart = rightAlignOfLeftPart + 2;
  let lines = [];
  for (const option of optionsList) {
    const tmp = generateOptionOutput(sys2, option, rightAlignOfLeftPart, leftAlignOfRightPart);
    lines = [...lines, ...tmp];
  }
  if (lines[lines.length - 2] !== sys2.newLine) {
    lines.push(sys2.newLine);
  }
  return lines;
}
function generateSectionOptionsOutput(sys2, sectionName, options, subCategory, beforeOptionsDescription, afterOptionsDescription) {
  let res = [];
  res.push(createColors(sys2).bold(sectionName) + sys2.newLine + sys2.newLine);
  if (beforeOptionsDescription) {
    res.push(beforeOptionsDescription + sys2.newLine + sys2.newLine);
  }
  if (!subCategory) {
    res = [...res, ...generateGroupOptionOutput(sys2, options)];
    if (afterOptionsDescription) {
      res.push(afterOptionsDescription + sys2.newLine + sys2.newLine);
    }
    return res;
  }
  const categoryMap = /* @__PURE__ */ new Map();
  for (const option of options) {
    if (!option.category) {
      continue;
    }
    const curCategory = getDiagnosticText(option.category);
    const optionsOfCurCategory = categoryMap.get(curCategory) ?? [];
    optionsOfCurCategory.push(option);
    categoryMap.set(curCategory, optionsOfCurCategory);
  }
  categoryMap.forEach((value, key) => {
    res.push(`### ${key}${sys2.newLine}${sys2.newLine}`);
    res = [...res, ...generateGroupOptionOutput(sys2, value)];
  });
  if (afterOptionsDescription) {
    res.push(afterOptionsDescription + sys2.newLine + sys2.newLine);
  }
  return res;
}
function printEasyHelp(sys2, simpleOptions) {
  const colors = createColors(sys2);
  let output = [...getHeader(sys2, `${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)];
  output.push(colors.bold(getDiagnosticText(Diagnostics.COMMON_COMMANDS)) + sys2.newLine + sys2.newLine);
  example("tsc", Diagnostics.Compiles_the_current_project_tsconfig_json_in_the_working_directory);
  example("tsc app.ts util.ts", Diagnostics.Ignoring_tsconfig_json_compiles_the_specified_files_with_default_compiler_options);
  example("tsc -b", Diagnostics.Build_a_composite_project_in_the_working_directory);
  example("tsc --init", Diagnostics.Creates_a_tsconfig_json_with_the_recommended_settings_in_the_working_directory);
  example("tsc -p ./path/to/tsconfig.json", Diagnostics.Compiles_the_TypeScript_project_located_at_the_specified_path);
  example("tsc --help --all", Diagnostics.An_expanded_version_of_this_information_showing_all_possible_compiler_options);
  example(["tsc --noEmit", "tsc --target esnext"], Diagnostics.Compiles_the_current_project_with_additional_settings);
  const cliCommands = simpleOptions.filter((opt) => opt.isCommandLineOnly || opt.category === Diagnostics.Command_line_Options);
  const configOpts = simpleOptions.filter((opt) => !contains(cliCommands, opt));
  output = [
    ...output,
    ...generateSectionOptionsOutput(
      sys2,
      getDiagnosticText(Diagnostics.COMMAND_LINE_FLAGS),
      cliCommands,
      /*subCategory*/
      false,
      /*beforeOptionsDescription*/
      void 0,
      /*afterOptionsDescription*/
      void 0
    ),
    ...generateSectionOptionsOutput(
      sys2,
      getDiagnosticText(Diagnostics.COMMON_COMPILER_OPTIONS),
      configOpts,
      /*subCategory*/
      false,
      /*beforeOptionsDescription*/
      void 0,
      formatMessage(Diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0, "https://aka.ms/tsc")
    )
  ];
  for (const line of output) {
    sys2.write(line);
  }
  function example(ex, desc) {
    const examples = typeof ex === "string" ? [ex] : ex;
    for (const example2 of examples) {
      output.push("  " + colors.blue(example2) + sys2.newLine);
    }
    output.push("  " + getDiagnosticText(desc) + sys2.newLine + sys2.newLine);
  }
}
function printAllHelp(sys2, compilerOptions, buildOptions, watchOptions) {
  let output = [...getHeader(sys2, `${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)];
  output = [...output, ...generateSectionOptionsOutput(
    sys2,
    getDiagnosticText(Diagnostics.ALL_COMPILER_OPTIONS),
    compilerOptions,
    /*subCategory*/
    true,
    /*beforeOptionsDescription*/
    void 0,
    formatMessage(Diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0, "https://aka.ms/tsc")
  )];
  output = [...output, ...generateSectionOptionsOutput(
    sys2,
    getDiagnosticText(Diagnostics.WATCH_OPTIONS),
    watchOptions,
    /*subCategory*/
    false,
    getDiagnosticText(Diagnostics.Including_watch_w_will_start_watching_the_current_project_for_the_file_changes_Once_set_you_can_config_watch_mode_with_Colon)
  )];
  output = [...output, ...generateSectionOptionsOutput(
    sys2,
    getDiagnosticText(Diagnostics.BUILD_OPTIONS),
    buildOptions,
    /*subCategory*/
    false,
    formatMessage(Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds")
  )];
  for (const line of output) {
    sys2.write(line);
  }
}
function printBuildHelp(sys2, buildOptions) {
  let output = [...getHeader(sys2, `${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)];
  output = [...output, ...generateSectionOptionsOutput(
    sys2,
    getDiagnosticText(Diagnostics.BUILD_OPTIONS),
    buildOptions,
    /*subCategory*/
    false,
    formatMessage(Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds")
  )];
  for (const line of output) {
    sys2.write(line);
  }
}
function getHeader(sys2, message) {
  var _a;
  const colors = createColors(sys2);
  const header = [];
  const terminalWidth = ((_a = sys2.getWidthOfTerminal) == null ? void 0 : _a.call(sys2)) ?? 0;
  const tsIconLength = 5;
  const tsIconFirstLine = colors.blueBackground("".padStart(tsIconLength));
  const tsIconSecondLine = colors.blueBackground(colors.brightWhite("TS ".padStart(tsIconLength)));
  if (terminalWidth >= message.length + tsIconLength) {
    const rightAlign = terminalWidth > 120 ? 120 : terminalWidth;
    const leftAlign = rightAlign - tsIconLength;
    header.push(message.padEnd(leftAlign) + tsIconFirstLine + sys2.newLine);
    header.push("".padStart(leftAlign) + tsIconSecondLine + sys2.newLine);
  } else {
    header.push(message + sys2.newLine);
    header.push(sys2.newLine);
  }
  return header;
}
function printHelp(sys2, commandLine) {
  if (!commandLine.options.all) {
    printEasyHelp(sys2, getOptionsForHelp(commandLine));
  } else {
    printAllHelp(sys2, getOptionsForHelp(commandLine), optionsForBuild, optionsForWatch);
  }
}
function executeCommandLineWorker(sys2, cb, commandLine) {
  let reportDiagnostic = createDiagnosticReporter(sys2);
  if (commandLine.options.build) {
    reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_build_must_be_the_first_command_line_argument));
    return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
  }
  let configFileName;
  if (commandLine.options.locale) {
    validateLocaleAndSetLanguage(commandLine.options.locale, sys2, commandLine.errors);
  }
  if (commandLine.errors.length > 0) {
    commandLine.errors.forEach(reportDiagnostic);
    return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
  }
  if (commandLine.options.init) {
    writeConfigFile(sys2, reportDiagnostic, commandLine.options, commandLine.fileNames);
    return sys2.exit(0 /* Success */);
  }
  if (commandLine.options.version) {
    printVersion(sys2);
    return sys2.exit(0 /* Success */);
  }
  if (commandLine.options.help || commandLine.options.all) {
    printHelp(sys2, commandLine);
    return sys2.exit(0 /* Success */);
  }
  if (commandLine.options.watch && commandLine.options.listFilesOnly) {
    reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "listFilesOnly"));
    return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
  }
  if (commandLine.options.project) {
    if (commandLine.fileNames.length !== 0) {
      reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line));
      return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
    }
    const fileOrDirectory = normalizePath(commandLine.options.project);
    if (!fileOrDirectory || sys2.directoryExists(fileOrDirectory)) {
      configFileName = combinePaths(fileOrDirectory, "tsconfig.json");
      if (!sys2.fileExists(configFileName)) {
        reportDiagnostic(createCompilerDiagnostic(Diagnostics.Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0, commandLine.options.project));
        return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
      }
    } else {
      configFileName = fileOrDirectory;
      if (!sys2.fileExists(configFileName)) {
        reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, commandLine.options.project));
        return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
      }
    }
  } else if (commandLine.fileNames.length === 0) {
    const searchPath = normalizePath(sys2.getCurrentDirectory());
    configFileName = findConfigFile(searchPath, (fileName) => sys2.fileExists(fileName));
  }
  if (commandLine.fileNames.length === 0 && !configFileName) {
    if (commandLine.options.showConfig) {
      reportDiagnostic(createCompilerDiagnostic(Diagnostics.Cannot_find_a_tsconfig_json_file_at_the_current_directory_Colon_0, normalizePath(sys2.getCurrentDirectory())));
    } else {
      printVersion(sys2);
      printHelp(sys2, commandLine);
    }
    return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
  }
  const currentDirectory = sys2.getCurrentDirectory();
  const commandLineOptions = convertToOptionsWithAbsolutePaths(
    commandLine.options,
    (fileName) => getNormalizedAbsolutePath(fileName, currentDirectory)
  );
  if (configFileName) {
    const extendedConfigCache = /* @__PURE__ */ new Map();
    const configParseResult = parseConfigFileWithSystem(configFileName, commandLineOptions, extendedConfigCache, commandLine.watchOptions, sys2, reportDiagnostic);
    if (commandLineOptions.showConfig) {
      if (configParseResult.errors.length !== 0) {
        reportDiagnostic = updateReportDiagnostic(
          sys2,
          reportDiagnostic,
          configParseResult.options
        );
        configParseResult.errors.forEach(reportDiagnostic);
        return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
      }
      sys2.write(JSON.stringify(convertToTSConfig(configParseResult, configFileName, sys2), null, 4) + sys2.newLine);
      return sys2.exit(0 /* Success */);
    }
    reportDiagnostic = updateReportDiagnostic(
      sys2,
      reportDiagnostic,
      configParseResult.options
    );
    if (isWatchSet(configParseResult.options)) {
      if (reportWatchModeWithoutSysSupport(sys2, reportDiagnostic)) return;
      return createWatchOfConfigFile(
        sys2,
        cb,
        reportDiagnostic,
        configParseResult,
        commandLineOptions,
        commandLine.watchOptions,
        extendedConfigCache
      );
    } else if (isIncrementalCompilation(configParseResult.options)) {
      performIncrementalCompilation2(
        sys2,
        cb,
        reportDiagnostic,
        configParseResult
      );
    } else {
      performCompilation(
        sys2,
        cb,
        reportDiagnostic,
        configParseResult
      );
    }
  } else {
    if (commandLineOptions.showConfig) {
      sys2.write(JSON.stringify(convertToTSConfig(commandLine, combinePaths(currentDirectory, "tsconfig.json"), sys2), null, 4) + sys2.newLine);
      return sys2.exit(0 /* Success */);
    }
    reportDiagnostic = updateReportDiagnostic(
      sys2,
      reportDiagnostic,
      commandLineOptions
    );
    if (isWatchSet(commandLineOptions)) {
      if (reportWatchModeWithoutSysSupport(sys2, reportDiagnostic)) return;
      return createWatchOfFilesAndCompilerOptions(
        sys2,
        cb,
        reportDiagnostic,
        commandLine.fileNames,
        commandLineOptions,
        commandLine.watchOptions
      );
    } else if (isIncrementalCompilation(commandLineOptions)) {
      performIncrementalCompilation2(
        sys2,
        cb,
        reportDiagnostic,
        { ...commandLine, options: commandLineOptions }
      );
    } else {
      performCompilation(
        sys2,
        cb,
        reportDiagnostic,
        { ...commandLine, options: commandLineOptions }
      );
    }
  }
}
function isBuild(commandLineArgs) {
  if (commandLineArgs.length > 0 && commandLineArgs[0].charCodeAt(0) === 45 /* minus */) {
    const firstOption = commandLineArgs[0].slice(commandLineArgs[0].charCodeAt(1) === 45 /* minus */ ? 2 : 1).toLowerCase();
    return firstOption === "build" || firstOption === "b";
  }
  return false;
}
function executeCommandLine(system, cb, commandLineArgs) {
  if (isBuild(commandLineArgs)) {
    const { buildOptions, watchOptions, projects, errors } = parseBuildCommand(commandLineArgs.slice(1));
    if (buildOptions.generateCpuProfile && system.enableCPUProfiler) {
      system.enableCPUProfiler(buildOptions.generateCpuProfile, () => performBuild(
        system,
        cb,
        buildOptions,
        watchOptions,
        projects,
        errors
      ));
    } else {
      return performBuild(
        system,
        cb,
        buildOptions,
        watchOptions,
        projects,
        errors
      );
    }
  }
  const commandLine = parseCommandLine(commandLineArgs, (path) => system.readFile(path));
  if (commandLine.options.generateCpuProfile && system.enableCPUProfiler) {
    system.enableCPUProfiler(commandLine.options.generateCpuProfile, () => executeCommandLineWorker(
      system,
      cb,
      commandLine
    ));
  } else {
    return executeCommandLineWorker(system, cb, commandLine);
  }
}
function reportWatchModeWithoutSysSupport(sys2, reportDiagnostic) {
  if (!sys2.watchFile || !sys2.watchDirectory) {
    reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"));
    sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
    return true;
  }
  return false;
}
var defaultJSDocParsingMode = 2 /* ParseForTypeErrors */;
function performBuild(sys2, cb, buildOptions, watchOptions, projects, errors) {
  const reportDiagnostic = updateReportDiagnostic(
    sys2,
    createDiagnosticReporter(sys2),
    buildOptions
  );
  if (buildOptions.locale) {
    validateLocaleAndSetLanguage(buildOptions.locale, sys2, errors);
  }
  if (errors.length > 0) {
    errors.forEach(reportDiagnostic);
    return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
  }
  if (buildOptions.help) {
    printVersion(sys2);
    printBuildHelp(sys2, buildOpts);
    return sys2.exit(0 /* Success */);
  }
  if (projects.length === 0) {
    printVersion(sys2);
    printBuildHelp(sys2, buildOpts);
    return sys2.exit(0 /* Success */);
  }
  if (!sys2.getModifiedTime || !sys2.setModifiedTime || buildOptions.clean && !sys2.deleteFile) {
    reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--build"));
    return sys2.exit(1 /* DiagnosticsPresent_OutputsSkipped */);
  }
  if (buildOptions.watch) {
    if (reportWatchModeWithoutSysSupport(sys2, reportDiagnostic)) return;
    const buildHost2 = createSolutionBuilderWithWatchHost(
      sys2,
      /*createProgram*/
      void 0,
      reportDiagnostic,
      createBuilderStatusReporter(sys2, shouldBePretty(sys2, buildOptions)),
      createWatchStatusReporter2(sys2, buildOptions)
    );
    buildHost2.jsDocParsingMode = defaultJSDocParsingMode;
    const solutionPerformance2 = enableSolutionPerformance(sys2, buildOptions);
    updateSolutionBuilderHost(sys2, cb, buildHost2, solutionPerformance2);
    const onWatchStatusChange = buildHost2.onWatchStatusChange;
    let reportBuildStatistics = false;
    buildHost2.onWatchStatusChange = (d, newLine, options, errorCount) => {
      onWatchStatusChange == null ? void 0 : onWatchStatusChange(d, newLine, options, errorCount);
      if (reportBuildStatistics && (d.code === Diagnostics.Found_0_errors_Watching_for_file_changes.code || d.code === Diagnostics.Found_1_error_Watching_for_file_changes.code)) {
        reportSolutionBuilderTimes(builder2, solutionPerformance2);
      }
    };
    const builder2 = createSolutionBuilderWithWatch(buildHost2, projects, buildOptions, watchOptions);
    builder2.build();
    reportSolutionBuilderTimes(builder2, solutionPerformance2);
    reportBuildStatistics = true;
    return builder2;
  }
  const buildHost = createSolutionBuilderHost(
    sys2,
    /*createProgram*/
    void 0,
    reportDiagnostic,
    createBuilderStatusReporter(sys2, shouldBePretty(sys2, buildOptions)),
    createReportErrorSummary(sys2, buildOptions)
  );
  buildHost.jsDocParsingMode = defaultJSDocParsingMode;
  const solutionPerformance = enableSolutionPerformance(sys2, buildOptions);
  updateSolutionBuilderHost(sys2, cb, buildHost, solutionPerformance);
  const builder = createSolutionBuilder(buildHost, projects, buildOptions);
  const exitStatus = buildOptions.clean ? builder.clean() : builder.build();
  reportSolutionBuilderTimes(builder, solutionPerformance);
  dumpTracingLegend();
  return sys2.exit(exitStatus);
}
function createReportErrorSummary(sys2, options) {
  return shouldBePretty(sys2, options) ? (errorCount, filesInError) => sys2.write(getErrorSummaryText(errorCount, filesInError, sys2.newLine, sys2)) : void 0;
}
function performCompilation(sys2, cb, reportDiagnostic, config) {
  const { fileNames, options, projectReferences } = config;
  const host = createCompilerHostWorker(
    options,
    /*setParentNodes*/
    void 0,
    sys2
  );
  host.jsDocParsingMode = defaultJSDocParsingMode;
  const currentDirectory = host.getCurrentDirectory();
  const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
  changeCompilerHostLikeToUseCache(host, (fileName) => toPath(fileName, currentDirectory, getCanonicalFileName));
  enableStatisticsAndTracing(
    sys2,
    options,
    /*isBuildMode*/
    false
  );
  const programOptions = {
    rootNames: fileNames,
    options,
    projectReferences,
    host,
    configFileParsingDiagnostics: getConfigFileParsingDiagnostics(config)
  };
  const program = createProgram(programOptions);
  const exitStatus = emitFilesAndReportErrorsAndGetExitStatus(
    program,
    reportDiagnostic,
    (s) => sys2.write(s + sys2.newLine),
    createReportErrorSummary(sys2, options)
  );
  reportStatistics(
    sys2,
    program,
    /*solutionPerformance*/
    void 0
  );
  cb(program);
  return sys2.exit(exitStatus);
}
function performIncrementalCompilation2(sys2, cb, reportDiagnostic, config) {
  const { options, fileNames, projectReferences } = config;
  enableStatisticsAndTracing(
    sys2,
    options,
    /*isBuildMode*/
    false
  );
  const host = createIncrementalCompilerHost(options, sys2);
  host.jsDocParsingMode = defaultJSDocParsingMode;
  const exitStatus = performIncrementalCompilation({
    host,
    system: sys2,
    rootNames: fileNames,
    options,
    configFileParsingDiagnostics: getConfigFileParsingDiagnostics(config),
    projectReferences,
    reportDiagnostic,
    reportErrorSummary: createReportErrorSummary(sys2, options),
    afterProgramEmitAndDiagnostics: (builderProgram) => {
      reportStatistics(
        sys2,
        builderProgram.getProgram(),
        /*solutionPerformance*/
        void 0
      );
      cb(builderProgram);
    }
  });
  return sys2.exit(exitStatus);
}
function updateSolutionBuilderHost(sys2, cb, buildHost, solutionPerformance) {
  updateCreateProgram(
    sys2,
    buildHost,
    /*isBuildMode*/
    true
  );
  buildHost.afterProgramEmitAndDiagnostics = (program) => {
    reportStatistics(sys2, program.getProgram(), solutionPerformance);
    cb(program);
  };
}
function updateCreateProgram(sys2, host, isBuildMode) {
  const compileUsingBuilder = host.createProgram;
  host.createProgram = (rootNames, options, host2, oldProgram, configFileParsingDiagnostics, projectReferences) => {
    Debug.assert(rootNames !== void 0 || options === void 0 && !!oldProgram);
    if (options !== void 0) {
      enableStatisticsAndTracing(sys2, options, isBuildMode);
    }
    return compileUsingBuilder(rootNames, options, host2, oldProgram, configFileParsingDiagnostics, projectReferences);
  };
}
function updateWatchCompilationHost(sys2, cb, watchCompilerHost) {
  watchCompilerHost.jsDocParsingMode = defaultJSDocParsingMode;
  updateCreateProgram(
    sys2,
    watchCompilerHost,
    /*isBuildMode*/
    false
  );
  const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate;
  watchCompilerHost.afterProgramCreate = (builderProgram) => {
    emitFilesUsingBuilder(builderProgram);
    reportStatistics(
      sys2,
      builderProgram.getProgram(),
      /*solutionPerformance*/
      void 0
    );
    cb(builderProgram);
  };
}
function createWatchStatusReporter2(sys2, options) {
  return createWatchStatusReporter(sys2, shouldBePretty(sys2, options));
}
function createWatchOfConfigFile(system, cb, reportDiagnostic, configParseResult, optionsToExtend, watchOptionsToExtend, extendedConfigCache) {
  const watchCompilerHost = createWatchCompilerHostOfConfigFile({
    configFileName: configParseResult.options.configFilePath,
    optionsToExtend,
    watchOptionsToExtend,
    system,
    reportDiagnostic,
    reportWatchStatus: createWatchStatusReporter2(system, configParseResult.options)
  });
  updateWatchCompilationHost(system, cb, watchCompilerHost);
  watchCompilerHost.configFileParsingResult = configParseResult;
  watchCompilerHost.extendedConfigCache = extendedConfigCache;
  return createWatchProgram(watchCompilerHost);
}
function createWatchOfFilesAndCompilerOptions(system, cb, reportDiagnostic, rootFiles, options, watchOptions) {
  const watchCompilerHost = createWatchCompilerHostOfFilesAndCompilerOptions({
    rootFiles,
    options,
    watchOptions,
    system,
    reportDiagnostic,
    reportWatchStatus: createWatchStatusReporter2(system, options)
  });
  updateWatchCompilationHost(system, cb, watchCompilerHost);
  return createWatchProgram(watchCompilerHost);
}
function enableSolutionPerformance(system, options) {
  if (system === sys && options.extendedDiagnostics) {
    enable();
    return createSolutionPerfomrance();
  }
}
function createSolutionPerfomrance() {
  let statistics;
  return {
    addAggregateStatistic,
    forEachAggregateStatistics: forEachAggreateStatistics,
    clear: clear2
  };
  function addAggregateStatistic(s) {
    const existing = statistics == null ? void 0 : statistics.get(s.name);
    if (existing) {
      if (existing.type === 2 /* memory */) existing.value = Math.max(existing.value, s.value);
      else existing.value += s.value;
    } else {
      (statistics ?? (statistics = /* @__PURE__ */ new Map())).set(s.name, s);
    }
  }
  function forEachAggreateStatistics(cb) {
    statistics == null ? void 0 : statistics.forEach(cb);
  }
  function clear2() {
    statistics = void 0;
  }
}
function reportSolutionBuilderTimes(builder, solutionPerformance) {
  if (!solutionPerformance) return;
  if (!isEnabled()) {
    sys.write(Diagnostics.Performance_timings_for_diagnostics_or_extendedDiagnostics_are_not_available_in_this_session_A_native_implementation_of_the_Web_Performance_API_could_not_be_found.message + "\n");
    return;
  }
  const statistics = [];
  statistics.push(
    { name: "Projects in scope", value: getBuildOrderFromAnyBuildOrder(builder.getBuildOrder()).length, type: 1 /* count */ }
  );
  reportSolutionBuilderCountStatistic("SolutionBuilder::Projects built");
  reportSolutionBuilderCountStatistic("SolutionBuilder::Timestamps only updates");
  reportSolutionBuilderCountStatistic("SolutionBuilder::Bundles updated");
  solutionPerformance.forEachAggregateStatistics((s) => {
    s.name = `Aggregate ${s.name}`;
    statistics.push(s);
  });
  forEachMeasure((name, duration) => {
    if (isSolutionMarkOrMeasure(name)) statistics.push({ name: `${getNameFromSolutionBuilderMarkOrMeasure(name)} time`, value: duration, type: 0 /* time */ });
  });
  disable();
  enable();
  solutionPerformance.clear();
  reportAllStatistics(sys, statistics);
  function reportSolutionBuilderCountStatistic(name) {
    const value = getCount(name);
    if (value) {
      statistics.push({ name: getNameFromSolutionBuilderMarkOrMeasure(name), value, type: 1 /* count */ });
    }
  }
  function getNameFromSolutionBuilderMarkOrMeasure(name) {
    return name.replace("SolutionBuilder::", "");
  }
}
function canReportDiagnostics(system, compilerOptions) {
  return system === sys && (compilerOptions.diagnostics || compilerOptions.extendedDiagnostics);
}
function canTrace(system, compilerOptions) {
  return system === sys && compilerOptions.generateTrace;
}
function enableStatisticsAndTracing(system, compilerOptions, isBuildMode) {
  if (canReportDiagnostics(system, compilerOptions)) {
    enable(system);
  }
  if (canTrace(system, compilerOptions)) {
    startTracing(isBuildMode ? "build" : "project", compilerOptions.generateTrace, compilerOptions.configFilePath);
  }
}
function isSolutionMarkOrMeasure(name) {
  return startsWith(name, "SolutionBuilder::");
}
function reportStatistics(sys2, program, solutionPerformance) {
  var _a;
  const compilerOptions = program.getCompilerOptions();
  if (canTrace(sys2, compilerOptions)) {
    (_a = tracing) == null ? void 0 : _a.stopTracing();
  }
  let statistics;
  if (canReportDiagnostics(sys2, compilerOptions)) {
    statistics = [];
    const memoryUsed = sys2.getMemoryUsage ? sys2.getMemoryUsage() : -1;
    reportCountStatistic("Files", program.getSourceFiles().length);
    const lineCounts = countLines(program);
    if (compilerOptions.extendedDiagnostics) {
      for (const [key, value] of lineCounts.entries()) {
        reportCountStatistic("Lines of " + key, value);
      }
    } else {
      reportCountStatistic("Lines", reduceLeftIterator(lineCounts.values(), (sum, count) => sum + count, 0));
    }
    reportCountStatistic("Identifiers", program.getIdentifierCount());
    reportCountStatistic("Symbols", program.getSymbolCount());
    reportCountStatistic("Types", program.getTypeCount());
    reportCountStatistic("Instantiations", program.getInstantiationCount());
    if (memoryUsed >= 0) {
      reportStatisticalValue(
        { name: "Memory used", value: memoryUsed, type: 2 /* memory */ },
        /*aggregate*/
        true
      );
    }
    const isPerformanceEnabled = isEnabled();
    const programTime = isPerformanceEnabled ? getDuration("Program") : 0;
    const bindTime = isPerformanceEnabled ? getDuration("Bind") : 0;
    const checkTime = isPerformanceEnabled ? getDuration("Check") : 0;
    const emitTime = isPerformanceEnabled ? getDuration("Emit") : 0;
    if (compilerOptions.extendedDiagnostics) {
      const caches = program.getRelationCacheSizes();
      reportCountStatistic("Assignability cache size", caches.assignable);
      reportCountStatistic("Identity cache size", caches.identity);
      reportCountStatistic("Subtype cache size", caches.subtype);
      reportCountStatistic("Strict subtype cache size", caches.strictSubtype);
      if (isPerformanceEnabled) {
        forEachMeasure((name, duration) => {
          if (!isSolutionMarkOrMeasure(name)) reportTimeStatistic(
            `${name} time`,
            duration,
            /*aggregate*/
            true
          );
        });
      }
    } else if (isPerformanceEnabled) {
      reportTimeStatistic(
        "I/O read",
        getDuration("I/O Read"),
        /*aggregate*/
        true
      );
      reportTimeStatistic(
        "I/O write",
        getDuration("I/O Write"),
        /*aggregate*/
        true
      );
      reportTimeStatistic(
        "Parse time",
        programTime,
        /*aggregate*/
        true
      );
      reportTimeStatistic(
        "Bind time",
        bindTime,
        /*aggregate*/
        true
      );
      reportTimeStatistic(
        "Check time",
        checkTime,
        /*aggregate*/
        true
      );
      reportTimeStatistic(
        "Emit time",
        emitTime,
        /*aggregate*/
        true
      );
    }
    if (isPerformanceEnabled) {
      reportTimeStatistic(
        "Total time",
        programTime + bindTime + checkTime + emitTime,
        /*aggregate*/
        false
      );
    }
    reportAllStatistics(sys2, statistics);
    if (!isPerformanceEnabled) {
      sys2.write(Diagnostics.Performance_timings_for_diagnostics_or_extendedDiagnostics_are_not_available_in_this_session_A_native_implementation_of_the_Web_Performance_API_could_not_be_found.message + "\n");
    } else {
      if (solutionPerformance) {
        forEachMeasure((name) => {
          if (!isSolutionMarkOrMeasure(name)) clearMeasures(name);
        });
        forEachMark((name) => {
          if (!isSolutionMarkOrMeasure(name)) clearMarks(name);
        });
      } else {
        disable();
      }
    }
  }
  function reportStatisticalValue(s, aggregate) {
    statistics.push(s);
    if (aggregate) solutionPerformance == null ? void 0 : solutionPerformance.addAggregateStatistic(s);
  }
  function reportCountStatistic(name, count) {
    reportStatisticalValue(
      { name, value: count, type: 1 /* count */ },
      /*aggregate*/
      true
    );
  }
  function reportTimeStatistic(name, time, aggregate) {
    reportStatisticalValue({ name, value: time, type: 0 /* time */ }, aggregate);
  }
}
function reportAllStatistics(sys2, statistics) {
  let nameSize = 0;
  let valueSize = 0;
  for (const s of statistics) {
    if (s.name.length > nameSize) {
      nameSize = s.name.length;
    }
    const value = statisticValue(s);
    if (value.length > valueSize) {
      valueSize = value.length;
    }
  }
  for (const s of statistics) {
    sys2.write(`${s.name}:`.padEnd(nameSize + 2) + statisticValue(s).toString().padStart(valueSize) + sys2.newLine);
  }
}
function statisticValue(s) {
  switch (s.type) {
    case 1 /* count */:
      return "" + s.value;
    case 0 /* time */:
      return (s.value / 1e3).toFixed(2) + "s";
    case 2 /* memory */:
      return Math.round(s.value / 1e3) + "K";
    default:
      Debug.assertNever(s.type);
  }
}
function writeConfigFile(sys2, reportDiagnostic, options, fileNames) {
  const currentDirectory = sys2.getCurrentDirectory();
  const file = normalizePath(combinePaths(currentDirectory, "tsconfig.json"));
  if (sys2.fileExists(file)) {
    reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file));
  } else {
    sys2.writeFile(file, generateTSConfig(options, fileNames, sys2.newLine));
    const output = [sys2.newLine, ...getHeader(sys2, "Created a new tsconfig.json with:")];
    output.push(getCompilerOptionsDiffValue(options, sys2.newLine) + sys2.newLine + sys2.newLine);
    output.push(`You can learn more at https://aka.ms/tsconfig` + sys2.newLine);
    for (const line of output) {
      sys2.write(line);
    }
  }
  return;
}

// src/compiler/expressionToTypeNode.ts
function createSyntacticTypeNodeBuilder(options, resolver) {
  const strictNullChecks = getStrictOptionValue(options, "strictNullChecks");
  return {
    typeFromExpression,
    serializeTypeOfDeclaration,
    serializeReturnTypeForSignature,
    serializeTypeOfExpression
  };
  function serializeExistingTypeAnnotation(type, addUndefined) {
    return type !== void 0 && (!addUndefined || type && canAddUndefined(type)) ? true : void 0;
  }
  function serializeTypeOfExpression(expr, context, addUndefined, preserveLiterals) {
    return typeFromExpression(
      expr,
      context,
      /*isConstContext*/
      false,
      addUndefined,
      preserveLiterals
    ) ?? inferExpressionType(expr, context);
  }
  function serializeTypeOfDeclaration(node, context) {
    switch (node.kind) {
      case 171 /* PropertySignature */:
        return serializeExistingTypeAnnotation(getEffectiveTypeAnnotationNode(node));
      case 169 /* Parameter */:
        return typeFromParameter(node, context);
      case 260 /* VariableDeclaration */:
        return typeFromVariable(node, context);
      case 172 /* PropertyDeclaration */:
        return typeFromProperty(node, context);
      case 208 /* BindingElement */:
        return inferTypeOfDeclaration(node, context);
      case 277 /* ExportAssignment */:
        return serializeTypeOfExpression(
          node.expression,
          context,
          /*addUndefined*/
          void 0,
          /*preserveLiterals*/
          true
        );
      case 211 /* PropertyAccessExpression */:
      case 212 /* ElementAccessExpression */:
      case 226 /* BinaryExpression */:
        return serializeExistingTypeAnnotation(getEffectiveTypeAnnotationNode(node)) || inferTypeOfDeclaration(node, context);
      case 303 /* PropertyAssignment */:
        return typeFromExpression(node.initializer, context) || inferTypeOfDeclaration(node, context);
      default:
        Debug.assertNever(node, `Node needs to be an inferrable node, found ${Debug.formatSyntaxKind(node.kind)}`);
    }
  }
  function serializeReturnTypeForSignature(node, context) {
    switch (node.kind) {
      case 177 /* GetAccessor */:
        return typeFromAccessor(node, context);
      case 174 /* MethodDeclaration */:
      case 262 /* FunctionDeclaration */:
      case 180 /* ConstructSignature */:
      case 173 /* MethodSignature */:
      case 179 /* CallSignature */:
      case 176 /* Constructor */:
      case 178 /* SetAccessor */:
      case 181 /* IndexSignature */:
      case 184 /* FunctionType */:
      case 185 /* ConstructorType */:
      case 218 /* FunctionExpression */:
      case 219 /* ArrowFunction */:
      case 317 /* JSDocFunctionType */:
      case 323 /* JSDocSignature */:
        return createReturnFromSignature(node, context);
      default:
        Debug.assertNever(node, `Node needs to be an inferrable node, found ${Debug.formatSyntaxKind(node.kind)}`);
    }
  }
  function getTypeAnnotationFromAccessor2(accessor) {
    if (accessor) {
      return accessor.kind === 177 /* GetAccessor */ ? getEffectiveReturnTypeNode(accessor) : accessor.parameters.length > 0 ? getEffectiveTypeAnnotationNode(accessor.parameters[0]) : void 0;
    }
  }
  function getTypeAnnotationFromAllAccessorDeclarations(node, accessors) {
    let accessorType = getTypeAnnotationFromAccessor2(node);
    if (!accessorType && node !== accessors.firstAccessor) {
      accessorType = getTypeAnnotationFromAccessor2(accessors.firstAccessor);
    }
    if (!accessorType && accessors.secondAccessor && node !== accessors.secondAccessor) {
      accessorType = getTypeAnnotationFromAccessor2(accessors.secondAccessor);
    }
    return accessorType;
  }
  function typeFromAccessor(node, context) {
    const accessorDeclarations = resolver.getAllAccessorDeclarations(node);
    const accessorType = getTypeAnnotationFromAllAccessorDeclarations(node, accessorDeclarations);
    if (accessorType) {
      return serializeExistingTypeAnnotation(accessorType);
    }
    if (accessorDeclarations.getAccessor) {
      return createReturnFromSignature(accessorDeclarations.getAccessor, context);
    }
    return false;
  }
  function typeFromVariable(node, context) {
    const declaredType = getEffectiveTypeAnnotationNode(node);
    if (declaredType) {
      return serializeExistingTypeAnnotation(declaredType);
    }
    let resultType;
    if (node.initializer) {
      if (!resolver.isExpandoFunctionDeclaration(node)) {
        resultType = typeFromExpression(
          node.initializer,
          context,
          /*isConstContext*/
          void 0,
          /*requiresAddingUndefined*/
          void 0,
          isVarConstLike(node)
        );
      }
    }
    return resultType ?? inferTypeOfDeclaration(node, context);
  }
  function typeFromParameter(node, context) {
    const parent = node.parent;
    if (parent.kind === 178 /* SetAccessor */) {
      return typeFromAccessor(parent, context);
    }
    const declaredType = getEffectiveTypeAnnotationNode(node);
    const addUndefined = resolver.requiresAddingImplicitUndefined(node);
    let resultType;
    if (declaredType) {
      resultType = serializeExistingTypeAnnotation(declaredType, addUndefined);
    } else {
      if (node.initializer && isIdentifier(node.name)) {
        resultType = typeFromExpression(
          node.initializer,
          context,
          /*isConstContext*/
          void 0,
          addUndefined
        );
      }
    }
    return resultType ?? inferTypeOfDeclaration(node, context);
  }
  function typeFromProperty(node, context) {
    const declaredType = getEffectiveTypeAnnotationNode(node);
    if (declaredType) {
      return serializeExistingTypeAnnotation(declaredType);
    }
    let resultType;
    if (node.initializer) {
      const isReadonly = isDeclarationReadonly(node);
      resultType = typeFromExpression(
        node.initializer,
        context,
        /*isConstContext*/
        void 0,
        /*requiresAddingUndefined*/
        void 0,
        isReadonly
      );
    }
    return resultType ?? inferTypeOfDeclaration(node, context);
  }
  function inferTypeOfDeclaration(node, context) {
    context.tracker.reportInferenceFallback(node);
    return false;
  }
  function inferExpressionType(node, context) {
    context.tracker.reportInferenceFallback(node);
    return false;
  }
  function inferReturnTypeOfSignatureSignature(node, context) {
    context.tracker.reportInferenceFallback(node);
    return false;
  }
  function inferAccessorType(node, allAccessors, context) {
    if (node.kind === 177 /* GetAccessor */) {
      return createReturnFromSignature(node, context);
    } else {
      context.tracker.reportInferenceFallback(node);
      return false;
    }
  }
  function typeFromTypeAssertion(expression, type, context, requiresAddingUndefined) {
    if (isConstTypeReference(type)) {
      return typeFromExpression(
        expression,
        context,
        /*isConstContext*/
        true,
        requiresAddingUndefined
      );
    }
    if (requiresAddingUndefined && !canAddUndefined(type)) {
      context.tracker.reportInferenceFallback(type);
    }
    return serializeExistingTypeAnnotation(type);
  }
  function typeFromExpression(node, context, isConstContext = false, requiresAddingUndefined = false, preserveLiterals = false) {
    switch (node.kind) {
      case 217 /* ParenthesizedExpression */:
        if (isJSDocTypeAssertion(node)) {
          return typeFromTypeAssertion(node.expression, getJSDocTypeAssertionType(node), context, requiresAddingUndefined);
        }
        return typeFromExpression(node.expression, context, isConstContext, requiresAddingUndefined);
      case 80 /* Identifier */:
        if (resolver.isUndefinedIdentifierExpression(node)) {
          return true;
        }
        break;
      case 106 /* NullKeyword */:
        return true;
      case 219 /* ArrowFunction */:
      case 218 /* FunctionExpression */:
        return typeFromFunctionLikeExpression(node, context);
      case 216 /* TypeAssertionExpression */:
      case 234 /* AsExpression */:
        const asExpression = node;
        return typeFromTypeAssertion(asExpression.expression, asExpression.type, context, requiresAddingUndefined);
      case 224 /* PrefixUnaryExpression */:
        const unaryExpression = node;
        if (isPrimitiveLiteralValue(unaryExpression)) {
          if (unaryExpression.operand.kind === 10 /* BigIntLiteral */) {
            return typeFromPrimitiveLiteral();
          }
          if (unaryExpression.operand.kind === 9 /* NumericLiteral */) {
            return typeFromPrimitiveLiteral();
          }
        }
        break;
      case 9 /* NumericLiteral */:
        return typeFromPrimitiveLiteral();
      case 228 /* TemplateExpression */:
        if (!isConstContext && !preserveLiterals) {
          return true;
        }
        break;
      case 15 /* NoSubstitutionTemplateLiteral */:
      case 11 /* StringLiteral */:
        return typeFromPrimitiveLiteral();
      case 10 /* BigIntLiteral */:
        return typeFromPrimitiveLiteral();
      case 112 /* TrueKeyword */:
      case 97 /* FalseKeyword */:
        return typeFromPrimitiveLiteral();
      case 209 /* ArrayLiteralExpression */:
        return typeFromArrayLiteral(node, context, isConstContext);
      case 210 /* ObjectLiteralExpression */:
        return typeFromObjectLiteral(node, context, isConstContext);
      case 231 /* ClassExpression */:
        return inferExpressionType(node, context);
    }
    return void 0;
  }
  function typeFromFunctionLikeExpression(fnNode, context) {
    const returnType = serializeExistingTypeAnnotation(fnNode.type) ?? createReturnFromSignature(fnNode, context);
    const typeParameters = reuseTypeParameters(fnNode.typeParameters);
    const parameters = fnNode.parameters.every((p) => ensureParameter(p, context));
    return returnType && typeParameters && parameters;
  }
  function canGetTypeFromArrayLiteral(arrayLiteral, context, isConstContext) {
    if (!isConstContext) {
      context.tracker.reportInferenceFallback(arrayLiteral);
      return false;
    }
    for (const element of arrayLiteral.elements) {
      if (element.kind === 230 /* SpreadElement */) {
        context.tracker.reportInferenceFallback(element);
        return false;
      }
    }
    return true;
  }
  function typeFromArrayLiteral(arrayLiteral, context, isConstContext) {
    if (!canGetTypeFromArrayLiteral(arrayLiteral, context, isConstContext)) {
      return false;
    }
    let canInferArray = true;
    for (const element of arrayLiteral.elements) {
      Debug.assert(element.kind !== 230 /* SpreadElement */);
      if (element.kind !== 232 /* OmittedExpression */) {
        canInferArray = (typeFromExpression(element, context, isConstContext) ?? inferExpressionType(element, context)) && canInferArray;
      }
    }
    return true;
  }
  function canGetTypeFromObjectLiteral(objectLiteral, context) {
    let result = true;
    for (const prop of objectLiteral.properties) {
      if (prop.flags & 262144 /* ThisNodeHasError */) {
        result = false;
        break;
      }
      if (prop.kind === 304 /* ShorthandPropertyAssignment */ || prop.kind === 305 /* SpreadAssignment */) {
        context.tracker.reportInferenceFallback(prop);
        result = false;
      } else if (prop.name.flags & 262144 /* ThisNodeHasError */) {
        result = false;
        break;
      } else if (prop.name.kind === 81 /* PrivateIdentifier */) {
        result = false;
      } else if (prop.name.kind === 167 /* ComputedPropertyName */) {
        const expression = prop.name.expression;
        if (!isPrimitiveLiteralValue(
          expression,
          /*includeBigInt*/
          false
        ) && !resolver.isDefinitelyReferenceToGlobalSymbolObject(expression)) {
          context.tracker.reportInferenceFallback(prop.name);
          result = false;
        }
      }
    }
    return result;
  }
  function typeFromObjectLiteral(objectLiteral, context, isConstContext) {
    if (!canGetTypeFromObjectLiteral(objectLiteral, context)) return false;
    let canInferObjectLiteral = true;
    for (const prop of objectLiteral.properties) {
      Debug.assert(!isShorthandPropertyAssignment(prop) && !isSpreadAssignment(prop));
      const name = prop.name;
      switch (prop.kind) {
        case 174 /* MethodDeclaration */:
          canInferObjectLiteral = !!typeFromObjectLiteralMethod(prop, name, context) && canInferObjectLiteral;
          break;
        case 303 /* PropertyAssignment */:
          canInferObjectLiteral = !!typeFromObjectLiteralPropertyAssignment(prop, name, context, isConstContext) && canInferObjectLiteral;
          break;
        case 178 /* SetAccessor */:
        case 177 /* GetAccessor */:
          canInferObjectLiteral = !!typeFromObjectLiteralAccessor(prop, name, context) && canInferObjectLiteral;
          break;
      }
    }
    return canInferObjectLiteral;
  }
  function typeFromObjectLiteralPropertyAssignment(prop, name, context, isConstContext) {
    return typeFromExpression(prop.initializer, context, isConstContext) ?? inferTypeOfDeclaration(prop, context);
  }
  function ensureParameter(p, context) {
    return typeFromParameter(p, context);
  }
  function reuseTypeParameters(typeParameters) {
    return (typeParameters == null ? void 0 : typeParameters.every(
      (tp) => serializeExistingTypeAnnotation(tp.constraint) && serializeExistingTypeAnnotation(tp.default)
    )) ?? true;
  }
  function typeFromObjectLiteralMethod(method, name, context) {
    const returnType = createReturnFromSignature(method, context);
    const typeParameters = reuseTypeParameters(method.typeParameters);
    const parameters = method.parameters.every((p) => ensureParameter(p, context));
    return returnType && typeParameters && parameters;
  }
  function typeFromObjectLiteralAccessor(accessor, name, context) {
    const allAccessors = resolver.getAllAccessorDeclarations(accessor);
    const getAccessorType = allAccessors.getAccessor && getTypeAnnotationFromAccessor2(allAccessors.getAccessor);
    const setAccessorType = allAccessors.setAccessor && getTypeAnnotationFromAccessor2(allAccessors.setAccessor);
    if (getAccessorType !== void 0 && setAccessorType !== void 0) {
      const parameters = accessor.parameters.every((p) => ensureParameter(p, context));
      if (isGetAccessor(accessor)) {
        return parameters && serializeExistingTypeAnnotation(getAccessorType);
      } else {
        return parameters;
      }
    } else if (allAccessors.firstAccessor === accessor) {
      const foundType = getAccessorType ?? setAccessorType;
      const propertyType = foundType ? serializeExistingTypeAnnotation(foundType) : inferAccessorType(accessor, allAccessors, context);
      return propertyType;
    }
    return false;
  }
  function typeFromPrimitiveLiteral() {
    return true;
  }
  function canAddUndefined(node) {
    if (!strictNullChecks) return true;
    if (isKeyword(node.kind) || node.kind === 201 /* LiteralType */ || node.kind === 184 /* FunctionType */ || node.kind === 185 /* ConstructorType */ || node.kind === 188 /* ArrayType */ || node.kind === 189 /* TupleType */ || node.kind === 187 /* TypeLiteral */ || node.kind === 203 /* TemplateLiteralType */ || node.kind === 197 /* ThisType */) {
      return true;
    }
    if (node.kind === 196 /* ParenthesizedType */) {
      return canAddUndefined(node.type);
    }
    if (node.kind === 192 /* UnionType */ || node.kind === 193 /* IntersectionType */) {
      return node.types.every(canAddUndefined);
    }
    return false;
  }
  function createReturnFromSignature(fn, context) {
    let returnType;
    const returnTypeNode = getEffectiveReturnTypeNode(fn);
    if (returnTypeNode) {
      returnType = serializeExistingTypeAnnotation(returnTypeNode);
    }
    if (!returnType && isValueSignatureDeclaration(fn)) {
      returnType = typeFromSingleReturnExpression(fn, context);
    }
    return returnType ?? inferReturnTypeOfSignatureSignature(fn, context);
  }
  function typeFromSingleReturnExpression(declaration, context) {
    let candidateExpr;
    if (declaration && !nodeIsMissing(declaration.body)) {
      if (getFunctionFlags(declaration) & 3 /* AsyncGenerator */) return void 0;
      const body = declaration.body;
      if (body && isBlock(body)) {
        forEachReturnStatement(body, (s) => {
          if (!candidateExpr) {
            candidateExpr = s.expression;
          } else {
            candidateExpr = void 0;
            return true;
          }
        });
      } else {
        candidateExpr = body;
      }
    }
    if (candidateExpr) {
      return typeFromExpression(candidateExpr, context);
    }
    return void 0;
  }
}

// src/tsc/tsc.ts
Debug.loggingHost = {
  log(_level, s) {
    sys.write(`${s || ""}${sys.newLine}`);
  }
};
if (Debug.isDebugging) {
  Debug.enableDebugInfo();
}
if (sys.tryEnableSourceMapsForHost && /^development$/i.test(sys.getEnvironmentVariable("NODE_ENV"))) {
  sys.tryEnableSourceMapsForHost();
}
if (sys.setBlocking) {
  sys.setBlocking();
}
executeCommandLine(sys, noop, sys.args);
//# sourceMappingURL=tsc.js.map
