{"version":3,"file":"index.cjs","names":["createDiagnosticMessage","defaultTimeout","ApiError","API_VERSION","API_VERSION","hashSource","decode","encode","encode","defaultTimeout","LocaleConfig","_API_VERSION"],"sources":["../src/logging/errors.ts","../src/logging/logger.ts","../src/translate/utils/fetchWithTimeout.ts","../src/translate/utils/validateResponse.ts","../src/translate/utils/handleFetchError.ts","../src/translate/api.ts","../src/translate/utils/generateRequestHeaders.ts","../src/translate/utils/apiRequest.ts","../src/translate/translateMany.ts","../src/translate/setupProject.ts","../src/translate/utils/batch.ts","../src/translate/enqueueFiles.ts","../src/translate/createTag.ts","../src/translate/downloadFileBatch.ts","../src/translate/submitUserEditDiffs.ts","../src/translate/uploadSourceFiles.ts","../src/translate/uploadTranslations.ts","../src/translate/querySourceFile.ts","../src/projects/getProjectData.ts","../src/translate/checkJobStatus.ts","../src/translate/awaitJobs.ts","../src/translate/queryFileData.ts","../src/translate/queryBranchData.ts","../src/translate/createBranch.ts","../src/translate/processFileMoves.ts","../src/translate/getOrphanedFiles.ts","../src/translate/publishFiles.ts","../src/index.ts"],"sourcesContent":["import { createDiagnosticMessage } from './diagnostics';\n\nconst GT_SOURCE = 'GT';\n\nexport const translationTimeoutError = (timeout: number) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `Translation request timed out after ${timeout}ms`,\n    fix: 'Try again, or increase the request timeout if the source content is large',\n  });\n\nexport const translationRequestFailedError = (error: string) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: 'Translation request could not be completed',\n    fix: 'Check your network connection and translation credentials, then try again',\n    details: error,\n  });\n\nexport const apiError = (status: number, statusText: string, error: string) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `The translation API returned ${status} ${statusText}`,\n    fix: 'Check the request configuration and try again',\n    details: error,\n  });\n\nexport const invalidAuthError = createDiagnosticMessage({\n  source: GT_SOURCE,\n  severity: 'Error',\n  whatHappened: 'Authentication failed',\n  fix: 'Check that your API key and project ID are correct',\n});\n\nexport const noTargetLocaleProvidedError = (functionName: string) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `Cannot call \\`${functionName}\\` without a specified locale`,\n    fix: `Pass a locale to \\`${functionName}\\` or specify targetLocale in the GT constructor`,\n  });\n\nexport const noSourceLocaleProvidedError = (functionName: string) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `Cannot call \\`${functionName}\\` without a specified locale`,\n    fix: `Pass a locale to \\`${functionName}\\` or specify sourceLocale in the GT constructor`,\n  });\n\nexport const noProjectIdProvidedError = (functionName: string) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `Cannot call \\`${functionName}\\` without a specified project ID`,\n    fix: `Pass a project ID to \\`${functionName}\\` or specify projectId in the GT constructor`,\n  });\n\nexport const noApiKeyProvidedError = (functionName: string) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `Cannot call \\`${functionName}\\` without a specified API key`,\n    fix: `Pass an API key to \\`${functionName}\\` or specify apiKey in the GT constructor`,\n  });\n\nexport const invalidLocaleError = (locale: string) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `Locale \"${locale}\" is not valid`,\n    fix: 'Use a valid BCP 47 locale code or add a custom mapping',\n  });\n\nexport const invalidLocalesError = (locales: string[]) =>\n  createDiagnosticMessage({\n    source: GT_SOURCE,\n    severity: 'Error',\n    whatHappened: `These locales are not valid: ${locales.join(', ')}`,\n    fix: 'Use valid BCP 47 locale codes or add custom mappings',\n  });\n","/**\n * Comprehensive logging system for the General Translation library.\n * Provides structured logging with multiple levels and configurable output.\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'off';\n\nexport type LogMetadataValue =\n  | string\n  | number\n  | boolean\n  | null\n  | undefined\n  | Date\n  | Error\n  | LogMetadataValue[]\n  | { [key: string]: LogMetadataValue };\n\nexport type LogMetadata = Record<string, LogMetadataValue>;\n\nexport interface LogEntry {\n  level: LogLevel;\n  message: string;\n  timestamp: Date;\n  context?: string;\n  metadata?: LogMetadata;\n}\n\nexport interface LoggerConfig {\n  /** Minimum log level to output. */\n  level: LogLevel;\n  /** Whether to include timestamps in log output. */\n  includeTimestamp: boolean;\n  /** Whether to include context information. */\n  includeContext: boolean;\n  /** Custom prefix for all log messages. */\n  prefix?: string;\n  /** Whether to output to console (default: true) */\n  enableConsole: boolean;\n  /** Custom log handlers. */\n  handlers?: LogHandler[];\n}\n\nexport interface LogHandler {\n  handle(entry: LogEntry): void;\n}\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n  debug: 0,\n  info: 1,\n  warn: 2,\n  error: 3,\n  off: 4,\n};\n\nconst LOG_COLORS: Record<LogLevel, string> = {\n  debug: '\\x1b[36m', // Cyan\n  info: '\\x1b[32m', // Green\n  warn: '\\x1b[33m', // Yellow\n  error: '\\x1b[31m', // Red\n  off: '', // No color needed since 'off' level logs are never displayed\n};\n\nconst RESET_COLOR = '\\x1b[0m';\n\n/**\n * Get the configured log level from environment variable or default to 'warn'\n */\nfunction getConfiguredLogLevel(): LogLevel {\n  if (typeof process !== 'undefined' && process.env?._GT_LOG_LEVEL) {\n    const envLevel = process.env._GT_LOG_LEVEL.toLowerCase();\n    if (envLevel in LOG_LEVELS) {\n      return envLevel as LogLevel;\n    }\n  }\n  return 'warn';\n}\n\n/**\n * Console log handler that outputs formatted messages to console\n */\nexport class ConsoleLogHandler implements LogHandler {\n  private config: LoggerConfig;\n\n  constructor(config: LoggerConfig) {\n    this.config = config;\n  }\n\n  handle(entry: LogEntry): void {\n    const parts: string[] = [];\n\n    // Add timestamp if enabled\n    if (this.config.includeTimestamp) {\n      parts.push(`[${entry.timestamp.toISOString()}]`);\n    }\n\n    // Add level with color\n    const colorCode = LOG_COLORS[entry.level];\n    const levelText = `[${entry.level.toUpperCase()}]`;\n    parts.push(`${colorCode}${levelText}${RESET_COLOR}`);\n\n    // Add prefix if configured\n    if (this.config.prefix) {\n      parts.push(`[${this.config.prefix}]`);\n    }\n\n    // Add context if available and enabled.\n    if (this.config.includeContext && entry.context) {\n      parts.push(`[${entry.context}]`);\n    }\n\n    // Add the main message\n    parts.push(entry.message);\n\n    // Format metadata if available.\n    if (entry.metadata && Object.keys(entry.metadata).length > 0) {\n      parts.push(`\\n  Metadata: ${JSON.stringify(entry.metadata, null, 2)}`);\n    }\n\n    const formattedMessage = parts.join(' ');\n\n    // Output to appropriate console method based on level\n    switch (entry.level) {\n      case 'debug':\n        // eslint-disable-next-line no-console\n        console.debug(formattedMessage);\n        break;\n      case 'info':\n        // eslint-disable-next-line no-console\n        console.info(formattedMessage);\n        break;\n      case 'warn':\n        console.warn(formattedMessage);\n        break;\n      case 'error':\n        console.error(formattedMessage);\n        break;\n    }\n  }\n}\n\n/**\n * Main Logger class providing structured logging capabilities.\n */\nexport class Logger {\n  private config: LoggerConfig;\n  private handlers: LogHandler[];\n\n  constructor(config: Partial<LoggerConfig> = {}) {\n    this.config = {\n      level: getConfiguredLogLevel(),\n      includeTimestamp: true,\n      includeContext: true,\n      enableConsole: true,\n      handlers: [],\n      ...config,\n    };\n\n    this.handlers = [...(this.config.handlers || [])];\n\n    // Add console handler if enabled\n    if (this.config.enableConsole) {\n      this.handlers.push(new ConsoleLogHandler(this.config));\n    }\n  }\n\n  /**\n   * Add a custom log handler\n   */\n  addHandler(handler: LogHandler): void {\n    this.handlers.push(handler);\n  }\n\n  /**\n   * Remove a log handler\n   */\n  removeHandler(handler: LogHandler): void {\n    const index = this.handlers.indexOf(handler);\n    if (index > -1) {\n      this.handlers.splice(index, 1);\n    }\n  }\n\n  /**\n   * Update logger configuration\n   */\n  configure(config: Partial<LoggerConfig>): void {\n    this.config = { ...this.config, ...config };\n  }\n\n  /**\n   * Check if a log level should be output based on current configuration\n   */\n  private shouldLog(level: LogLevel): boolean {\n    return LOG_LEVELS[level] >= LOG_LEVELS[this.config.level];\n  }\n\n  /**\n   * Internal logging method that creates log entries and passes them to handlers\n   */\n  private log(\n    level: LogLevel,\n    message: string,\n    context?: string,\n    metadata?: LogMetadata\n  ): void {\n    if (!this.shouldLog(level)) {\n      return;\n    }\n\n    const entry: LogEntry = {\n      level,\n      message,\n      timestamp: new Date(),\n      context,\n      metadata,\n    };\n\n    // Pass to all handlers\n    this.handlers.forEach((handler) => {\n      try {\n        handler.handle(entry);\n      } catch (error) {\n        // Prevent logging errors from breaking the application\n        console.error('Error in log handler:', error);\n      }\n    });\n  }\n\n  /**\n   * Log a debug message\n   * Used for detailed diagnostic information, typically of interest only when diagnosing problems\n   */\n  debug(message: string, context?: string, metadata?: LogMetadata): void {\n    this.log('debug', message, context, metadata);\n  }\n\n  /**\n   * Log an info message\n   * Used for general information about application operation.\n   */\n  info(message: string, context?: string, metadata?: LogMetadata): void {\n    this.log('info', message, context, metadata);\n  }\n\n  /**\n   * Log a warning message\n   * Used for potentially problematic situations that don't prevent operation\n   */\n  warn(message: string, context?: string, metadata?: LogMetadata): void {\n    this.log('warn', message, context, metadata);\n  }\n\n  /**\n   * Log an error message\n   * Used for error events that might still allow the application to continue.\n   */\n  error(message: string, context?: string, metadata?: LogMetadata): void {\n    this.log('error', message, context, metadata);\n  }\n\n  /**\n   * Create a child logger with a specific context\n   */\n  child(context: string): ContextLogger {\n    return new ContextLogger(this, context);\n  }\n\n  /**\n   * Get current logger configuration\n   */\n  getConfig(): LoggerConfig {\n    return { ...this.config };\n  }\n}\n\n/**\n * Context logger that automatically includes context information.\n */\nexport class ContextLogger {\n  private logger: Logger;\n  private context: string;\n\n  constructor(logger: Logger, context: string) {\n    this.logger = logger;\n    this.context = context;\n  }\n\n  debug(message: string, metadata?: LogMetadata): void {\n    this.logger.debug(message, this.context, metadata);\n  }\n\n  info(message: string, metadata?: LogMetadata): void {\n    this.logger.info(message, this.context, metadata);\n  }\n\n  warn(message: string, metadata?: LogMetadata): void {\n    this.logger.warn(message, this.context, metadata);\n  }\n\n  error(message: string, metadata?: LogMetadata): void {\n    this.logger.error(message, this.context, metadata);\n  }\n\n  child(childContext: string): ContextLogger {\n    return new ContextLogger(this.logger, `${this.context}:${childContext}`);\n  }\n}\n\n// Default logger instance.\nexport const defaultLogger = new Logger({\n  level: getConfiguredLogLevel(),\n  includeTimestamp: true,\n  includeContext: true,\n  prefix: 'GT',\n});\n\n// Convenience functions using the default logger.\nexport const debug = (\n  message: string,\n  context?: string,\n  metadata?: LogMetadata\n) => defaultLogger.debug(message, context, metadata);\n\nexport const info = (\n  message: string,\n  context?: string,\n  metadata?: LogMetadata\n) => defaultLogger.info(message, context, metadata);\n\nexport const warn = (\n  message: string,\n  context?: string,\n  metadata?: LogMetadata\n) => defaultLogger.warn(message, context, metadata);\n\nexport const error = (\n  message: string,\n  context?: string,\n  metadata?: LogMetadata\n) => defaultLogger.error(message, context, metadata);\n\n// Create context-specific loggers for different parts of the system\nexport const fetchLogger = defaultLogger.child('fetch');\nexport const gtInstanceLogger = defaultLogger.child('GT instance');\n\n// Export types and classes\nexport { Logger as GTLogger };\n","import { translationTimeoutError } from '../../logging/errors';\nimport { defaultTimeout } from '../../settings/settings';\n\n/**\n * @internal\n *\n * Wraps the fetch function with a timeout.\n *\n * @param url - The URL to fetch.\n * @param options - The options to pass to the fetch function.\n * @param timeout - The timeout in milliseconds.\n * @returns The response from the fetch function.\n */\nexport default async function fetchWithTimeout(\n  url: string | URL | globalThis.Request,\n  options: RequestInit,\n  timeout?: number\n) {\n  const controller = new AbortController();\n  const signal = controller.signal;\n\n  timeout = timeout ? timeout : defaultTimeout;\n  const timeoutId = timeout\n    ? setTimeout(() => controller.abort(), timeout)\n    : null;\n\n  try {\n    const response = await fetch(url, { ...options, signal });\n    return response;\n  } catch (error) {\n    if (error instanceof Error && error.name === 'AbortError') {\n      throw translationTimeoutError(timeout);\n    }\n    throw error;\n  } finally {\n    if (timeoutId) clearTimeout(timeoutId);\n  }\n}\n","import { apiError } from '../../logging/errors';\nimport { ApiError } from '../../errors/ApiError';\n\nexport default async function validateResponse(response: Response) {\n  if (!response.ok) {\n    let errorMsg = 'Unknown error';\n    try {\n      const text = await response.text();\n      try {\n        const errorJson = JSON.parse(text) as { error: string };\n        errorMsg = errorJson.error;\n      } catch {\n        errorMsg = text || 'Unknown error';\n      }\n    } catch {\n      // response.text() failed, keep 'Unknown error'\n    }\n    const errorMessage = apiError(\n      response.status,\n      response.statusText,\n      errorMsg\n    );\n    const error = new ApiError(errorMessage, response.status, errorMsg);\n    throw error;\n  }\n}\n","import { fetchLogger } from '../../logging/logger';\nimport {\n  translationRequestFailedError,\n  translationTimeoutError,\n} from '../../logging/errors';\n\nexport default function handleFetchError(\n  error: unknown,\n  timeout: number\n): never {\n  if (error instanceof Error && error.name === 'AbortError') {\n    const errorMessage = translationTimeoutError(timeout);\n    fetchLogger.error(errorMessage);\n    throw new Error(errorMessage);\n  }\n  const errorMessage = translationRequestFailedError(\n    error instanceof Error ? error.message : String(error)\n  );\n  fetchLogger.error(errorMessage);\n  throw error;\n}\n","export const API_VERSION = '2026-03-06.v1';\n","import { TranslationRequestConfig } from '../../types';\nimport { API_VERSION } from '../api';\n\nexport default function generateRequestHeaders(\n  config: TranslationRequestConfig,\n  excludeContentType = false\n) {\n  const authHeaders: Record<string, string> = {\n    ...(!excludeContentType && { 'Content-Type': 'application/json' }),\n    'x-gt-project-id': config.projectId,\n  };\n\n  if (config.apiKey) {\n    if (config.apiKey.startsWith('gtx-internal-')) {\n      authHeaders['x-gt-internal-api-key'] = config.apiKey;\n    } else {\n      authHeaders['x-gt-api-key'] = config.apiKey;\n    }\n  }\n\n  authHeaders['gt-api-version'] = API_VERSION;\n\n  return authHeaders;\n}\n","import { TranslationRequestConfig } from '../../types';\nimport { defaultBaseUrl } from '../../settings/settingsUrls';\nimport { defaultTimeout } from '../../settings/settings';\nimport fetchWithTimeout from './fetchWithTimeout';\nimport validateResponse from './validateResponse';\nimport handleFetchError from './handleFetchError';\nimport generateRequestHeaders from './generateRequestHeaders';\n\nconst MAX_RETRIES = 3;\nconst INITIAL_DELAY_MS = 500;\n\ntype RetryPolicy = 'exponential' | 'linear' | 'none';\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction getRetryDelay(policy: RetryPolicy, attempt: number): number {\n  switch (policy) {\n    case 'linear':\n      return INITIAL_DELAY_MS * (attempt + 1);\n    case 'exponential':\n      return INITIAL_DELAY_MS * 2 ** attempt;\n    default:\n      return 0;\n  }\n}\n\n/**\n * @internal\n *\n * Makes an API request with automatic retry for 5XX errors.\n *\n * Encapsulates URL construction, fetch with timeout, error handling,\n * response validation, and JSON parsing.\n *\n * @param config - The configuration for the API call.\n * @param endpoint - The API endpoint path (e.g. '/v2/project/jobs/info')\n * @param options - Optional request options.\n * @returns The parsed JSON response.\n */\nexport default async function apiRequest<T>(\n  config: TranslationRequestConfig,\n  endpoint: string,\n  options?: {\n    body?: unknown;\n    timeout?: number;\n    method?: 'GET' | 'POST';\n    retryPolicy?: RetryPolicy;\n  }\n): Promise<T> {\n  const timeout = options?.timeout ?? defaultTimeout;\n  const url = `${config.baseUrl || defaultBaseUrl}${endpoint}`;\n  const method = options?.method ?? 'POST';\n  const retryPolicy = options?.retryPolicy ?? 'exponential';\n  const maxRetries = retryPolicy === 'none' ? 0 : MAX_RETRIES;\n\n  const requestInit: RequestInit = {\n    method,\n    headers: generateRequestHeaders(config),\n  };\n  if (options?.body !== undefined) {\n    requestInit.body = JSON.stringify(options.body);\n  }\n\n  for (let attempt = 0; attempt <= maxRetries; attempt++) {\n    let response: Response;\n    try {\n      response = await fetchWithTimeout(url, requestInit, timeout);\n    } catch (error) {\n      if (attempt < maxRetries) {\n        await sleep(getRetryDelay(retryPolicy, attempt));\n        continue;\n      }\n      handleFetchError(error, timeout);\n    }\n\n    // Retry on 5XX server errors.\n    if (response!.status >= 500 && attempt < maxRetries) {\n      await sleep(getRetryDelay(retryPolicy, attempt));\n      continue;\n    }\n\n    await validateResponse(response!);\n    return (await response!.json()) as T;\n  }\n\n  throw new Error('Max retries exceeded');\n}\n","import {\n  TranslationRequestConfig,\n  TranslateManyResult,\n  TranslationResult,\n} from '../types';\nimport { defaultRuntimeApiUrl } from '../settings/settingsUrls';\nimport {\n  TranslateManyEntry,\n  TranslateOptions,\n  EntryMetadata,\n} from '../types-dir/api/entry';\nimport apiRequest from './utils/apiRequest';\nimport type { Content } from '@generaltranslation/format/types';\nimport { hashSource } from '../id';\n\n/**\n * @internal\n *\n * Translates multiple entries in a single API request for better performance.\n * This function batches multiple translation requests together and sends them\n * to the GT translation API in one call.\n *\n * @param requests - The entries to translate. Can be an array (entries are hashed and results returned in order) or a record keyed by hash (skips hash calculation, returns a record).\n * @param globalMetadata - The metadata for the translation.\n * @param config - The configuration for the translation.\n * @returns The results of the translation. An array if requests was an array, a record if requests was a record.\n */\nexport default async function _translateMany<\n  T extends TranslateManyEntry[] | Record<string, TranslateManyEntry>,\n>(\n  requests: T,\n  globalMetadata: {\n    targetLocale: string;\n    sourceLocale: string;\n  } & TranslateOptions,\n  config: TranslationRequestConfig,\n  timeout?: number\n): Promise<\n  T extends TranslateManyEntry[]\n    ? TranslateManyResult\n    : Record<string, TranslationResult>\n>;\nexport default async function _translateMany(\n  requests: TranslateManyEntry[] | Record<string, TranslateManyEntry>,\n  globalMetadata: {\n    targetLocale: string;\n    sourceLocale: string;\n  } & TranslateOptions,\n  config: TranslationRequestConfig,\n  timeout?: number\n): Promise<TranslateManyResult | Record<string, TranslationResult>> {\n  const isArray = Array.isArray(requests);\n\n  // normalize and map from requests to requests record\n  const hashOrder: string[] | undefined = isArray ? [] : undefined;\n  const requestsObject: Record<\n    string,\n    { source: Content; metadata?: EntryMetadata }\n  > = {};\n\n  const entries: [string | undefined, TranslateManyEntry][] = isArray\n    ? requests.map((r) => [undefined, r])\n    : Object.entries(requests);\n\n  for (const [key, request] of entries) {\n    const normalized =\n      typeof request === 'string' ? { source: request } : request;\n    const { source, metadata } = normalized;\n    const hash =\n      key ??\n      metadata?.hash ??\n      hashSource({\n        source,\n        dataFormat: metadata?.dataFormat ?? 'STRING',\n        ...metadata,\n      });\n    hashOrder?.push(hash);\n    requestsObject[hash] = {\n      source,\n      metadata: metadata,\n    };\n  }\n\n  const response = await apiRequest<Record<string, TranslationResult>>(\n    { ...config, baseUrl: config.baseUrl || defaultRuntimeApiUrl },\n    `/v2/translate`,\n    {\n      body: {\n        requests: requestsObject,\n        targetLocale: globalMetadata.targetLocale,\n        sourceLocale: globalMetadata.sourceLocale,\n        metadata: globalMetadata,\n      },\n      timeout: timeout,\n      retryPolicy: 'none',\n    }\n  );\n\n  // If input was an array, map the record response back to an array in input order\n  if (hashOrder) {\n    return hashOrder.map(\n      (hash) =>\n        response[hash] ?? {\n          success: false,\n          error: 'No translation returned',\n          code: 500,\n        }\n    );\n  }\n\n  // If input was a record, return the record response directly\n  return response;\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport type { FileReference } from '../types-dir/api/file';\n\nexport type SetupProjectResult =\n  | { setupJobId: string; status: 'queued' }\n  | { status: 'completed' };\n\nexport type SetupProjectOptions = {\n  force?: boolean;\n  locales?: string[];\n  timeoutMs?: number;\n};\n\n/**\n * @internal\n * Enqueues files for project setup the General Translation API.\n * @param files - References of files to translate (file content already uploaded)\n * @param config - The configuration for the API call.\n * @param timeoutMS - The timeout in milliseconds\n * @returns The result of the API call.\n */\nexport default async function _setupProject(\n  files: FileReference[],\n  config: TranslationRequestConfig,\n  options?: SetupProjectOptions\n): Promise<SetupProjectResult> {\n  return apiRequest<SetupProjectResult>(config, '/v2/project/setup/generate', {\n    body: {\n      files: files.map((f) => ({\n        branchId: f.branchId,\n        fileId: f.fileId,\n        versionId: f.versionId,\n      })),\n      locales: options?.locales,\n      force: options?.force,\n    },\n    timeout: options?.timeoutMs,\n  });\n}\n","/**\n * Splits an array into batches of a specified size.\n * @param items - The array to split into batches.\n * @param batchSize - The maximum size of each batch.\n * @returns An array of batches.\n */\nexport function createBatches<T>(items: T[], batchSize: number): T[][] {\n  const batches: T[][] = [];\n  for (let i = 0; i < items.length; i += batchSize) {\n    batches.push(items.slice(i, i + batchSize));\n  }\n  return batches;\n}\n\n/**\n * Result of processing batches.\n */\nexport interface BatchList<T> {\n  /** The items successfully processed across all batches */\n  data: T[];\n  /** The total number of items processed */\n  count: number;\n  /** The number of batches processed */\n  batchCount: number;\n}\n\n/**\n * Options for batch processing.\n */\nexport interface BatchProcessOptions {\n  /** Maximum number of items per batch (default: 100) */\n  batchSize?: number;\n  /** Whether to process batches in parallel (default: true) */\n  parallel?: boolean;\n}\n\n/**\n * Processes items in batches using a provided processor function.\n *\n * @param items - The items to process.\n * @param processor - Async function that processes a single batch and returns items.\n * @param options - Optional configuration for batch processing.\n * @returns Promise that resolves to a BatchList containing all processed items.\n *\n * @example\n * ```typescript\n * const result = await processBatches(\n *   files,\n *   async (batch) => {\n *     const response = await uploadFiles(batch);\n *     return response.uploadedFiles;\n *   },\n *   { batchSize: 100 }\n * );\n *\n * console.log(result.data); // All items\n * console.log(result.count); // Total count\n * console.log(result.batchCount); // Number of batches processed\n * ```\n */\nexport async function processBatches<TInput, TOutput>(\n  items: TInput[],\n  processor: (batch: TInput[]) => Promise<TOutput[]>,\n  options: BatchProcessOptions = {}\n): Promise<BatchList<TOutput>> {\n  const { batchSize = 100, parallel = true } = options;\n\n  if (items.length === 0) {\n    return {\n      data: [],\n      count: 0,\n      batchCount: 0,\n    };\n  }\n\n  const batches = createBatches(items, batchSize);\n  const allItems: TOutput[] = [];\n\n  if (parallel) {\n    // Process all batches in parallel.\n    const results = await Promise.all(batches.map((batch) => processor(batch)));\n    for (const result of results) {\n      if (result) {\n        allItems.push(...result);\n      }\n    }\n  } else {\n    // Process batches sequentially.\n    for (const batch of batches) {\n      const result = await processor(batch);\n      if (result) {\n        allItems.push(...result);\n      }\n    }\n  }\n\n  return {\n    data: allItems,\n    count: allItems.length,\n    batchCount: batches.length,\n  };\n}\n","import { TranslationRequestConfig, EnqueueFilesResult } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport type { FileReferenceIds } from '../types-dir/api/file';\nimport { processBatches } from './utils/batch';\nimport { validateFileFormatTransforms } from './utils/validateFileFormatTransform';\n\nexport type EnqueueOptions = {\n  sourceLocale?: string;\n  targetLocales: string[];\n  requireApproval?: boolean;\n  modelProvider?: string;\n  force?: boolean;\n  timeout?: number;\n};\n\n/**\n * @internal\n * Enqueues files for translation in the General Translation API.\n * @param files - References of files to translate (file content already uploaded)\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The result of the API call.\n */\nexport default async function _enqueueFiles(\n  files: FileReferenceIds[],\n  options: EnqueueOptions,\n  config: TranslationRequestConfig\n): Promise<EnqueueFilesResult> {\n  validateFileFormatTransforms(files);\n\n  const result = await processBatches(\n    files,\n    async (batch) => {\n      const body = {\n        files: batch.map((f) => ({\n          branchId: f.branchId,\n          fileId: f.fileId,\n          versionId: f.versionId,\n          fileName: f.fileName,\n          transformFormat: f.transformFormat,\n        })),\n        targetLocales: options.targetLocales,\n        sourceLocale: options.sourceLocale,\n        requireApproval: options.requireApproval,\n        modelProvider: options.modelProvider,\n        force: options.force,\n      };\n\n      const apiResult = await apiRequest<EnqueueFilesResult>(\n        config,\n        '/v2/project/translations/enqueue',\n        { body, timeout: options.timeout }\n      );\n      return Array.from(Object.entries(apiResult.jobData));\n    },\n    { batchSize: 100 }\n  );\n  // flatten the result\n  const jobs = Object.fromEntries(\n    result.data.map(([jobId, jobData]) => [jobId, jobData])\n  );\n  return {\n    jobData: jobs,\n    locales: options.targetLocales,\n    message: `Successfully enqueued ${result.count} file translation jobs in ${result.batchCount} batch(es)`,\n  };\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\n\nexport type CreateTagFileReference = {\n  fileId: string;\n  versionId: string;\n  branchId: string;\n};\n\nexport type CreateTagOptions = {\n  tagId: string;\n  files: CreateTagFileReference[];\n  message?: string;\n};\n\nexport type CreateTagResult = {\n  tag: {\n    id: string;\n    tagId: string;\n    message: string | null;\n    createdAt: string;\n    updatedAt: string;\n  };\n};\n\n/**\n * @internal\n * Creates or upserts a file tag in the General Translation API.\n * @param options - The tag creation options.\n * @param config - The configuration for the API call.\n * @returns The created or updated tag.\n */\nexport default async function _createTag(\n  options: CreateTagOptions,\n  config: TranslationRequestConfig\n): Promise<CreateTagResult> {\n  return await apiRequest<CreateTagResult>(config, '/v2/project/tags/create', {\n    body: {\n      tagId: options.tagId,\n      files: options.files,\n      ...(options.message && { message: options.message }),\n    },\n  });\n}\n","import { TranslationRequestConfig } from '../types';\nimport {\n  DownloadFileBatchOptions,\n  DownloadFileBatchRequest,\n  DownloadFileBatchResult,\n} from '../types-dir/api/downloadFileBatch';\nimport apiRequest from './utils/apiRequest';\nimport { decode } from '../utils/base64';\nimport { processBatches } from './utils/batch';\n\n/**\n * @internal\n * Downloads multiple translation files in batches.\n * @param files - Array of files to download\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns Promise resolving to a BatchList with all downloaded files\n */\nexport default async function _downloadFileBatch(\n  requests: DownloadFileBatchRequest,\n  options: DownloadFileBatchOptions,\n  config: TranslationRequestConfig\n) {\n  return processBatches(\n    requests,\n    async (batch) => {\n      const result = await apiRequest<DownloadFileBatchResult>(\n        config,\n        '/v2/project/files/download',\n        { body: batch, timeout: options.timeout }\n      );\n\n      // convert from base64 to string\n      const files = result.files.map((file) => ({\n        ...file,\n        data: decode(file.data),\n      }));\n\n      return files;\n    },\n    { batchSize: 100 }\n  );\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nexport type SubmitUserEditDiff = {\n  fileName: string;\n  locale: string;\n  diff: string;\n  branchId: string;\n  versionId: string;\n  fileId: string;\n  localContent: string;\n};\n\nexport type SubmitUserEditDiffsPayload = {\n  diffs: SubmitUserEditDiff[];\n};\n\n/**\n * @internal\n * Submits user edit diffs so the service can learn/persist user-intended rules.\n */\nexport default async function _submitUserEditDiffs(\n  payload: SubmitUserEditDiffsPayload,\n  config: TranslationRequestConfig,\n  options: { timeout?: number } = {}\n): Promise<{ success: boolean }> {\n  await processBatches(\n    payload.diffs,\n    async (batch) => {\n      await apiRequest(config, '/v2/project/files/diffs', {\n        body: { diffs: batch } satisfies SubmitUserEditDiffsPayload,\n        timeout: options.timeout,\n      });\n      return [{ success: true }];\n    },\n    { batchSize: 100 }\n  );\n\n  return { success: true };\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport { encode } from '../utils/base64';\nimport { processBatches } from './utils/batch';\n\nimport {\n  FileUpload,\n  UploadFilesResponse,\n  RequiredUploadFilesOptions,\n} from '../types-dir/api/uploadFiles';\n\n/**\n * @internal\n * Uploads source files to the General Translation API in batches.\n * @param files - The files to upload.\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns Promise resolving to a BatchList with all uploaded files\n */\nexport default async function _uploadSourceFiles(\n  files: { source: FileUpload }[],\n  options: RequiredUploadFilesOptions,\n  config: TranslationRequestConfig\n) {\n  return processBatches(\n    files,\n    async (batch) => {\n      const body = {\n        data: batch.map(({ source }) => ({\n          source: {\n            content: encode(source.content),\n            fileName: source.fileName,\n            fileFormat: source.fileFormat,\n            locale: source.locale,\n            dataFormat: source.dataFormat,\n            formatMetadata: source.formatMetadata,\n            fileId: source.fileId,\n            versionId: source.versionId,\n            branchId: source.branchId,\n            incomingBranchId: source.incomingBranchId,\n            checkedOutBranchId: source.checkedOutBranchId,\n          },\n        })),\n        sourceLocale: options.sourceLocale,\n      };\n\n      const result = await apiRequest<UploadFilesResponse>(\n        config,\n        '/v2/project/files/upload-files',\n        { body, timeout: options.timeout }\n      );\n\n      return result.uploadedFiles || [];\n    },\n    { batchSize: 100 }\n  );\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nimport {\n  FileUpload,\n  UploadFilesResponse,\n  RequiredUploadFilesOptions,\n} from '../types-dir/api/uploadFiles';\nimport { encode } from '../utils/base64';\nimport { validateFileFormatTransforms } from './utils/validateFileFormatTransform';\n\n/**\n * @internal\n * Uploads multiple translations to the General Translation API in batches.\n * @param files - Translations to upload with their source\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns Promise resolving to a BatchList with all uploaded files\n */\nexport default async function _uploadTranslations(\n  files: {\n    source: FileUpload;\n    translations: FileUpload[];\n  }[],\n  options: RequiredUploadFilesOptions,\n  config: TranslationRequestConfig\n) {\n  validateFileFormatTransforms(files.map(({ source }) => source));\n\n  return processBatches(\n    files,\n    async (batch) => {\n      const body = {\n        data: batch.map(({ source, translations }) => ({\n          source: {\n            content: encode(source.content),\n            fileName: source.fileName,\n            fileFormat: source.fileFormat,\n            transformFormat: source.transformFormat,\n            locale: source.locale,\n            dataFormat: source.dataFormat,\n            formatMetadata: source.formatMetadata,\n            fileId: source.fileId,\n            versionId: source.versionId,\n            branchId: source.branchId,\n          },\n          translations: translations.map((t) => ({\n            content: encode(t.content),\n            fileName: t.fileName,\n            fileFormat: t.fileFormat,\n            locale: t.locale,\n            dataFormat: t.dataFormat,\n            fileId: t.fileId,\n            versionId: t.versionId,\n            branchId: t.branchId,\n          })),\n        })),\n        sourceLocale: options.sourceLocale,\n      };\n\n      const result = await apiRequest<UploadFilesResponse>(\n        config,\n        '/v2/project/files/upload-translations',\n        { body, timeout: options.timeout }\n      );\n\n      return result.uploadedFiles || [];\n    },\n    { batchSize: 100 }\n  );\n}\n","import { TranslationRequestConfig } from '../types';\nimport {\n  CheckFileTranslationsOptions,\n  FileQueryResult,\n} from '../types-dir/api/checkFileTranslations';\nimport { FileQuery } from '../types-dir/api/checkFileTranslations';\nimport apiRequest from './utils/apiRequest';\n\n/**\n * @internal\n * Gets the source file and translation information for a given file ID and version ID.\n * @param query - The file ID and version ID to get the source file and translation information for\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns The source file and translation information for the given file ID and version ID\n */\nexport default async function _querySourceFile(\n  query: FileQuery,\n  options: CheckFileTranslationsOptions,\n  config: TranslationRequestConfig\n): Promise<FileQueryResult> {\n  const branchId = query.branchId;\n  const versionId = query.versionId;\n  const fileId = query.fileId;\n\n  const searchParams = new URLSearchParams();\n  if (branchId) {\n    searchParams.set('branchId', branchId);\n  }\n  if (versionId) {\n    searchParams.set('versionId', versionId);\n  }\n  const endpoint = `/v2/project/translations/files/status/${encodeURIComponent(fileId)}?${searchParams.toString()}`;\n\n  return apiRequest<FileQueryResult>(config, endpoint, {\n    method: 'GET',\n    timeout: options.timeout,\n  });\n}\n","import { defaultBaseUrl } from '../settings/settingsUrls';\nimport fetchWithTimeout from '../translate/utils/fetchWithTimeout';\nimport { defaultTimeout } from '../settings/settings';\nimport validateResponse from '../translate/utils/validateResponse';\nimport handleFetchError from '../translate/utils/handleFetchError';\nimport { TranslationRequestConfig } from '../types';\nimport generateRequestHeaders from '../translate/utils/generateRequestHeaders';\nimport { ProjectData } from '../types-dir/api/project';\n\n/**\n * @internal\n * Gets the project data for a given project ID.\n * @param projectId - The project ID to get the project data for\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns The project data for the given project ID.\n */\nexport default async function _getProjectData(\n  projectId: string,\n  options: { timeout?: number },\n  config: TranslationRequestConfig\n): Promise<ProjectData> {\n  const { baseUrl } = config;\n  const timeout = options.timeout ? options.timeout : defaultTimeout;\n  const url = `${baseUrl || defaultBaseUrl}/v2/project/info/${encodeURIComponent(projectId)}`;\n\n  // Get the project data\n  let response;\n  try {\n    response = await fetchWithTimeout(\n      url,\n      {\n        method: 'GET',\n        headers: generateRequestHeaders(config),\n      },\n      timeout\n    );\n  } catch (error) {\n    handleFetchError(error, timeout);\n  }\n\n  // Validate the response\n  await validateResponse(response);\n\n  const result = await response.json();\n  return result as ProjectData;\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\n\nexport type JobStatus =\n  | 'queued'\n  | 'processing'\n  | 'completed'\n  | 'failed'\n  | 'unknown';\n\nexport type CheckJobStatusResult = {\n  jobId: string;\n  status: JobStatus;\n  error?: { message: string };\n}[];\n\n/**\n * @internal\n * Queries job statuses for a project.\n * @param jobIds - Job IDs.\n * @param config - The configuration for the API call.\n * @param timeoutMs - The timeout in milliseconds.\n * @returns The result of the API call.\n */\nexport async function _checkJobStatus(\n  jobIds: string[],\n  config: TranslationRequestConfig,\n  timeoutMs?: number\n): Promise<CheckJobStatusResult> {\n  return apiRequest<CheckJobStatusResult>(config, '/v2/project/jobs/info', {\n    body: { jobIds },\n    timeout: timeoutMs,\n  });\n}\n","import { EnqueueFilesResult } from '../types-dir/api/enqueueFiles';\nimport { TranslationRequestConfig } from '../types';\nimport { _checkJobStatus, JobStatus } from './checkJobStatus';\n\nexport type AwaitJobsOptions = {\n  /** Polling interval in seconds. Defaults to 5. */\n  pollingIntervalSeconds?: number;\n  /** Timeout in seconds. Defaults to 600 (10 minutes). If reached, resolves with whatever status is current. */\n  timeoutSeconds?: number;\n};\n\nexport type JobResult = {\n  jobId: string;\n  status: JobStatus;\n  error?: { message: string };\n};\n\nexport type AwaitJobsResult = {\n  /** Whether all jobs completed (none still in progress). */\n  complete: boolean;\n  jobs: JobResult[];\n};\n\n/**\n * @internal\n * Polls job statuses until all jobs are finished or the timeout is reached.\n * @param enqueueResult - The result from enqueueFiles.\n * @param options - Polling configuration.\n * @param config - API credentials and configuration.\n * @returns The final status of all jobs.\n */\nexport default async function _awaitJobs(\n  enqueueResult: EnqueueFilesResult,\n  options: AwaitJobsOptions | undefined,\n  config: TranslationRequestConfig\n): Promise<AwaitJobsResult> {\n  const pollingInterval = (options?.pollingIntervalSeconds ?? 5) * 1000;\n  const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n  const timeout =\n    options?.timeoutSeconds !== undefined\n      ? options.timeoutSeconds * 1000\n      : DEFAULT_TIMEOUT_MS;\n\n  const jobIds = Object.keys(enqueueResult.jobData);\n\n  if (jobIds.length === 0) {\n    return { complete: true, jobs: [] };\n  }\n\n  const startTime = Date.now();\n  const finalStatuses = new Map<string, JobResult>(\n    jobIds.map((id) => [id, { jobId: id, status: 'unknown' as JobStatus }])\n  );\n  const pendingJobIds = new Set(jobIds);\n\n  while (pendingJobIds.size > 0) {\n    const statuses = await _checkJobStatus(Array.from(pendingJobIds), config);\n\n    for (const job of statuses) {\n      if (\n        job.status === 'completed' ||\n        job.status === 'failed' ||\n        job.status === 'unknown'\n      ) {\n        finalStatuses.set(job.jobId, {\n          jobId: job.jobId,\n          status: job.status,\n          ...(job.error ? { error: job.error } : {}),\n        });\n        pendingJobIds.delete(job.jobId);\n      } else {\n        finalStatuses.set(job.jobId, {\n          jobId: job.jobId,\n          status: job.status,\n        });\n      }\n    }\n\n    if (pendingJobIds.size === 0) break;\n\n    if (Date.now() - startTime >= timeout) break;\n\n    await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n  }\n\n  return {\n    complete: pendingJobIds.size === 0,\n    jobs: Array.from(finalStatuses.values()),\n  };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { CheckFileTranslationsOptions } from '../types-dir/api/checkFileTranslations';\nimport apiRequest from './utils/apiRequest';\n\nexport type FileDataQuery = {\n  sourceFiles?: {\n    fileId: string;\n    versionId: string;\n    branchId: string;\n  }[];\n  translatedFiles?: {\n    fileId: string;\n    versionId: string;\n    branchId: string;\n    locale: string;\n  }[];\n};\n\nexport type FileDataResult = {\n  sourceFiles?: {\n    branchId: string;\n    fileId: string;\n    versionId: string;\n    fileName: string;\n    fileFormat: string;\n    dataFormat: string | null;\n    createdAt: string;\n    updatedAt: string;\n    approvalRequiredAt: string | null;\n    publishedAt: string | null;\n    locales: string[];\n    sourceLocale: string;\n  }[];\n  translatedFiles?: {\n    branchId: string;\n    fileId: string;\n    versionId: string;\n    fileFormat: string;\n    dataFormat: string | null;\n    createdAt: string;\n    updatedAt: string;\n    approvedAt: string | null;\n    publishedAt: string | null;\n    completedAt: string | null;\n    locale: string;\n  }[];\n};\n\n/**\n * @internal\n * Queries data about one or more source or translation files.\n * @param data - Object mapping source or translation file information\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The file data.\n */\nexport default async function _queryFileData(\n  data: FileDataQuery,\n  options: CheckFileTranslationsOptions = {},\n  config: TranslationRequestConfig\n): Promise<FileDataResult> {\n  const body = {\n    sourceFiles: data.sourceFiles?.map((item) => ({\n      fileId: item.fileId,\n      versionId: item.versionId,\n      branchId: item.branchId,\n    })),\n    translatedFiles: data.translatedFiles?.map((item) => ({\n      fileId: item.fileId,\n      versionId: item.versionId,\n      branchId: item.branchId,\n      locale: item.locale,\n    })),\n  };\n\n  return apiRequest<FileDataResult>(config, '/v2/project/files/info', {\n    body,\n    timeout: options.timeout,\n  });\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport type { BranchDataResult } from '../types-dir/api/branch';\n\nexport type BranchQuery = {\n  branchNames: string[];\n};\n\n/**\n * @internal\n * Queries branch information from the API.\n * @param query - Object mapping the current branch and incoming branches\n * @param config - The configuration for the API call.\n * @returns The branch information.\n */\nexport default async function _queryBranchData(\n  query: BranchQuery,\n  config: TranslationRequestConfig\n): Promise<BranchDataResult> {\n  return apiRequest<BranchDataResult>(config, '/v2/project/branches/info', {\n    body: query,\n  });\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\n\nexport type CreateBranchQuery = {\n  branchName: string;\n  defaultBranch: boolean;\n};\n\nexport type CreateBranchResult = {\n  branch: { id: string; name: string };\n};\n\n/**\n * @internal\n * Creates a new branch in the API.\n * @param query - Object mapping the branch name and default branch flag\n * @param config - The configuration for the API call.\n * @returns The created branch information.\n */\nexport default async function _createBranch(\n  query: CreateBranchQuery,\n  config: TranslationRequestConfig\n): Promise<CreateBranchResult> {\n  return apiRequest<CreateBranchResult>(config, '/v2/project/branches/create', {\n    body: query,\n  });\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nexport type MoveMapping = {\n  oldFileId: string;\n  newFileId: string;\n  newFileName: string;\n};\n\nexport type MoveResult = {\n  oldFileId: string;\n  newFileId: string;\n  success: boolean;\n  newSourceFileId?: string;\n  clonedTranslationsCount?: number;\n  error?: string;\n};\n\nexport type ProcessMovesResponse = {\n  results: MoveResult[];\n  summary: {\n    total: number;\n    succeeded: number;\n    failed: number;\n  };\n};\n\nexport type ProcessMovesOptions = {\n  timeout?: number;\n  branchId?: string;\n};\n\n/**\n * @internal\n * Processes file moves by cloning source files and translations with new fileIds.\n * Called when the CLI detects that files have been moved/renamed.\n * @param moves - Array of move mappings (old fileId to new fileId)\n * @param options - Options including branchId and timeout\n * @param config - The configuration for the API call.\n * @returns Promise resolving to the move results\n */\nexport default async function _processFileMoves(\n  moves: MoveMapping[],\n  options: ProcessMovesOptions,\n  config: TranslationRequestConfig\n): Promise<ProcessMovesResponse> {\n  if (moves.length === 0) {\n    return {\n      results: [],\n      summary: { total: 0, succeeded: 0, failed: 0 },\n    };\n  }\n\n  const batchResult = await processBatches(\n    moves,\n    async (batch) => {\n      const result = await apiRequest<ProcessMovesResponse>(\n        config,\n        '/v2/project/files/moves',\n        {\n          body: { branchId: options.branchId, moves: batch },\n          timeout: options.timeout,\n        }\n      );\n      return result.results;\n    },\n    { batchSize: 100 }\n  );\n\n  const succeeded = batchResult.data.filter((r) => r.success).length;\n  const failed = batchResult.data.filter((r) => !r.success).length;\n\n  return {\n    results: batchResult.data,\n    summary: {\n      total: moves.length,\n      succeeded,\n      failed,\n    },\n  };\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\nimport { createBatches } from './utils/batch';\n\nexport type OrphanedFile = {\n  fileId: string;\n  versionId: string;\n  fileName: string;\n};\n\nexport type GetOrphanedFilesResult = {\n  orphanedFiles: OrphanedFile[];\n};\n\n/**\n * @internal\n * Gets orphaned files for a branch - files that exist on the branch\n * but whose fileIds are not in the provided list.\n * Used for move detection.\n * @param branchId - The branch to check for orphaned files\n * @param fileIds - List of current file IDs (files that are NOT orphaned)\n * @param options - The options for the API call\n * @param config - The configuration for the API call\n * @returns The orphaned files\n */\nexport default async function _getOrphanedFiles(\n  branchId: string,\n  fileIds: string[],\n  options: { timeout?: number } = {},\n  config: TranslationRequestConfig\n): Promise<GetOrphanedFilesResult> {\n  const makeRequest = (batchFileIds: string[]) =>\n    apiRequest<GetOrphanedFilesResult>(config, '/v2/project/files/orphaned', {\n      body: { branchId, fileIds: batchFileIds },\n      timeout: options.timeout,\n    });\n\n  // If no fileIds, make a single request\n  if (fileIds.length === 0) {\n    return makeRequest([]);\n  }\n\n  // Split fileIds into batches of 100\n  const batches = createBatches(fileIds, 100);\n\n  // Process batches in parallel\n  // Each batch returns files NOT in that batch's fileIds\n  // True orphans are files that appear in ALL batch responses (intersection)\n  const batchResults = await Promise.all(\n    batches.map((batch) => makeRequest(batch))\n  );\n\n  if (batchResults.length === 1) {\n    return batchResults[0];\n  }\n\n  // Find intersection of orphaned files across all batches\n  // A file is truly orphaned only if it's not in ANY of our fileId batches\n  // Start with first batch's orphans\n  const orphanedFileMap = new Map<string, OrphanedFile>();\n  for (const orphan of batchResults[0].orphanedFiles) {\n    orphanedFileMap.set(orphan.fileId, orphan);\n  }\n\n  // Intersect with each subsequent batch.\n  for (let i = 1; i < batchResults.length; i++) {\n    const batchOrphanIds = new Set(\n      batchResults[i].orphanedFiles.map((f) => f.fileId)\n    );\n    Array.from(orphanedFileMap.keys()).forEach((fileId) => {\n      if (!batchOrphanIds.has(fileId)) {\n        orphanedFileMap.delete(fileId);\n      }\n    });\n  }\n\n  return {\n    orphanedFiles: Array.from(orphanedFileMap.values()),\n  };\n}\n","import { TranslationRequestConfig } from '../types';\nimport apiRequest from './utils/apiRequest';\n\nexport type PublishFileEntry = {\n  fileId: string;\n  versionId: string;\n  branchId?: string;\n  publish: boolean;\n  fileName?: string;\n};\n\nexport type PublishFilesResult = {\n  results: {\n    fileId: string;\n    versionId: string;\n    locale?: string; // if locale is provided, it means this result is for a translation. Else it is for a source file.\n    branchId: string;\n    success: boolean;\n    error?: string;\n  }[];\n};\n\n/**\n * @internal\n * Publishes or unpublishes files on the CDN.\n * @param files - Array of file entries with publish flags\n * @param config - The configuration for the API call.\n * @returns The result of the API call.\n */\nexport default async function _publishFiles(\n  files: PublishFileEntry[],\n  config: TranslationRequestConfig\n): Promise<PublishFilesResult> {\n  return await apiRequest<PublishFilesResult>(\n    config,\n    '/v2/project/files/publish',\n    {\n      body: { files },\n    }\n  );\n}\n","// `generaltranslation` language toolkit\n// © 2026, General Translation, Inc.\n\n// ----- IMPORTS ----- //\n\nimport {\n  LocaleConfig,\n  determineLocale as _determineLocale,\n  getRegionProperties as _getRegionProperties,\n  isValidLocale as _isValidLocale,\n  requiresTranslation as _requiresTranslation,\n  resolveAliasLocale as _resolveAliasLocale,\n  resolveCanonicalLocale as _resolveCanonicalLocale,\n  standardizeLocale as _standardizeLocale,\n} from '@generaltranslation/format';\nimport type {\n  CustomMapping,\n  CustomRegionMapping,\n  CutoffFormatOptions,\n  FormatVariables,\n  LocaleProperties,\n  StringFormat,\n} from '@generaltranslation/format/types';\nimport {\n  TranslateManyResult,\n  TranslationError,\n  TranslationRequestConfig,\n  TranslationResult,\n  EnqueueFilesResult,\n  CheckFileTranslationsOptions,\n  DownloadFileBatchOptions,\n  DownloadFileBatchResult,\n  DownloadFileOptions,\n  TranslateManyEntry,\n} from './types';\nimport { libraryDefaultLocale } from './settings/settings';\nimport {\n  noSourceLocaleProvidedError,\n  noTargetLocaleProvidedError,\n  invalidLocaleError,\n  invalidLocalesError,\n  noProjectIdProvidedError,\n  noApiKeyProvidedError,\n} from './logging/errors';\nimport { gtInstanceLogger } from './logging/logger';\nimport _translateMany from './translate/translateMany';\nimport _setupProject, {\n  SetupProjectResult,\n  SetupProjectOptions,\n} from './translate/setupProject';\nimport _enqueueFiles, { EnqueueOptions } from './translate/enqueueFiles';\nimport _createTag, {\n  CreateTagOptions,\n  CreateTagResult,\n} from './translate/createTag';\nimport _downloadFileBatch from './translate/downloadFileBatch';\nimport {\n  FileQuery,\n  FileQueryResult,\n} from './types-dir/api/checkFileTranslations';\nimport _submitUserEditDiffs, {\n  SubmitUserEditDiffsPayload,\n} from './translate/submitUserEditDiffs';\nimport _uploadSourceFiles from './translate/uploadSourceFiles';\nimport _uploadTranslations from './translate/uploadTranslations';\nimport {\n  FileUpload,\n  RequiredUploadFilesOptions,\n  UploadFilesOptions,\n  UploadFilesResponse,\n} from './types-dir/api/uploadFiles';\nimport _querySourceFile from './translate/querySourceFile';\nimport { ProjectData } from './types-dir/api/project';\nimport _getProjectData from './projects/getProjectData';\nimport { DownloadFileBatchRequest } from './types-dir/api/downloadFileBatch';\nimport {\n  _checkJobStatus,\n  CheckJobStatusResult,\n} from './translate/checkJobStatus';\nimport _awaitJobs, {\n  AwaitJobsOptions,\n  AwaitJobsResult,\n} from './translate/awaitJobs';\nimport type { FileDataQuery, FileDataResult } from './translate/queryFileData';\nimport _queryFileData from './translate/queryFileData';\nimport type { BranchQuery } from './translate/queryBranchData';\nimport type { BranchDataResult } from './types-dir/api/branch';\nimport _queryBranchData from './translate/queryBranchData';\nimport type {\n  CreateBranchQuery,\n  CreateBranchResult,\n} from './translate/createBranch';\nimport _createBranch from './translate/createBranch';\nimport type { FileReference, FileReferenceIds } from './types-dir/api/file';\nimport _processFileMoves, {\n  type MoveMapping,\n  type ProcessMovesResponse,\n  type ProcessMovesOptions,\n} from './translate/processFileMoves';\nimport _getOrphanedFiles, {\n  type GetOrphanedFilesResult,\n} from './translate/getOrphanedFiles';\nimport _publishFiles, {\n  type PublishFileEntry,\n  type PublishFilesResult,\n} from './translate/publishFiles';\nimport { TranslateOptions } from './types-dir/api/entry';\nimport { API_VERSION as _API_VERSION } from './translate/api';\n\nexport {\n  LocaleConfig,\n  type LocaleConfigConstructorParams,\n} from '@generaltranslation/format';\n\nexport {\n  determineLocale,\n  formatCurrency,\n  formatCutoff,\n  formatDateTime,\n  formatList,\n  formatListToParts,\n  formatMessage,\n  formatNum,\n  formatRelativeTime,\n  formatRelativeTimeFromDate,\n  getLocaleDirection,\n  getLocaleEmoji,\n  getLocaleName,\n  getLocaleProperties,\n  getRegionProperties,\n  isSameDialect,\n  isSameLanguage,\n  isSupersetLocale,\n  isValidLocale,\n  requiresTranslation,\n  resolveAliasLocale,\n  resolveCanonicalLocale,\n  standardizeLocale,\n} from '@generaltranslation/format';\n\n// ============================================================ //\n//                        Core Class                            //\n// ============================================================ //\n/**\n * Type representing the constructor parameters for the GT class.\n * @typedef {Object} GTConstructorParams\n * @property {string} [apiKey] - The API key for accessing the translation service\n * @property {string} [devApiKey] - The development API key for accessing the translation service\n * @property {string} [sourceLocale] - The default source locale for translations\n * @property {string} [targetLocale] - The default target locale for translations\n * @property {string[]} [locales] - Array of supported locales\n * @property {string} [projectId] - The project ID for the translation service\n * @property {string} [baseUrl] - The base URL for the translation service\n * @property {CustomMapping} [customMapping] - Custom mapping of locale codes to their names\n */\ntype GTConstructorParams = {\n  apiKey?: string;\n  devApiKey?: string;\n  sourceLocale?: string;\n  targetLocale?: string;\n  locales?: string[];\n  projectId?: string;\n  baseUrl?: string;\n  customMapping?: CustomMapping;\n};\n\n/**\n * GT is the core driver for the General Translation library.\n * This class provides functionality for locale management, formatting, and translation operations.\n *\n * @class GT\n * @description A comprehensive toolkit for handling internationalization and localization.\n *\n * @example\n * const gt = new GT({\n *   sourceLocale: 'en-US',\n *   targetLocale: 'es-ES',\n *   locales: ['en-US', 'es-ES', 'fr-FR']\n * });\n */\nexport class GT {\n  /** Base URL for the translation service API */\n  baseUrl?: string;\n\n  /** Project ID for the translation service */\n  projectId?: string;\n\n  /** API key for accessing the translation service */\n  apiKey?: string;\n\n  /** Development API key for accessing the translation service */\n  devApiKey?: string;\n\n  /** Source locale for translations */\n  sourceLocale?: string;\n\n  /** Target locale for translations */\n  targetLocale?: string;\n\n  /** Array of supported locales */\n  locales?: string[];\n\n  /** Custom mapping for locale codes to their names */\n  customMapping?: CustomMapping;\n\n  /** Lazily derived reverse custom mapping for alias locales */\n  reverseCustomMapping?: Record<string, string>;\n\n  /** Lazily derived custom mapping for regions */\n  customRegionMapping?: CustomRegionMapping;\n\n  /** Runtime-safe locale and formatting helpers (backing field) */\n  private _localeConfig!: LocaleConfig;\n\n  /** Runtime-safe locale and formatting helpers */\n  get localeConfig() {\n    return this._localeConfig;\n  }\n\n  /**\n   * Constructs an instance of the GT class.\n   *\n   * @param {GTConstructorParams} [params] - The parameters for initializing the GT instance\n   * @throws {Error} If an invalid locale is provided\n   * @throws {Error} If any of the provided locales are invalid\n   *\n   * @example\n   * const gt = new GT({\n   *   apiKey: 'your-api-key',\n   *   sourceLocale: 'en-US',\n   *   targetLocale: 'es-ES',\n   *   locales: ['en-US', 'es-ES', 'fr-FR']\n   * });\n   */\n  constructor(params: GTConstructorParams = {}) {\n    // Read environment\n    if (typeof process !== 'undefined') {\n      this.apiKey ||= process.env?.GT_API_KEY;\n      this.devApiKey ||= process.env?.GT_DEV_API_KEY;\n      this.projectId ||= process.env?.GT_PROJECT_ID;\n    }\n    // Set up config\n    this.setConfig(params);\n  }\n\n  setConfig({\n    apiKey,\n    devApiKey,\n    sourceLocale,\n    targetLocale,\n    locales,\n    projectId,\n    customMapping,\n    baseUrl,\n  }: GTConstructorParams) {\n    // ----- Environment properties ----- //\n    if (apiKey) this.apiKey = apiKey;\n    if (devApiKey) this.devApiKey = devApiKey;\n    if (projectId) this.projectId = projectId;\n\n    // ----- Standardize locales ----- //\n\n    // source locale\n    if (sourceLocale) {\n      this.sourceLocale = _standardizeLocale(sourceLocale);\n      if (!_isValidLocale(this.sourceLocale, customMapping))\n        throw new Error(invalidLocaleError(this.sourceLocale));\n    }\n\n    // target locale\n    if (targetLocale) {\n      this.targetLocale = _standardizeLocale(targetLocale);\n      if (!_isValidLocale(this.targetLocale, customMapping))\n        throw new Error(invalidLocaleError(this.targetLocale));\n    }\n\n    // locales\n    if (locales) {\n      const result: string[] = [];\n      const invalidLocales: string[] = [];\n      locales.forEach((locale) => {\n        const standardizedLocale = _standardizeLocale(locale);\n        if (_isValidLocale(standardizedLocale)) {\n          result.push(standardizedLocale);\n        } else {\n          invalidLocales.push(locale);\n        }\n      });\n      if (invalidLocales.length > 0) {\n        throw new Error(invalidLocalesError(invalidLocales));\n      }\n      this.locales = result;\n    }\n\n    // ----- Other properties ----- //\n    if (baseUrl) this.baseUrl = baseUrl;\n    if (customMapping) {\n      this.customMapping = customMapping;\n      this.reverseCustomMapping = Object.fromEntries(\n        Object.entries(customMapping)\n          .filter(\n            ([, value]) => value && typeof value === 'object' && 'code' in value\n          )\n          .map(([key, value]) => [(value as { code: string }).code, key])\n      );\n    }\n    this._localeConfig = new LocaleConfig({\n      defaultLocale: this.sourceLocale,\n      locales: this.locales ?? [],\n      customMapping: this.customMapping,\n    });\n  }\n\n  // -------------- Private Methods -------------- //\n\n  private _getTranslationConfig(): TranslationRequestConfig {\n    return {\n      baseUrl: this.baseUrl,\n      apiKey: this.apiKey || this.devApiKey,\n      projectId: this.projectId || '',\n    };\n  }\n\n  private _validateAuth(functionName: string) {\n    const errors: string[] = [];\n    if (!this.apiKey && !this.devApiKey) {\n      const error = noApiKeyProvidedError(functionName);\n      errors.push(error);\n    }\n    if (!this.projectId) {\n      const error = noProjectIdProvidedError(functionName);\n      errors.push(error);\n    }\n    if (errors.length) {\n      throw new Error(errors.join('\\n'));\n    }\n  }\n\n  // -------------- Branch Methods -------------- //\n\n  /**\n   * Queries branch information from the API.\n   *\n   * @param {BranchQuery} query - Object mapping the current branch and incoming branches\n   * @returns {Promise<BranchDataResult>} The branch information.\n   */\n  async queryBranchData(query: BranchQuery): Promise<BranchDataResult> {\n    this._validateAuth('queryBranchData');\n    return await _queryBranchData(query, this._getTranslationConfig());\n  }\n\n  /**\n   * Creates a new branch in the API. If the branch already exists, it will be returned.\n   *\n   * @param {CreateBranchQuery} query - Object mapping the branch name and default branch flag\n   * @returns {Promise<CreateBranchResult>} The created branch information.\n   */\n  async createBranch(query: CreateBranchQuery): Promise<CreateBranchResult> {\n    this._validateAuth('createBranch');\n    return await _createBranch(query, this._getTranslationConfig());\n  }\n\n  /**\n   * Processes file moves by cloning source files and translations with new fileIds.\n   * This is called when files have been moved/renamed and we want to preserve translations.\n   *\n   * @param {MoveMapping[]} moves - Array of move mappings (old fileId to new fileId)\n   * @param {ProcessMovesOptions} options - Options including branchId and timeout\n   * @returns {Promise<ProcessMovesResponse>} The move processing results.\n   *\n   * @example\n   * const result = await gt.processFileMoves([\n   *   { oldFileId: 'abc123', newFileId: 'def456', newFileName: 'locales/en.json' }\n   * ], { branchId: 'main' });\n   */\n  async processFileMoves(\n    moves: MoveMapping[],\n    options: ProcessMovesOptions = {}\n  ): Promise<ProcessMovesResponse> {\n    this._validateAuth('processFileMoves');\n    return await _processFileMoves(\n      moves,\n      options,\n      this._getTranslationConfig()\n    );\n  }\n\n  /**\n   * Gets orphaned files for a branch - files that exist on the branch\n   * but whose fileIds are not in the provided list.\n   * Used for move detection.\n   *\n   * @param {string} branchId - The branch to check for orphaned files.\n   * @param {string[]} fileIds - List of current file IDs (files that are NOT orphaned)\n   * @param {Object} options - Options including timeout.\n   * @returns {Promise<GetOrphanedFilesResult>} The orphaned files.\n   *\n   * @example\n   * const result = await gt.getOrphanedFiles('branch-id', ['file-1', 'file-2']);\n   */\n  async getOrphanedFiles(\n    branchId: string,\n    fileIds: string[],\n    options: { timeout?: number } = {}\n  ): Promise<GetOrphanedFilesResult> {\n    this._validateAuth('getOrphanedFiles');\n    return await _getOrphanedFiles(\n      branchId,\n      fileIds,\n      options,\n      this._getTranslationConfig()\n    );\n  }\n\n  // -------------- Translation Methods -------------- //\n\n  /**\n   * Enqueues project setup job using the specified file references\n   *\n   * This method creates setup jobs that will process source file references\n   * and generate a project setup. The files parameter contains references (IDs) to source\n   * files that have already been uploaded via uploadSourceFiles. The setup jobs are queued\n   * for processing and will generate a project setup based on the source files.\n   *\n   * @param {FileReference[]} files - Array of file references containing IDs of previously uploaded source files\n   * @param {SetupProjectOptions} [options] - Optional settings for target locales and timeout.\n   * @returns {Promise<SetupProjectResult>} Object containing the jobId and status\n   */\n  async setupProject(\n    files: FileReference[],\n    options?: SetupProjectOptions\n  ): Promise<SetupProjectResult> {\n    this._validateAuth('setupProject');\n    options = {\n      ...options,\n      locales: options?.locales?.map((locale) =>\n        this.resolveCanonicalLocale(locale)\n      ),\n    };\n    return await _setupProject(files, this._getTranslationConfig(), options);\n  }\n\n  /**\n   * Checks the current status of one or more project jobs by their unique identifiers.\n   *\n   * This method polls the API to determine whether one or more jobs are still running,\n   * have completed successfully, or have failed. Jobs are created after calling either enqueueFiles or setupProject.\n   *\n   * @param {string[]} jobIds - The unique identifiers of the jobs to check.\n   * @param {number} [timeoutMs] - Optional timeout in milliseconds for the API request.\n   * @returns {Promise<CheckJobStatusResult>} Object containing the job status.\n   *\n   * @example\n   * const result = await gt.checkJobStatus([\n   *   'job-123',\n   *   'job-456',\n   * ], {\n   *   timeout: 10000,\n   * });\n   */\n  async checkJobStatus(\n    jobIds: string[],\n    timeoutMs?: number\n  ): Promise<CheckJobStatusResult> {\n    this._validateAuth('checkJobStatus');\n    return await _checkJobStatus(\n      jobIds,\n      this._getTranslationConfig(),\n      timeoutMs\n    );\n  }\n\n  /**\n   * Polls job statuses until all jobs from enqueueFiles are finished or the timeout is reached.\n   *\n   * @param {EnqueueFilesResult} enqueueResult - The result returned from enqueueFiles.\n   * @param {AwaitJobsOptions} [options] - Polling configuration (interval, timeout).\n   * @returns {Promise<AwaitJobsResult>} The final status of all jobs and whether they all completed.\n   */\n  async awaitJobs(\n    enqueueResult: EnqueueFilesResult,\n    options?: AwaitJobsOptions\n  ): Promise<AwaitJobsResult> {\n    this._validateAuth('awaitJobs');\n    return await _awaitJobs(\n      enqueueResult,\n      options,\n      this._getTranslationConfig()\n    );\n  }\n\n  /**\n   * Enqueues translation jobs for previously uploaded source files.\n   *\n   * This method creates translation jobs that will process existing source files\n   * and generate translations in the specified target languages. The files parameter\n   * contains references (IDs) to source files that have already been uploaded via\n   * uploadSourceFiles. The translation jobs are queued for processing and will\n   * generate translated content based on the source files and target locales provided.\n   *\n   * @param {FileReferenceIds[]} files - Array of file references containing IDs of previously uploaded source files\n   * @param {EnqueueOptions} options - Configuration options including source locale, target locales, and job settings.\n   * @returns {Promise<EnqueueFilesResult>} Result containing job IDs, queue status, and processing information.\n   */\n  async enqueueFiles(\n    files: FileReferenceIds[],\n    options: EnqueueOptions\n  ): Promise<EnqueueFilesResult> {\n    // Validation\n    this._validateAuth('enqueueFiles');\n\n    // Merge instance settings with options.\n    let mergedOptions: EnqueueOptions = {\n      ...options,\n      sourceLocale: options.sourceLocale ?? this.sourceLocale!,\n      targetLocales: options.targetLocales ?? [this.targetLocale!],\n    };\n\n    // Require source locale\n    if (!mergedOptions.sourceLocale) {\n      const error = noSourceLocaleProvidedError('enqueueFiles');\n      gtInstanceLogger.error(error);\n      throw new Error(error);\n    }\n\n    // Require target locale(s)\n    if (\n      !mergedOptions.targetLocales ||\n      mergedOptions.targetLocales.length === 0\n    ) {\n      const error = noTargetLocaleProvidedError('enqueueFiles');\n      gtInstanceLogger.error(error);\n      throw new Error(error);\n    }\n\n    // Replace target locales with canonical locales\n    mergedOptions = {\n      ...mergedOptions,\n      targetLocales: mergedOptions.targetLocales.map((locale) =>\n        this.resolveCanonicalLocale(locale)\n      ),\n    };\n\n    return await _enqueueFiles(\n      files,\n      mergedOptions,\n      this._getTranslationConfig()\n    );\n  }\n\n  /**\n   * Creates or upserts a file tag, associating a set of source files\n   * with a user-defined tag ID and optional message.\n   *\n   * @param {CreateTagOptions} options - Tag creation options including tagId, sourceFileIds, and optional message\n   * @returns {Promise<CreateTagResult>} The created or updated tag.\n   */\n  async createTag(options: CreateTagOptions): Promise<CreateTagResult> {\n    this._validateAuth('createTag');\n    return await _createTag(options, this._getTranslationConfig());\n  }\n\n  /**\n   * Publishes or unpublishes files on the CDN.\n   *\n   * @param {PublishFileEntry[]} files - Array of file entries with publish flags\n   * @returns {Promise<PublishFilesResult>} Result containing per-file success/failure\n   */\n  async publishFiles(files: PublishFileEntry[]): Promise<PublishFilesResult> {\n    this._validateAuth('publishFiles');\n    return await _publishFiles(files, this._getTranslationConfig());\n  }\n\n  /**\n   * Submits user edit diffs for existing translations so future generations preserve user intent.\n   *\n   * @param {SubmitUserEditDiffsPayload} payload - Project-scoped diff payload.\n   * @returns {Promise<void>} Resolves when submission succeeds.\n   */\n  async submitUserEditDiffs(\n    payload: SubmitUserEditDiffsPayload\n  ): Promise<void> {\n    this._validateAuth('submitUserEditDiffs');\n    // Normalize locales to canonical form before submission.\n    const normalized: SubmitUserEditDiffsPayload = {\n      ...payload,\n      diffs: (payload.diffs || []).map((d) => ({\n        ...d,\n        locale: this.resolveCanonicalLocale(d.locale),\n      })),\n    };\n    await _submitUserEditDiffs(normalized, this._getTranslationConfig());\n  }\n\n  /**\n   * Queries data about one or more source or translation files.\n   *\n   * @param {FileDataQuery} data - Object mapping source and translation file information.\n   * @param {CheckFileTranslationsOptions} options - Options for the API call.\n   * @returns {Promise<FileDataResult>} The source and translation file data information.\n   *\n   * @example\n   * const result = await gt.queryFileData({\n   *   sourceFiles: [\n   *     { fileId: '1234567890', versionId: '1234567890', branchId: '1234567890' },\n   *   ],\n   *   translatedFiles: [\n   *     { fileId: '1234567890', versionId: '1234567890', branchId: '1234567890', locale: 'es-ES' },\n   *   ],\n   * }, {\n   *   timeout: 10000,\n   * });\n   *\n   */\n  async queryFileData(\n    data: FileDataQuery,\n    options: CheckFileTranslationsOptions = {}\n  ): Promise<FileDataResult> {\n    // Validation\n    this._validateAuth('queryFileData');\n\n    // Replace target locales with canonical locales\n    data.translatedFiles = data.translatedFiles?.map((item) => ({\n      ...item,\n      locale: this.resolveCanonicalLocale(item.locale),\n    }));\n\n    // Request the file translation status\n    const result = await _queryFileData(\n      data,\n      options,\n      this._getTranslationConfig()\n    );\n\n    // Resolve canonical locales\n    result.translatedFiles = result.translatedFiles?.map((item) => ({\n      ...item,\n      ...(item.locale && { locale: this.resolveAliasLocale(item.locale) }),\n    }));\n    result.sourceFiles = result.sourceFiles?.map((item) => ({\n      ...item,\n      ...(item.sourceLocale && {\n        sourceLocale: this.resolveAliasLocale(item.sourceLocale),\n      }),\n      locales: item.locales.map((locale) => this.resolveAliasLocale(locale)),\n    }));\n    return result;\n  }\n\n  /**\n   * Gets source and translation information for a given file ID and version ID.\n   *\n   * @param {FileQuery} data - File query containing file ID and version ID.\n   * @param {CheckFileTranslationsOptions} options - Options for getting source and translation information.\n   * @returns {Promise<FileQueryResult>} The source file and translation information.\n   *\n   * @example\n   * const result = await gt.querySourceFile(\n   *   { fileId: '1234567890', versionId: '1234567890' },\n   *   { timeout: 10000 }\n   * );\n   *\n   */\n  async querySourceFile(\n    data: FileQuery,\n    options: CheckFileTranslationsOptions = {}\n  ): Promise<FileQueryResult> {\n    // Validation\n    this._validateAuth('querySourceFile');\n\n    // Request the file translation status\n    const result = await _querySourceFile(\n      data,\n      options,\n      this._getTranslationConfig()\n    );\n    // Replace locales with canonical locales\n    result.translations = result.translations.map((item) => ({\n      ...item,\n      ...(item.locale && { locale: this.resolveAliasLocale(item.locale) }),\n    }));\n    result.sourceFile.locales = result.sourceFile.locales.map((locale) =>\n      this.resolveAliasLocale(locale)\n    );\n    if (result.sourceFile.sourceLocale) {\n      result.sourceFile.sourceLocale = this.resolveAliasLocale(\n        result.sourceFile.sourceLocale\n      );\n    }\n    return result;\n  }\n  /**\n   * Get project data for a given project ID.\n   *\n   * @param {string} projectId - The ID of the project to get the data for.\n   * @returns {Promise<ProjectData>} The project data.\n   *\n   * @example\n   * const result = await gt.getProjectData(\n   *   '1234567890'\n   * );\n   *\n   */\n  async getProjectData(\n    projectId: string,\n    options: { timeout?: number } = {}\n  ): Promise<ProjectData> {\n    // Validation\n    this._validateAuth('getProjectData');\n\n    // Request the file translation status\n    const result = await _getProjectData(\n      projectId,\n      options,\n      this._getTranslationConfig()\n    );\n    // Replace locales with canonical locales\n    result.currentLocales = result.currentLocales.map((item) =>\n      this.resolveAliasLocale(item)\n    );\n    result.defaultLocale = this.resolveAliasLocale(result.defaultLocale);\n    return result;\n  }\n\n  /**\n   * Downloads a single file.\n   *\n   * @param file - The file query object.\n   * @param {string} file.fileId - The ID of the file to download.\n   * @param {string} [file.branchId] - The ID of the branch to download the file from. If not provided, the default branch will be used.\n   * @param {string} [file.locale] - The locale to download the file for. If not provided, the source file will be downloaded.\n   * @param {string} [file.versionId] - The version ID to download the file from. If not provided, the latest version will be used.\n   * @param {DownloadFileOptions} options - Options for downloading the file.\n   * @returns {Promise<string>} The downloaded file content.\n   *\n   * @example\n   * const result = await gt.downloadFile({\n   *   fileId: '1234567890',\n   *   branchId: '1234567890',\n   *   locale: 'es-ES',\n   *   versionId: '1234567890',\n   * }, {\n   *   timeout: 10000,\n   * });\n   */\n  async downloadFile(\n    file: {\n      fileId: string;\n      branchId?: string;\n      locale?: string;\n      versionId?: string;\n      useLatestAvailableVersion?: boolean;\n    },\n    options: DownloadFileOptions = {}\n  ): Promise<string> {\n    // Validation\n    this._validateAuth('downloadTranslatedFile');\n\n    const result = await _downloadFileBatch(\n      [\n        {\n          fileId: file.fileId,\n          branchId: file.branchId,\n          locale: file.locale\n            ? this.resolveCanonicalLocale(file.locale)\n            : undefined,\n          versionId: file.versionId,\n          useLatestAvailableVersion: file.useLatestAvailableVersion,\n        },\n      ],\n      options,\n      this._getTranslationConfig()\n    );\n    return result.data?.[0]?.data ?? '';\n  }\n\n  /**\n   * Downloads multiple files in a batch.\n   *\n   * @param {DownloadFileBatchRequest} requests - Array of file query objects to download.\n   * @param {DownloadFileBatchOptions} options - Options for the batch download.\n   * @returns {Promise<DownloadFileBatchResult>} The batch download results.\n   *\n   * @example\n   * const result = await gt.downloadFileBatch([{\n   *   fileId: '1234567890',\n   *   locale: 'es-ES',\n   *   versionId: '1234567890',\n   * }], {\n   *   timeout: 10000,\n   * });\n   */\n  async downloadFileBatch(\n    requests: DownloadFileBatchRequest,\n    options: DownloadFileBatchOptions = {}\n  ): Promise<DownloadFileBatchResult> {\n    // Validation\n    this._validateAuth('downloadFileBatch');\n\n    requests = requests.map((request) => ({\n      ...request,\n      locale: request.locale\n        ? this.resolveCanonicalLocale(request.locale)\n        : undefined,\n    }));\n\n    // Request the batch download.\n    const result = await _downloadFileBatch(\n      requests,\n      options,\n      this._getTranslationConfig()\n    );\n\n    return {\n      files: result.data.map((file) => ({\n        ...file,\n        ...(file.locale && {\n          locale: this.resolveAliasLocale(file.locale),\n        }),\n      })),\n      count: result.count,\n    };\n  }\n\n  /**\n   * Translates a single source string to the target locale.\n   * Routes through {@link translateMany} under the hood.\n   *\n   * @param {string} source - The source string to translate.\n   * @param {object} options - Translation options including targetLocale and optional entry metadata.\n   * @returns {Promise<TranslationResult | TranslationError>} The translated content.\n   *\n   * @example\n   * const result = await gt.translate('Hello, world!', { targetLocale: 'es' });\n   *\n   * @example\n   * const result = await gt.translate('Hello, world!', {\n   *   targetLocale: 'es',\n   *   dataFormat: 'ICU',\n   *   context: 'A formal greeting',\n   * });\n   */\n  async translate(\n    source: TranslateManyEntry,\n    options: string | TranslateOptions,\n    timeout?: number\n  ): Promise<TranslationResult | TranslationError> {\n    // Normalize string shorthand to options object\n    if (typeof options === 'string') {\n      options = { targetLocale: options };\n    }\n\n    // Validation\n    this._validateAuth('translate');\n\n    // Require target locale\n    let targetLocale = options?.targetLocale || this.targetLocale;\n    if (!targetLocale) {\n      const error = noTargetLocaleProvidedError('translate');\n      gtInstanceLogger.error(error);\n      throw new Error(error);\n    }\n\n    // Replace target locale with canonical locale\n    targetLocale = this.resolveCanonicalLocale(targetLocale);\n\n    const sourceLocale = this.resolveCanonicalLocale(\n      options?.sourceLocale || this.sourceLocale || libraryDefaultLocale\n    );\n\n    // Request the translation.\n    const results = await _translateMany(\n      [source],\n      {\n        ...options,\n        targetLocale,\n        sourceLocale,\n      },\n      this._getTranslationConfig(),\n      timeout\n    );\n    return results[0];\n  }\n\n  /**\n   * Translates multiple source strings to the target locale.\n   * Each entry can be a plain string or an object with source and metadata fields.\n   *\n   * @param {TranslateManyEntry[] | Record<string, TranslateManyEntry>} sources - The source entries to translate. Can be an array or a record keyed by hash.\n   * @param {object} options - Translation options including targetLocale.\n   * @returns {Promise<TranslateManyResult | Record<string, TranslationResult>>} The translated contents. An array if sources was an array, a record if sources was a record.\n   *\n   * @example\n   * const result = await gt.translateMany(\n   *   ['Hello, world!', 'Goodbye, world!'],\n   *   { targetLocale: 'es' }\n   * );\n   *\n   * @example\n   * const result = await gt.translateMany(\n   *   [{ source: 'Hello, world!', dataFormat: 'ICU' }],\n   *   { targetLocale: 'es' }\n   * );\n   *\n   * @example\n   * const result = await gt.translateMany(\n   *   { 'my-hash': 'Hello, world!' },\n   *   { targetLocale: 'es' }\n   * );\n   */\n  async translateMany(\n    sources: TranslateManyEntry[],\n    options: string | TranslateOptions,\n    timeout?: number\n  ): Promise<TranslateManyResult>;\n  async translateMany(\n    sources: Record<string, TranslateManyEntry>,\n    options: string | TranslateOptions,\n    timeout?: number\n  ): Promise<Record<string, TranslationResult>>;\n  async translateMany(\n    sources: TranslateManyEntry[] | Record<string, TranslateManyEntry>,\n    options: string | TranslateOptions,\n    timeout?: number\n  ): Promise<TranslateManyResult | Record<string, TranslationResult>> {\n    // Normalize string shorthand to options object\n    if (typeof options === 'string') {\n      options = { targetLocale: options };\n    }\n\n    // Validation\n    this._validateAuth('translateMany');\n\n    // Require target locale\n    let targetLocale = options?.targetLocale || this.targetLocale;\n    if (!targetLocale) {\n      const error = noTargetLocaleProvidedError('translateMany');\n      gtInstanceLogger.error(error);\n      throw new Error(error);\n    }\n\n    // Replace target locale with canonical locale\n    targetLocale = this.resolveCanonicalLocale(targetLocale);\n\n    const sourceLocale = this.resolveCanonicalLocale(\n      options?.sourceLocale || this.sourceLocale || libraryDefaultLocale\n    );\n\n    // Request the translation.\n    return await _translateMany(\n      sources,\n      {\n        ...options,\n        targetLocale,\n        sourceLocale,\n      },\n      this._getTranslationConfig(),\n      timeout\n    );\n  }\n\n  /**\n   * Uploads source files to the translation service without any translation content.\n   *\n   * This method creates or replaces source file entries in your project. Each uploaded\n   * file becomes a source that can later be translated into target languages. The files\n   * are processed and stored as base entries that serve as the foundation for generating\n   * translations through the translation workflow.\n   *\n   * @param {Array<{source: FileUpload}>} files - Array of objects containing source file data to upload\n   * @param {UploadFilesOptions} options - Configuration options including source locale and other upload settings.\n   * @returns {Promise<UploadFilesResponse>} Upload result containing file IDs, version information, and upload status.\n   */\n  async uploadSourceFiles(\n    files: { source: FileUpload }[],\n    options: UploadFilesOptions\n  ): Promise<UploadFilesResponse> {\n    // Validation\n    this._validateAuth('uploadSourceFiles');\n\n    // Merge instance settings with options.\n    const mergedOptions: UploadFilesOptions = {\n      ...options,\n      sourceLocale: this.resolveCanonicalLocale(\n        options.sourceLocale ?? this.sourceLocale ?? libraryDefaultLocale\n      ),\n    };\n\n    // resolve canonical locales\n    files = files.map((f) => ({\n      ...f,\n      source: {\n        ...f.source,\n        locale: this.resolveCanonicalLocale(f.source.locale),\n      },\n    }));\n\n    // Process files in batches and convert result to UploadFilesResponse\n    const result = await _uploadSourceFiles(\n      files,\n      mergedOptions as RequiredUploadFilesOptions,\n      this._getTranslationConfig()\n    );\n\n    return {\n      uploadedFiles: result.data,\n      count: result.count,\n      message: `Successfully uploaded ${result.count} files in ${result.batchCount} batch(es)`,\n    };\n  }\n\n  /**\n   * Uploads translation files that correspond to previously uploaded source files.\n   *\n   * This method allows you to provide translated content for existing source files in your project.\n   * Each translation must reference an existing source file and include the translated content\n   * along with the target locale information. This is used when you have pre-existing translations\n   * that you want to upload directly rather than generating them through the translation service.\n   *\n   * @param {Array<{source: FileUpload, translations: FileUpload[]}>} files - Array of file objects where:\n   *   - `source`: Reference to the existing source file (contains IDs but no content).\n   *   - `translations`: Array of translated files, each containing content, locale, and reference IDs\n   * @param {UploadFilesOptions} options - Configuration options including source locale and upload settings.\n   * @returns {Promise<UploadFilesResponse>} Upload result containing translation IDs, status, and processing information.\n   */\n  async uploadTranslations(\n    files: {\n      source: FileUpload; // reference only (no content)\n      translations: FileUpload[]; // each has content + ids + locale\n    }[],\n    options: UploadFilesOptions\n  ): Promise<UploadFilesResponse> {\n    // Validation\n    this._validateAuth('uploadTranslations');\n\n    // Merge instance settings with options.\n    const mergedOptions: UploadFilesOptions = {\n      ...options,\n      sourceLocale: options.sourceLocale ?? this.sourceLocale,\n    };\n\n    // Require source locale\n    if (!mergedOptions.sourceLocale) {\n      const error = noSourceLocaleProvidedError('uploadTranslations');\n      gtInstanceLogger.error(error);\n      throw new Error(error);\n    }\n\n    // Ensure all translation locales use canonical locales\n    const targetFiles = files.map((f) => ({\n      ...f,\n      translations: f.translations.map((t) => ({\n        ...t,\n        locale: this.resolveCanonicalLocale(t.locale),\n      })),\n    }));\n\n    // Process files in batches and convert result to UploadFilesResponse\n    const result = await _uploadTranslations(\n      targetFiles,\n      mergedOptions as RequiredUploadFilesOptions,\n      this._getTranslationConfig()\n    );\n\n    return {\n      uploadedFiles: result.data,\n      count: result.count,\n      message: `Successfully uploaded ${result.count} files in ${result.batchCount} batch(es)`,\n    };\n  }\n\n  // -------------- Formatting -------------- //\n\n  /**\n   * Formats a string with cutoff behavior, applying a terminator when the string exceeds the maximum character limit.\n   *\n   * This method uses the GT instance's rendering locales by default for locale-specific terminator selection,\n   * but can be overridden with custom locales in the options.\n   *\n   * @param {string} value - The string value to format with cutoff behavior.\n   * @param {Object} [options] - Configuration options for cutoff formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for terminator selection. Defaults to instance's rendering locales.\n   * @param {number} [options.maxChars] - The maximum number of characters to display.\n   * - Undefined values are treated as no cutoff.\n   * - Negative values follow .slice() behavior and terminator will be added before the value.\n   * - 0 will result in an empty string.\n   * - If cutoff results in an empty string, no terminator is added.\n   * @param {CutoffFormatStyle} [options.style='ellipsis'] - The style of the terminator.\n   * @param {string} [options.terminator] - Optional override the terminator to use.\n   * @param {string} [options.separator] - Optional override the separator to use between the terminator and the value.\n   * - If no terminator is provided, then separator is ignored.\n   * @returns {string} The formatted string with terminator applied if cutoff occurs.\n   *\n   * @example\n   * const gt = new GT({ targetLocale: 'en-US' });\n   * gt.formatCutoff('Hello, world!', { maxChars: 8 });\n   * // Returns: 'Hello, w...'\n   *\n   * @example\n   * gt.formatCutoff('Hello, world!', { maxChars: -3 });\n   * // Returns: '...ld!'\n   */\n  formatCutoff(\n    value: string,\n    options?: {\n      locales?: string | string[];\n    } & CutoffFormatOptions\n  ): string {\n    return this.localeConfig.formatCutoff(value, this.targetLocale, options);\n  }\n\n  /**\n   * Formats a message according to the specified locales and options.\n   *\n   * @param {string} message - The message to format.\n   * @param {string | string[]} [locales='en'] - The locales to use for formatting.\n   * @param {FormatVariables} [variables={}] - The variables to use for formatting.\n   * @param {StringFormat} [dataFormat='ICU'] - The format of the message.\n   * @returns {string} The formatted message.\n   *\n   * @example\n   * gt.formatMessage('Hello {name}', { name: 'John' });\n   * // Returns: \"Hello John\"\n   *\n   * gt.formatMessage('Hello {name}', { name: 'John' }, { locales: ['fr'] });\n   * // Returns: \"Bonjour John\"\n   */\n  formatMessage(\n    message: string,\n    options?: {\n      locales?: string | string[];\n      variables?: FormatVariables;\n      dataFormat?: StringFormat;\n    }\n  ): string {\n    return this.localeConfig.formatMessage(message, this.targetLocale, options);\n  }\n  /**\n   * Formats a number according to the specified locales and options.\n   *\n   * @param {number} number - The number to format.\n   * @param {Object} [options] - Additional options for number formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for formatting.\n   * @param {Intl.NumberFormatOptions} [options] - Additional Intl.NumberFormat options.\n   * @returns {string} The formatted number.\n   *\n   * @example\n   * gt.formatNum(1234.56, { style: 'currency', currency: 'USD' });\n   * // Returns: \"$1,234.56\"\n   */\n  formatNum(\n    number: number,\n    options?: {\n      locales?: string | string[];\n    } & Intl.NumberFormatOptions\n  ): string {\n    return this.localeConfig.formatNum(number, this.targetLocale, options);\n  }\n\n  /**\n   * Formats a date according to the specified locales and options.\n   *\n   * @param {Date} date - The date to format.\n   * @param {Object} [options] - Additional options for date formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for formatting.\n   * @param {Intl.DateTimeFormatOptions} [options] - Additional Intl.DateTimeFormat options.\n   * @returns {string} The formatted date.\n   *\n   * @example\n   * gt.formatDateTime(new Date(), { dateStyle: 'full', timeStyle: 'long' });\n   * // Returns: \"Thursday, March 14, 2024 at 2:30:45 PM GMT-7\"\n   */\n  formatDateTime(\n    date: Date,\n    options?: {\n      locales?: string | string[];\n    } & Intl.DateTimeFormatOptions\n  ): string {\n    return this.localeConfig.formatDateTime(date, this.targetLocale, options);\n  }\n\n  /**\n   * Formats a currency value according to the specified locales and options.\n   *\n   * @param {number} value - The currency value to format.\n   * @param {string} currency - The currency code (e.g., 'USD', 'EUR')\n   * @param {Object} [options] - Additional options for currency formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for formatting.\n   * @param {Intl.NumberFormatOptions} [options] - Additional Intl.NumberFormat options.\n   * @returns {string} The formatted currency value.\n   *\n   * @example\n   * gt.formatCurrency(1234.56, 'USD', { style: 'currency' });\n   * // Returns: \"$1,234.56\"\n   */\n  formatCurrency(\n    value: number,\n    currency: string,\n    options?: {\n      locales?: string | string[];\n    } & Intl.NumberFormatOptions\n  ): string {\n    return this.localeConfig.formatCurrency(\n      value,\n      currency,\n      this.targetLocale,\n      options\n    );\n  }\n\n  /**\n   * Formats a list of items according to the specified locales and options.\n   *\n   * @param {Array<string | number>} array - The list of items to format.\n   * @param {Object} [options] - Additional options for list formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for formatting.\n   * @param {Intl.ListFormatOptions} [options] - Additional Intl.ListFormat options.\n   * @returns {string} The formatted list.\n   *\n   * @example\n   * gt.formatList(['apple', 'banana', 'orange'], { type: 'conjunction' });\n   * // Returns: \"apple, banana, and orange\"\n   */\n  formatList(\n    array: Array<string | number>,\n    options?: {\n      locales?: string | string[];\n    } & Intl.ListFormatOptions\n  ) {\n    return this.localeConfig.formatList(array, this.targetLocale, options);\n  }\n\n  /**\n   * Formats a list of items according to the specified locales and options.\n   * @param {Array<T>} array - The list of items to format.\n   * @param {Object} [options] - Additional options for list formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for formatting.\n   * @param {Intl.ListFormatOptions} [options] - Additional Intl.ListFormat options.\n   * @returns {Array<T | string>} The formatted list parts.\n   *\n   * @example\n   * gt.formatListToParts(['apple', 42, { foo: 'bar' }], { type: 'conjunction', style: 'short', locales: ['en'] });\n   * // Returns: ['apple', ', ', 42, ' and ', '{ foo: \"bar\" }']\n   */\n  formatListToParts<T>(\n    array: Array<T>,\n    options?: {\n      locales?: string | string[];\n    } & Intl.ListFormatOptions\n  ): Array<T | string> {\n    return this.localeConfig.formatListToParts<T>(\n      array,\n      this.targetLocale,\n      options\n    );\n  }\n\n  /**\n   * Formats a relative time value according to the specified locales and options.\n   *\n   * @param {number} value - The relative time value to format.\n   * @param {Intl.RelativeTimeFormatUnit} unit - The unit of time (e.g., 'second', 'minute', 'hour', 'day', 'week', 'month', 'year')\n   * @param {Object} options - Additional options for relative time formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for formatting.\n   * @param {Intl.RelativeTimeFormatOptions} [options] - Additional Intl.RelativeTimeFormat options.\n   * @returns {string} The formatted relative time string.\n   *\n   * @example\n   * gt.formatRelativeTime(-1, 'day', { locales: ['en-US'], numeric: 'auto' });\n   * // Returns: \"yesterday\"\n   */\n  formatRelativeTime(\n    value: number,\n    unit: Intl.RelativeTimeFormatUnit,\n    options?: {\n      locales?: string | string[];\n    } & Omit<Intl.RelativeTimeFormatOptions, 'locales'>\n  ): string {\n    return this.localeConfig.formatRelativeTime(\n      value,\n      unit,\n      this.targetLocale,\n      options\n    );\n  }\n\n  /**\n   * Formats a relative time string from a Date, automatically selecting the best unit.\n   *\n   * @param {Date} date - The date to format relative to now.\n   * @param {Object} [options] - Additional options for relative time formatting.\n   * @param {string | string[]} [options.locales] - The locales to use for formatting.\n   * @returns {string} The formatted relative time string (e.g., \"2 hours ago\", \"in 3 days\")\n   *\n   * @example\n   * gt.formatRelativeTimeFromDate(new Date(Date.now() - 3600000));\n   * // Returns: \"1 hour ago\"\n   */\n  formatRelativeTimeFromDate(\n    date: Date,\n    options?: {\n      locales?: string | string[];\n      baseDate?: Date;\n    } & Omit<Intl.RelativeTimeFormatOptions, 'locales'>\n  ): string {\n    return this.localeConfig.formatRelativeTimeFromDate(\n      date,\n      this.targetLocale,\n      options\n    );\n  }\n\n  // -------------- Locale Properties -------------- //\n\n  /**\n   * Retrieves the display name of a locale code using Intl.DisplayNames, returning an empty string if no name is found.\n   *\n   * @param {string} [locale=this.targetLocale] - A BCP-47 locale code.\n   * @returns {string} The display name corresponding to the code.\n   * @throws {Error} If no target locale is provided.\n   *\n   * @example\n   * gt.getLocaleName('es-ES');\n   * // Returns: \"Spanish (Spain)\"\n   */\n  getLocaleName(locale = this.targetLocale): string {\n    if (!locale) throw new Error(noTargetLocaleProvidedError('getLocaleName'));\n    return this.localeConfig.getLocaleName(locale);\n  }\n\n  /**\n   * Retrieves an emoji based on a given locale code.\n   * Uses the locale's region (if present) to select an emoji or falls back on default emojis.\n   *\n   * @param {string} [locale=this.targetLocale] - A BCP-47 locale code (e.g., 'en-US', 'fr-CA')\n   * @returns {string} The emoji representing the locale or its region.\n   * @throws {Error} If no target locale is provided.\n   *\n   * @example\n   * gt.getLocaleEmoji('es-ES');\n   * // Returns: \"🇪🇸\"\n   */\n  getLocaleEmoji(locale = this.targetLocale): string {\n    if (!locale) throw new Error(noTargetLocaleProvidedError('getLocaleEmoji'));\n    return this.localeConfig.getLocaleEmoji(locale);\n  }\n\n  /**\n   * Generates linguistic details for a given locale code.\n   *\n   * This function returns information about the locale,\n   * script, and region of a given language code both in a standard form and in a maximized form (with likely script and region).\n   * The function provides these names in both your default language and native forms, and an associated emoji.\n   *\n   * @param {string} [locale=this.targetLocale] - The locale code to get properties for (e.g., \"de-AT\").\n   * @returns {LocaleProperties} - An object containing detailed information about the locale.\n   *\n   * @property {string} code - The full locale code, e.g., \"de-AT\".\n   * @property {string} name - Language name in the default display language, e.g., \"Austrian German\".\n   * @property {string} nativeName - Language name in the locale's native language, e.g., \"Österreichisches Deutsch\".\n   * @property {string} languageCode - The base language code, e.g., \"de\".\n   * @property {string} languageName - The language name in the default display language, e.g., \"German\".\n   * @property {string} nativeLanguageName - The language name in the native language, e.g., \"Deutsch\".\n   * @property {string} nameWithRegionCode - Language name with region in the default language, e.g., \"German (AT)\".\n   * @property {string} nativeNameWithRegionCode - Language name with region in the native language, e.g., \"Deutsch (AT)\".\n   * @property {string} regionCode - The region code from maximization, e.g., \"AT\".\n   * @property {string} regionName - The region name in the default display language, e.g., \"Austria\".\n   * @property {string} nativeRegionName - The region name in the native language, e.g., \"Österreich\".\n   * @property {string} scriptCode - The script code from maximization, e.g., \"Latn\".\n   * @property {string} scriptName - The script name in the default display language, e.g., \"Latin\".\n   * @property {string} nativeScriptName - The script name in the native language, e.g., \"Lateinisch\".\n   * @property {string} maximizedCode - The maximized locale code, e.g., \"de-Latn-AT\".\n   * @property {string} maximizedName - Maximized locale name with likely script in the default language, e.g., \"Austrian German (Latin)\".\n   * @property {string} nativeMaximizedName - Maximized locale name in the native language, e.g., \"Österreichisches Deutsch (Lateinisch)\".\n   * @property {string} minimizedCode - Minimized locale code, e.g., \"de-AT\" (or \"de\" for \"de-DE\").\n   * @property {string} minimizedName - Minimized language name in the default language, e.g., \"Austrian German\".\n   * @property {string} nativeMinimizedName - Minimized language name in the native language, e.g., \"Österreichisches Deutsch\".\n   * @property {string} emoji - The emoji associated with the locale's region, if applicable.\n   */\n  getLocaleProperties(locale = this.targetLocale): LocaleProperties {\n    if (!locale)\n      throw new Error(noTargetLocaleProvidedError('getLocaleProperties'));\n    return this.localeConfig.getLocaleProperties(locale);\n  }\n\n  /**\n   * Retrieves multiple properties for a given region code, including:\n   * - `code`: the original region code\n   * - `name`: the localized display name\n   * - `emoji`: the associated flag or symbol\n   *\n   * Behavior:\n   * - Accepts ISO 3166-1 alpha-2 or UN M.49 region codes (e.g., `\"US\"`, `\"FR\"`, `\"419\"`).\n   * - Uses the instance's `targetLocale` to localize the region name for the user.\n   * - If `customMapping` contains a `name` or `emoji` for the region, those override the default values.\n   * - Otherwise, uses `Intl.DisplayNames` to get the localized region name, falling back to `libraryDefaultLocale`.\n   * - Falls back to the region code as `name` if display name resolution fails.\n   * - Falls back to a default emoji if no emoji mapping is found in built-in data or `customMapping`.\n   *\n   * @param {string} [region=this.getLocaleProperties().regionCode] - The region code to look up (e.g., `\"US\"`, `\"GB\"`, `\"DE\"`).\n   * @param {CustomRegionMapping} [customMapping] - Optional mapping of region codes to custom names and/or emojis.\n   * @returns {{ code: string, name: string, emoji: string }} An object containing:\n   *  - `code`: the input region code\n   *  - `name`: the localized or custom region name\n   *  - `emoji`: the matching emoji flag or symbol\n   *\n   * @throws {Error} If no target locale is available to determine region properties.\n   *\n   * @example\n   * const gt = new GT({ targetLocale: 'en-US' });\n   * gt.getRegionProperties('US');\n   * // => { code: 'US', name: 'United States', emoji: '🇺🇸' }\n   *\n   * @example\n   * const gt = new GT({ targetLocale: 'fr-FR' });\n   * gt.getRegionProperties('US');\n   * // => { code: 'US', name: 'États-Unis', emoji: '🇺🇸' }\n   *\n   * @example\n   * gt.getRegionProperties('US', { US: { name: 'USA', emoji: '🗽' } });\n   * // => { code: 'US', name: 'USA', emoji: '🗽' }\n   */\n  getRegionProperties(\n    region = this.getLocaleProperties().regionCode,\n    customMapping?: CustomRegionMapping\n  ): { code: string; name: string; emoji: string } {\n    if (!customMapping) {\n      if (this.customMapping && !this.customRegionMapping) {\n        // Lazy derive custom region mapping from customMapping\n        const customRegionMapping: CustomRegionMapping = {};\n        for (const [locale, lp] of Object.entries(this.customMapping)) {\n          if (\n            lp &&\n            typeof lp === 'object' &&\n            lp.regionCode &&\n            !customRegionMapping[lp.regionCode]\n          ) {\n            const { regionName: name, emoji } = lp;\n            customRegionMapping[lp.regionCode] = {\n              locale,\n              ...(name && { name }),\n              ...(emoji && { emoji }),\n            };\n          }\n        }\n        this.customRegionMapping = customRegionMapping;\n      }\n      customMapping = this.customRegionMapping;\n    }\n    return _getRegionProperties(\n      region,\n      this.targetLocale, // this.targetLocale because we want it in the user's language\n      customMapping\n    );\n  }\n\n  /**\n   * Determines whether a translation is required based on the source and target locales.\n   *\n   * @param {string} [sourceLocale=this.sourceLocale] - The locale code for the original content.\n   * @param {string} [targetLocale=this.targetLocale] - The locale code to translate into.\n   * @param {string[]} [approvedLocales=this.locales] - Optional array of approved target locales.\n   * @returns {boolean} True if translation is required, false otherwise\n   * @throws {Error} If no source locale is provided.\n   * @throws {Error} If no target locale is provided.\n   *\n   * @example\n   * gt.requiresTranslation('en-US', 'es-ES');\n   * // Returns: true\n   */\n  requiresTranslation(\n    sourceLocale = this.sourceLocale,\n    targetLocale = this.targetLocale,\n    approvedLocales: string[] | undefined = this.locales,\n    customMapping: CustomMapping | undefined = this.customMapping\n  ): boolean {\n    if (!sourceLocale)\n      throw new Error(noSourceLocaleProvidedError('requiresTranslation'));\n    if (!targetLocale)\n      throw new Error(noTargetLocaleProvidedError('requiresTranslation'));\n    if (customMapping === this.customMapping) {\n      return this.localeConfig.requiresTranslation(\n        targetLocale,\n        sourceLocale,\n        approvedLocales\n      );\n    }\n    return _requiresTranslation(\n      sourceLocale,\n      targetLocale,\n      approvedLocales,\n      customMapping\n    );\n  }\n\n  /**\n   * Determines the best matching locale from the provided approved locales list.\n   *\n   * @param {string | string[]} locales - A single locale or array of locales in preference order.\n   * @param {string[]} [approvedLocales=this.locales] - Array of approved locales in preference order.\n   * @returns {string | undefined} The best matching locale, or undefined if no match is found.\n   *\n   * @example\n   * gt.determineLocale(['fr-CA', 'fr-FR'], ['en-US', 'fr-FR', 'es-ES']);\n   * // Returns: \"fr-FR\"\n   */\n  determineLocale(\n    locales: string | string[],\n    approvedLocales: string[] | undefined = this.locales || [],\n    customMapping: CustomMapping | undefined = this.customMapping\n  ): string | undefined {\n    if (customMapping === this.customMapping) {\n      return this.localeConfig.determineLocale(locales, approvedLocales ?? []);\n    }\n    return _determineLocale(locales, approvedLocales, customMapping);\n  }\n\n  /**\n   * Gets the text direction for a given locale code.\n   *\n   * @param {string} [locale=this.targetLocale] - A BCP-47 locale code.\n   * @returns {'ltr' | 'rtl'} 'rtl' if the locale is right-to-left; otherwise 'ltr'.\n   * @throws {Error} If no target locale is provided.\n   *\n   * @example\n   * gt.getLocaleDirection('ar-SA');\n   * // Returns: \"rtl\"\n   */\n  getLocaleDirection(locale = this.targetLocale): 'ltr' | 'rtl' {\n    if (!locale)\n      throw new Error(noTargetLocaleProvidedError('getLocaleDirection'));\n    return this.localeConfig.getLocaleDirection(locale);\n  }\n\n  /**\n   * Checks if a given BCP 47 locale code is valid.\n   *\n   * @param {string} [locale=this.targetLocale] - The BCP 47 locale code to validate.\n   * @param {CustomMapping} [customMapping=this.customMapping] - The custom mapping to use for validation.\n   * @returns {boolean} True if the locale code is valid, false otherwise\n   * @throws {Error} If no target locale is provided.\n   *\n   * @example\n   * gt.isValidLocale('en-US');\n   * // Returns: true\n   */\n  isValidLocale(\n    locale = this.targetLocale,\n    customMapping: CustomMapping | undefined = this.customMapping\n  ): boolean {\n    if (!locale) throw new Error(noTargetLocaleProvidedError('isValidLocale'));\n    if (customMapping === this.customMapping) {\n      return this.localeConfig.isValidLocale(locale);\n    }\n    return _isValidLocale(locale, customMapping);\n  }\n\n  /**\n   * Resolves the canonical locale for a given locale.\n   * @param locale - The locale to resolve the canonical locale for\n   * @param customMapping - The custom mapping to use for resolving the canonical locale\n   * @returns The canonical locale, or the input locale when no canonical mapping exists.\n   */\n  resolveCanonicalLocale(\n    locale: string | undefined = this.targetLocale,\n    customMapping: CustomMapping | undefined = this.customMapping\n  ): string {\n    if (!locale)\n      throw new Error(noTargetLocaleProvidedError('resolveCanonicalLocale'));\n    if (customMapping === this.customMapping) {\n      return this.localeConfig.resolveCanonicalLocale(locale);\n    }\n    return _resolveCanonicalLocale(locale, customMapping);\n  }\n\n  /**\n   * Resolves the alias locale for a given locale.\n   * @param locale - The locale to resolve the alias locale for\n   * @param customMapping - The custom mapping to use for resolving the alias locale\n   * @returns The configured alias for a canonical locale, or the input locale when already an alias or no alias mapping exists.\n   */\n  resolveAliasLocale(\n    locale: string,\n    customMapping: CustomMapping | undefined = this.customMapping\n  ): string {\n    if (!locale)\n      throw new Error(noTargetLocaleProvidedError('resolveAliasLocale'));\n    if (customMapping === this.customMapping) {\n      return this.localeConfig.resolveAliasLocale(locale);\n    }\n    return _resolveAliasLocale(locale, customMapping);\n  }\n\n  /**\n   * Standardizes a BCP 47 locale code to ensure correct formatting.\n   *\n   * @param {string} [locale=this.targetLocale] - The BCP 47 locale code to standardize.\n   * @returns {string} The standardized locale code, or the input string if it cannot be standardized.\n   * @throws {Error} If no target locale is provided.\n   *\n   * @example\n   * gt.standardizeLocale('en_us');\n   * // Returns: \"en-US\"\n   */\n  standardizeLocale(locale = this.targetLocale): string {\n    if (!locale)\n      throw new Error(noTargetLocaleProvidedError('standardizeLocale'));\n    return this.localeConfig.standardizeLocale(locale);\n  }\n\n  /**\n   * Checks if multiple BCP 47 locale codes represent the same dialect.\n   *\n   * @param {...(string | string[])} locales - The BCP 47 locale codes to compare.\n   * @returns {boolean} True if all codes represent the same dialect, false otherwise\n   *\n   * @example\n   * gt.isSameDialect('en-US', 'en-GB');\n   * // Returns: false\n   *\n   * gt.isSameDialect('en', 'en-US');\n   * // Returns: true\n   */\n  isSameDialect(...locales: (string | string[])[]): boolean {\n    return this.localeConfig.isSameDialect(...locales);\n  }\n\n  /**\n   * Checks if multiple BCP 47 locale codes represent the same language.\n   *\n   * @param {...(string | string[])} locales - The BCP 47 locale codes to compare.\n   * @returns {boolean} True if all codes represent the same language, false otherwise\n   *\n   * @example\n   * gt.isSameLanguage('en-US', 'en-GB');\n   * // Returns: true\n   */\n  isSameLanguage(...locales: (string | string[])[]): boolean {\n    return this.localeConfig.isSameLanguage(...locales);\n  }\n\n  /**\n   * Checks if a locale is a superset of another locale.\n   *\n   * @param {string} superLocale - The locale to check if it is a superset\n   * @param {string} subLocale - The locale to check if it is a subset\n   * @returns {boolean} True if superLocale is a superset of subLocale, false otherwise\n   *\n   * @example\n   * gt.isSupersetLocale('en', 'en-US');\n   * // Returns: true\n   *\n   * gt.isSupersetLocale('en-US', 'en');\n   * // Returns: false\n   */\n  isSupersetLocale(superLocale: string, subLocale: string): boolean {\n    return this.localeConfig.isSupersetLocale(superLocale, subLocale);\n  }\n}\n\nexport const API_VERSION = _API_VERSION;\n"],"mappings":"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"}