@remotex-labs/xbuild 2.5.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -4
- package/dist/bash.d.ts +3135 -0
- package/dist/bash.js +41 -66
- package/dist/bash.js.map +1 -1
- package/dist/index.d.ts +2774 -4978
- package/dist/index.js +23 -27
- package/dist/index.js.map +1 -1
- package/package.json +25 -16
package/dist/bash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["src/bash.ts","src/errors/uncaught.error.ts","src/providers/stack.provider.ts","src/modules/symlinks/symlinks.module.ts","src/modules/typescript/models/files.model.ts","src/services/framework.service.ts","src/modules/observable/pipe/operators.pipe.ts","src/modules/observable/services/observable.service.ts","src/modules/observable/services/subject.service.ts","src/modules/observable/services/behavior-subject.service.ts","src/components/object.component.ts","src/constants/configuration.constant.ts","src/services/configuration.service.ts","src/errors/base.error.ts","src/modules/argv/argv.module.ts","src/modules/argv/constants/argv.constant.ts","src/components/interactive.component.ts","src/components/glob.component.ts","src/errors/types.error.ts","src/errors/xbuild.error.ts","src/errors/esbuild.error.ts","src/providers/esbuild-messages.provider.ts","src/modules/server/server.module.ts","src/modules/server/html/server.html","src/components/banner.component.ts","src/services/watch.service.ts","src/services/variant.service.ts","src/modules/typescript/models/graph.model.ts","src/modules/typescript/components/transformer.component.ts","src/modules/typescript/services/typescript.service.ts","src/modules/typescript/services/bundler.service.ts","src/modules/typescript/constants/typescript.constant.ts","src/modules/typescript/services/emitter.service.ts","src/modules/typescript/services/hosts.service.ts","src/services/transpiler.service.ts","src/components/entry-points.component.ts","src/providers/lifecycle.provider.ts","src/directives/macros.directive.ts","src/directives/define.directive.ts","src/directives/inline.directive.ts","src/errors/inline.error.ts","src/services/vm.service.ts","src/directives/analyze.directive.ts","src/services/build.service.ts","src/index.ts","src/components/constants/interactive.constant.ts","src/providers/config-file.provider.ts","src/components/printer.component.ts","src/errors/vm-runtime.error.ts","src/components/color.component.ts"],"sourceRoot":"https://github.com/remotex-labs/xBuild/tree/v2.5.1/","sourcesContent":["#!/usr/bin/env node\n\n/**\n * Import will remove at compile time\n */\n\nimport type { ServerConfigurationInterface } from './index';\nimport type { ArgumentsInterface } from '@argv/interfaces/argv-module.interface';\nimport type { xBuildConfigInterface } from '@providers/interfaces/config-file-provider.interface';\n\n/**\n * Imports\n */\n\nimport { rmSync } from 'fs';\nimport { cwd } from 'process';\nimport '@errors/uncaught.error';\nimport { join } from '@remotex-labs/xmap';\nimport { ArgvModule } from '@argv/argv.module';\nimport { inject } from '@symlinks/symlinks.module';\nimport { init } from '@components/interactive.component';\nimport { collectFilesFromGlob } from '@components/glob.component';\nimport { configFileProvider } from '@providers/config-file.provider';\nimport { bannerComponent, prefix } from '@components/banner.component';\nimport { BuildService, overwriteConfig, ServerModule, WatchService } from './index';\nimport { logError, logTypeDiagnostics, logBuildEnd } from '@components/printer.component';\nimport { errorColor, keywordColor, mutedColor, pathColor } from '@components/color.component';\nimport { logBuildStart, createActionPrefix, ERROR_SYMBOL } from '@components/printer.component';\n\n/**\n * Default glob patterns for excluding common non-source directories from entry point collection.\n *\n * @remarks\n * Applied when `--entryPoints` CLI flag is provided to filter out:\n * - `node_modules`: Third-party dependencies\n * - `dist`: Build output directory\n * - `bundle`: Alternative build output\n * - `**\\/*.d.ts`: TypeScript declaration files\n *\n * These patterns are prepended with `!` to indicate exclusion in glob syntax.\n *\n * @example\n * ```ts\n * const patterns = [...args.entryPoints, ...DEFAULT_IGNORE_PATTERNS];\n * // Result: ['src/**\\/*.ts', '!node_modules/**', '!dist/**', ...]\n * ```\n *\n * @see {@link configureEntryPoints} for usage context\n *\n * @since 2.0.0\n */\n\nconst DEFAULT_IGNORE_PATTERNS = [\n '!node_modules/**',\n '!dist/**',\n '!bundle/**',\n '!**/*.d.ts'\n] as const;\n\n/**\n * Glob patterns for directories excluded from watch mode file monitoring.\n *\n * @remarks\n * Prevents unnecessary rebuilds when files change in:\n * - `dist`: Build output (avoids rebuild loops)\n * - `.git`: Version control metadata\n * - `.idea`: IDE configuration files\n * - `node_modules`: Third-party dependencies (rarely change during development)\n *\n * Does not use `!` prefix as these are used directly with the watch service's\n * ignore configuration, not glob pattern matching.\n *\n * @example\n * ```ts\n * const watchService = new WatchService(WATCH_IGNORE_PATTERNS);\n * // Ignores changes in dist/, .git/, .idea/, node_modules/\n * ```\n *\n * @see {@link WatchService} for file monitoring implementation\n * @see {@link collectWatchIgnorePatterns} for dynamic pattern collection\n *\n * @since 2.0.0\n */\n\nconst WATCH_IGNORE_PATTERNS = [\n 'dist',\n 'dist/**',\n '.git/**',\n '.idea/**',\n 'node_modules/**'\n] as const;\n\n/**\n * Configures entry points from CLI glob patterns and injects them as a special \"argv\" build variant.\n *\n * @param config - The xBuild configuration object to modify\n * @param args - Parsed command-line arguments containing entry point patterns\n *\n * @remarks\n * When the `--entryPoints` CLI flag is provided, this function:\n * 1. Combines user patterns with default exclusion patterns\n * 2. Excludes custom output directories from config (both CLI and config file)\n * 3. Resolves glob patterns to actual file paths\n * 4. Creates an \"argv\" variant containing the collected entry points\n *\n * The \"argv\" variant is a special build variant that merges with other configured\n * variants or serves as the sole variant if none are defined in the config file.\n *\n * **Output directory exclusion**:\n * - Checks `args.outdir` (CLI flag)\n * - Checks `config.common.esbuild.outdir` (config file)\n * - Adds both as exclusion patterns to prevent output files from being processed as source\n *\n * @example With entry points CLI flag\n * ```ts\n * const args = { entryPoints: ['src/**\\/*.ts'], outdir: 'build' };\n * configureEntryPoints(config, args);\n *\n * // config.variants.argv now contains:\n * // {\n * // esbuild: {\n * // entryPoints: ['src/index.ts', 'src/utils.ts', ...]\n * // }\n * // }\n * ```\n *\n * @example Without entry points (no-op)\n * ```ts\n * const args = {};\n * configureEntryPoints(config, args);\n * // config unchanged\n * ```\n *\n * @see {@link ArgumentsInterface.entryPoints}\n * @see {@link DEFAULT_IGNORE_PATTERNS} for default exclusions\n * @see {@link collectFilesFromGlob} for glob pattern resolution\n *\n * @since 2.0.0\n */\n\nfunction configureEntryPoints(config: xBuildConfigInterface, args: ArgumentsInterface): void {\n if (!args.entryPoints) return;\n\n const ignorePatterns = [\n ...args.entryPoints,\n ...DEFAULT_IGNORE_PATTERNS\n ];\n\n if (args.outdir) {\n ignorePatterns.push(`!${ args.outdir }/**`, `!${ args.outdir }`);\n }\n\n if (config.common?.esbuild?.outdir) {\n ignorePatterns.push(`!${ config.common.esbuild.outdir }/**`, `!${ config.common.esbuild.outdir }`);\n }\n\n config.variants = {\n argv: {\n esbuild: {\n entryPoints: collectFilesFromGlob(cwd(), ignorePatterns)\n }\n }\n };\n}\n\n/**\n * Applies command-line argument overrides to all build variant configurations.\n *\n * @param config - The xBuild configuration object to modify\n * @param args - Parsed command-line arguments containing override values\n *\n * @remarks\n * Iterates through all configured variants and applies CLI flag overrides for:\n * - `--verbose`: Enable detailed logging\n * - `--types`: Enable/disable TypeScript type generation\n * - `--outdir`: Override output directory\n * - `--bundle`: Enable bundling and minification\n * - `--minify`: Enable code minification\n * - `--tsconfig`: Specify custom TypeScript configuration file\n * - `--platform`: Target platform (node, browser, neutral)\n * - `--declaration`: Enable/disable `.d.ts` generation\n * - `--failOnError`: Fail build on type errors\n *\n * **Precedence**: CLI flags take precedence over config file settings, allowing\n * temporary overrides without modifying the configuration file.\n *\n * **Top-level vs. variant settings**:\n * - `verbose` is set at the top level (affects all variants)\n * - Other settings are applied to each variant's configuration individually\n *\n * **Conditional application**: Only defined CLI arguments are applied, allowing\n * partial overrides while preserving other config file settings.\n *\n * @example Override output directory\n * ```ts\n * const args = { outdir: 'build' };\n * applyCommandLineOverrides(config, args);\n *\n * // All variants now have:\n * // variant.esbuild.outdir = 'build'\n * ```\n *\n * @example Multiple overrides\n * ```ts\n * const args = {\n * minify: true,\n * platform: 'node',\n * declaration: false\n * };\n * applyCommandLineOverrides(config, args);\n *\n * // All variants updated with these settings\n * ```\n *\n * @see {@link ArgumentsInterface} for available CLI flags\n * @see {@link xBuildConfigInterface} for configuration structure\n *\n * @since 2.0.0\n */\n\nfunction applyCommandLineOverrides(config: xBuildConfigInterface, args: ArgumentsInterface): void {\n if (args.verbose !== undefined) {\n config.verbose = args.verbose;\n }\n\n const variants = Object.values(config.variants ?? {});\n\n for (const variant of variants) {\n if (args.types !== undefined) variant.types = args.types;\n if (args.outdir !== undefined) variant.esbuild.outdir = args.outdir;\n if (args.bundle !== undefined) variant.esbuild.minify = args.bundle;\n if (args.minify !== undefined) variant.esbuild.minify = args.minify;\n if (args.tsconfig !== undefined) variant.esbuild.tsconfig = args.tsconfig;\n if (args.platform !== undefined) variant.esbuild.platform = args.platform;\n if (args.declaration !== undefined) variant.declaration = args.declaration;\n\n if (args.failOnError !== undefined) {\n variant.types = { failOnError: args.failOnError };\n }\n }\n}\n\n/**\n * Collects all directories that should be ignored by the file watcher.\n *\n * @param config - The xBuild configuration containing output directory settings\n *\n * @returns Array of directory patterns to exclude from watch monitoring\n *\n * @remarks\n * Combines default ignore patterns with dynamic output directories to create\n * a comprehensive exclusion list for the watch service. This prevents:\n * - Rebuild loops (watching build output directories)\n * - Unnecessary rebuild triggers from IDE/VCS file changes\n * - Performance issues from monitoring large node_modules directories\n *\n * **Dynamic pattern collection**:\n * 1. Starts with {@link WATCH_IGNORE_PATTERNS} (static patterns)\n * 2. Adds `config.common.esbuild.outdir` if present\n * 3. Adds each variant's `esbuild.outdir` if present\n * 4. For each directory, adds both the directory itself and a recursive pattern\n *\n * **Pattern format**:\n * - `dist`: Ignore the directory\n * - `dist/**`: Ignore all files within the directory recursively\n *\n * @example With common and variant output directories\n * ```ts\n * const config = {\n * common: { esbuild: { outdir: 'dist' } },\n * variants: {\n * prod: { esbuild: { outdir: 'build' } },\n * dev: { esbuild: { outdir: 'tmp' } }\n * }\n * };\n *\n * const patterns = collectWatchIgnorePatterns(config);\n * // Returns: [\n * // 'dist', '.git/**', 'node_modules/**', ...,\n * // 'dist', 'dist/**',\n * // 'build', 'build/**',\n * // 'tmp', 'tmp/**'\n * // ]\n * ```\n *\n * @example With no custom output directories\n * ```ts\n * const config = { variants: {} };\n * const patterns = collectWatchIgnorePatterns(config);\n * // Returns: ['dist', 'dist/**', '.git/**', '.idea/**', 'node_modules/**']\n * ```\n *\n * @see {@link WATCH_IGNORE_PATTERNS} for default exclusions\n * @see {@link WatchService} for watch service implementation\n *\n * @since 2.0.0\n */\n\nfunction collectWatchIgnorePatterns(config: xBuildConfigInterface): Array<string> {\n const ignorePatterns: Array<string> = [ ...WATCH_IGNORE_PATTERNS ];\n\n if (config.common?.esbuild?.outdir) {\n ignorePatterns.push(config.common.esbuild.outdir, `${ config.common.esbuild.outdir }/**`);\n }\n\n const variants = Object.values(config.variants ?? {});\n for (const variant of variants) {\n if (variant.esbuild.outdir) {\n ignorePatterns.push(variant.esbuild.outdir, `${ variant.esbuild.outdir }/**`);\n }\n }\n\n return ignorePatterns;\n}\n\n/**\n * Starts the development HTTP server if requested via CLI or configuration.\n *\n * @param config - The xBuild configuration containing server settings\n * @param args - Parsed command-line arguments containing serve flag\n *\n * @returns Promise resolving to the server URL string if started, otherwise undefined\n *\n * @remarks\n * The server is started when either:\n * - `--serve [dir]` CLI flag is provided (optionally with directory)\n * - `config.serve.start` is set to `true` in configuration file\n *\n * **Server directory resolution**:\n * 1. `config.serve.dir` (config file setting, highest priority)\n * 2. `args.serve` (CLI flag value, if string)\n * 3. `'dist'` (default fallback)\n *\n * **Configuration merging**:\n * - Merges config file server settings with CLI overrides\n * - Wraps the `onStart` callback to capture server URL and log startup message\n * - Preserves user-defined `onStart` callback if present\n *\n * **Startup logging**:\n * Displays formatted startup message:\n * ```\n * [serve] dist http://localhost:3000\n * ```\n *\n * @example Start server with CLI flag\n * ```ts\n * const args = { serve: 'public' };\n * const url = await startServer(config, args);\n * // Server started at http://localhost:3000\n * // Serving: public\n * ```\n *\n * @example Start server from config\n * ```ts\n * const config = {\n * serve: {\n * start: true,\n * dir: 'dist',\n * port: 8080\n * }\n * };\n * const url = await startServer(config, {});\n * // Server started at http://localhost:8080\n * ```\n *\n * @example No server (returns undefined)\n * ```ts\n * const config = { serve: { start: false } };\n * const url = await startServer(config, {});\n * // url === undefined\n * ```\n *\n * @see {@link ServerModule} for server implementation\n * @see {@link ServerConfigurationInterface} for configuration options\n *\n * @since 2.0.0\n */\n\nasync function startServer(config: xBuildConfigInterface, args: ArgumentsInterface): Promise<string | undefined> {\n const shouldStartServer = (args.serve ?? false) !== false || config.serve?.start;\n if (!shouldStartServer) return;\n\n let urlString = undefined;\n const serveDir = config.serve?.dir || args.serve || 'dist';\n const serverConfig: ServerConfigurationInterface = {\n ...config.serve,\n onStart({ host, port, url }): void {\n urlString = url;\n console.log(`${ createActionPrefix('serve') } ${ keywordColor(serveDir) } ${ pathColor(url) }\\n`);\n config.serve?.onStart?.({ host, port, url });\n }\n };\n\n const server = new ServerModule(serverConfig, serveDir);\n await server.start();\n\n return urlString;\n}\n\n/**\n * Executes a single build pass, handling clean, type checking, and build operations.\n *\n * @param buildService - The build service instance to execute\n * @param args - Parsed command-line arguments controlling build behavior\n *\n * @returns Promise that resolves when the build completes or fails\n *\n * @remarks\n * Orchestrates a complete build cycle with the following steps:\n * 1. **Clean**: Removes the `dist` directory (forced, recursive)\n * 2. **Type check or build**: Executes type checking if `--typeCheck` flag is set, otherwise performs full build\n * 3. **Error handling**: Catches and logs any build errors\n *\n * **Operational modes**:\n * - **Type check mode** (`--typeCheck`): Runs TypeScript compiler diagnostics without emitting files\n * - **Build mode**: Executes full build with optional build name parameter\n *\n * **Clean behavior**:\n * - Always removes `dist` directory before building\n * - Uses `{ recursive: true, force: true }` for safe deletion\n * - Errors during clean are silently ignored (directory may not exist)\n *\n * **Error handling**:\n * - All errors are caught and logged via {@link logError}\n * - Errors do not throw (suitable for watch mode)\n *\n * @example Standard build\n * ```ts\n * const args = { build: 'production' };\n * await executeBuild(buildService, args);\n * // 1. Removes dist/\n * // 2. Builds with 'production' configuration\n * ```\n *\n * @example Type check only\n * ```ts\n * const args = { typeCheck: true };\n * await executeBuild(buildService, args);\n * // 1. Removes dist/\n * // 2. Runs TypeScript diagnostics\n * // 3. Logs diagnostics (no files emitted)\n * ```\n *\n * @example Error during build\n * ```ts\n * await executeBuild(buildService, args);\n * // If build fails, error is logged but function doesn't throw\n * ```\n *\n * @see {@link logError} for error formatting\n * @see {@link BuildService.typeChack} for type checking\n * @see {@link BuildService.build} for build implementation\n * @see {@link logTypeDiagnostics} for diagnostic output formatting\n *\n * @since 2.0.0\n */\n\nasync function executeBuild(buildService: BuildService, args: ArgumentsInterface): Promise<void> {\n try {\n const distPath = join(process.cwd(), 'dist');\n rmSync(distPath, { recursive: true, force: true });\n\n if (args.typeCheck) {\n const diagnostics = await buildService.typeChack();\n logTypeDiagnostics(diagnostics);\n } else {\n const result = await buildService.build(args.build);\n Object.entries(result).forEach(([ name, variant ]) => {\n const errors = variant.errors.filter(\n (error: Error & { id?: string }) => error?.id === 'endHook'\n );\n\n if(!errors.length) return;\n const status = createActionPrefix('onEnd-hook', errorColor(ERROR_SYMBOL));\n console.log(status, name);\n\n errors.forEach((error: Error) => logError(error));\n console.log('');\n });\n }\n } catch (error) {\n logError(error);\n process.exitCode = 1;\n }\n}\n\n/**\n * Enters watch mode for continuous rebuilding on file changes.\n *\n * @param buildService - The build service instance to trigger rebuilds\n * @param config - The xBuild configuration containing watch patterns\n * @param args - Parsed command-line arguments controlling watch behavior\n * @param url - Optional server URL to display in interactive UI\n *\n * @returns Promise that resolves when watch mode is set up (never resolves in watch mode)\n *\n * @remarks\n * Watch mode is enabled when:\n * - `--watch` CLI flag is provided, OR\n * - `--serve` CLI flag is provided (implies watching), OR\n * - `config.serve.start` is `true` (implies watching)\n *\n * **Watch mode flow**:\n * 1. Collects ignore patterns from configuration\n * 2. Initializes watch service with ignore patterns\n * 3. Sets up interactive terminal UI (if applicable)\n * 4. Executes initial build\n * 5. Starts file system watcher\n * 6. On file changes:\n * - Touches changed files in TypeScript language service\n * - Reloads configuration if config file changed\n * - Logs rebuild trigger\n * - Executes rebuild\n *\n * **Configuration reloading**:\n * If the configuration file itself changes, the config is reloaded and\n * the build service is updated with the new configuration, allowing\n * configuration changes without restarting the process.\n *\n * **Interactive UI**:\n * Initializes an interactive terminal interface displaying:\n * - Server URL (if provided)\n * - Build status\n * - Keyboard shortcuts for manual actions\n *\n * **Early exit**:\n * If watch mode is not requested, the function returns immediately\n * without starting the watcher.\n *\n * @example Watch mode with server\n * ```ts\n * const args = { watch: true, serve: 'dist' };\n * await startWatchMode(buildService, config, args, 'http://localhost:3000');\n * // 1. Executes initial build\n * // 2. Starts watching files\n * // 3. Rebuilds on changes\n * // (Never returns)\n * ```\n *\n * @example Serve mode (implicit watch)\n * ```ts\n * const args = { serve: 'dist' };\n * await startWatchMode(buildService, config, args, url);\n * // Watch mode automatically enabled\n * ```\n *\n * @example No watch mode\n * ```ts\n * const args = {};\n * await startWatchMode(buildService, config, args);\n * // Returns immediately (no watching)\n * ```\n *\n * @see {@link WatchService} for file system monitoring\n * @see {@link BuildService.reload} for configuration reloading\n * @see {@link BuildService.touchFiles} for incremental compilation\n * @see {@link collectWatchIgnorePatterns} for ignore pattern collection\n *\n * @since 2.0.0\n */\n\nasync function startWatchMode(\n buildService: BuildService, config: xBuildConfigInterface, args: ArgumentsInterface, url?: string\n): Promise<void> {\n const shouldWatch = args.watch || args.serve !== undefined || config.serve?.start;\n if (!shouldWatch) return;\n\n const ignorePatterns = collectWatchIgnorePatterns(config);\n const watchService = new WatchService(ignorePatterns);\n\n init(async () => {\n buildService.reload({ clearCache: true });\n await executeBuild(buildService, args);\n }, url);\n\n await executeBuild(buildService, args);\n await watchService.start(async (changedFiles: Array<string>): Promise<void> => {\n buildService.touchFiles(changedFiles);\n\n if(changedFiles.includes(args.config!)) {\n const config = await configFileProvider(args.config!);\n buildService.reload({ config });\n }\n\n console.log(`\\n${ prefix() } ${ mutedColor('Rebuilding') }: files (${ changedFiles.length })\\n`);\n await executeBuild(buildService, args);\n });\n\n return;\n}\n\n/**\n * Main CLI entry point that orchestrates the complete xBuild execution lifecycle.\n *\n * @returns Promise that resolves when execution completes (or never in watch mode)\n *\n * @throws Errors are caught and logged internally, function does not throw\n *\n * @remarks\n * This is the primary entry point executed when the xBuild CLI is invoked.\n * It orchestrates the complete build lifecycle from configuration loading to\n * build execution, with support for watch mode, development server, and various\n * build configurations.\n *\n * **Execution flow**:\n * 1. **Banner**: Display xBuild version and branding\n * 2. **Configuration parsing**:\n * - Parse config file path from CLI args\n * - Load configuration file (if exists)\n * - Parse full CLI arguments with config context\n * - Extract user-defined arguments\n * 3. **Configuration setup**:\n * - Configure entry points from glob patterns\n * - Apply CLI overrides to variant configurations\n * - Finalize and validate configuration\n * 4. **Build service initialization**:\n * - Create build service instance with user args\n * - Register lifecycle callbacks (onStart, onEnd)\n * 5. **Server startup** (if requested):\n * - Start development HTTP server\n * - Capture server URL for UI display\n * 6. **Execution mode**:\n * - Enter watch mode if `--watch` or `--serve` flags present\n * - Otherwise, execute single build pass\n *\n * **Configuration precedence**:\n * 1. CLI flags (highest priority)\n * 2. Configuration file settings\n * 3. Built-in defaults (lowest priority)\n *\n * **User arguments**:\n * Custom CLI arguments defined in `config.userArgv` are parsed separately\n * and passed to the build service, allowing custom build scripts to extend\n * the CLI with additional flags.\n *\n * **Lifecycle callbacks**:\n * - `onStart`: Logs build start with timing information\n * - `onEnd`: Logs build completion with duration and status\n *\n * @example Standard build invocation\n * ```bash\n * xbuild\n * # 1. Displays banner\n * # 2. Loads xbuild.config.ts\n * # 3. Executes build\n * # 4. Exits\n * ```\n *\n * @example Watch mode with server\n * ```bash\n * xbuild --watch --serve dist --port 8080\n * # 1. Displays banner\n * # 2. Loads configuration\n * # 3. Starts server on port 8080\n * # 4. Executes initial build\n * # 5. Watches for changes\n * # (Runs indefinitely)\n * ```\n *\n * @example Custom configuration file\n * ```bash\n * xbuild --config custom.config.ts --minify\n * # Loads custom.config.ts instead of default\n * ```\n *\n * @see {@link startWatchMode} for watch mode\n * @see {@link executeBuild} for build execution\n * @see {@link startServer} for development server\n * @see {@link ArgvModule} for CLI argument parsing\n * @see {@link BuildService} for build orchestration\n * @see {@link configFileProvider} for configuration loading\n *\n * @since 2.0.0\n */\n\nasync function main(): Promise<void> {\n // Display banner\n console.log(bannerComponent());\n\n // Parse configuration\n const argvService = inject(ArgvModule);\n const preConfig = argvService.parseConfigFile(process.argv);\n\n globalThis.$argv = preConfig;\n const config = await configFileProvider(preConfig.config);\n const args = argvService.enhancedParse(process.argv, config.userArgv);\n const userArgs = argvService.parseUserArgv(process.argv, config.userArgv);\n\n // Configure build\n configureEntryPoints(config, args);\n applyCommandLineOverrides(config, args);\n overwriteConfig(config);\n\n // Initialize build service\n const buildService = new BuildService(userArgs);\n buildService.onEnd = logBuildEnd;\n buildService.onStart = logBuildStart;\n\n // Execute build pipeline\n const url = await startServer(config, args);\n await startWatchMode(buildService, config, args, url);\n await executeBuild(buildService, args);\n}\n\nmain();\n","/**\n * Imports\n */\n\nimport process from 'node:process';\nimport { xBuildBaseError } from '@errors/base.error';\nimport { formatStack, getErrorMetadata } from '@providers/stack.provider';\n\n/**\n * Formats and logs error output in a standardized way.\n *\n * @remarks\n * This utility is designed for use in global error handlers such as\n * `uncaughtException` and `unhandledRejection`.\n * - If the error is an {@link AggregateError}, all individual errors are iterated and logged.\n * - Errors extending {@link xBuildBaseError} are logged directly without stack formatting.\n * - Standard {@link Error} instances are logged using {@link formatStack}, with both\n * framework and native frames included.\n * - Non-error values are logged as-is.\n *\n * @param reason - The error, aggregate error, or arbitrary value to log.\n *\n * @example\n * ```ts\n * formatErrors(new Error(\"Something went wrong\"));\n * ```\n *\n * @see formatStack\n * @see xJetBaseError\n * @see AggregateError\n *\n * @since 2.0.0\n */\n\nexport function formatErrors(reason: unknown): void {\n if (reason instanceof AggregateError) {\n console.error('AggregateError:', reason.message);\n for (const err of reason.errors) {\n if (err instanceof Error && !(err instanceof xBuildBaseError)) {\n const metadata = getErrorMetadata(err, { withFrameworkFrames: true, withNativeFrames: true });\n console.error(formatStack(metadata, err.name, err.message));\n } else {\n console.error(err);\n }\n }\n\n return;\n }\n\n if (reason instanceof Error && !(reason instanceof xBuildBaseError)) {\n const metadata = getErrorMetadata(reason, { withFrameworkFrames: true, withNativeFrames: true });\n console.error(formatStack(metadata, reason.name, reason.message));\n } else {\n console.error(reason);\n }\n}\n\n/**\n * Global handler for uncaught exceptions in Node.js.\n *\n * @param reason - The value or error object representing the uncaught exception\n *\n * @throws This handler does not throw, but catches uncaught exceptions\n *\n * @remarks\n * When an uncaught exception occurs, this handler logs the error using {@link formatStack}\n * with both framework and native frames included, and then terminates the process\n * with exit code `2`, signaling failure.\n *\n * @example\n * ```ts\n * // Automatically registered when this file is loaded,\n * throw new Error('This error will be logged and exit the process');\n * ```\n *\n * @see formatStack\n * @see process.exit\n * @see {@link https://nodejs.org/api/process.html#event-uncaughtexception | Node.js documentation on 'uncaughtException'}\n *\n * @since 2.0.0\n */\n\nprocess.on('uncaughtException', (reason: unknown) => {\n formatErrors(reason);\n process.exit(2);\n});\n\n/**\n * Global handler for unhandled promise rejections in Node.js.\n *\n * @param reason - The value or error object representing the reason for the unhandled promise rejection\n *\n * @throws This handler does not throw, but catches unhandled promise rejections\n *\n * @remarks\n * When an unhandled promise rejection occurs, this handler logs the error using {@link formatStack}\n * with both framework and native frames included, and then terminates the process\n * with exit code `2`. Using a distinct exit code allows differentiating between uncaught exceptions\n * and unhandled promise rejections.\n *\n * @example\n * ```ts\n * // Automatically registered when this file is loaded\n * Promise.reject(new Error('This rejection will be logged and exit the process'));\n * ```\n *\n * @see formatStack\n * @see process.exit\n * @see {@link https://nodejs.org/api/process.html#process_event_unhandledrejection | Node.js documentation on 'unhandledRejection'}\n *\n * @since 2.0.0\n */\n\nprocess.on('unhandledRejection', (reason: unknown) => {\n formatErrors(reason);\n process.exit(2);\n});\n","/**\n * Import will remove at compile time\n */\n\nimport type { PartialMessage } from 'esbuild';\nimport type { SourceService } from '@remotex-labs/xmap';\nimport type { ParsedStackTraceInterface } from '@remotex-labs/xmap/parser.component';\nimport type { StackTraceInterface, ResolveMetadataInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { resolveError } from '@remotex-labs/xmap';\nimport { inject } from '@symlinks/symlinks.module';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { FilesModel } from '@typescript/models/files.model';\nimport { FrameworkService } from '@services/framework.service';\nimport { parseErrorStack } from '@remotex-labs/xmap/parser.component';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { formatErrorCode } from '@remotex-labs/xmap/formatter.component';\nimport { highlightCode } from '@remotex-labs/xmap/highlighter.component';\n\n/**\n * Retrieves a source service for a given stack frame, either from source maps or file snapshots.\n *\n * @param fileName - The source filename\n * @returns A {@link SourceService} if the source can be resolved, otherwise null\n *\n * @remarks\n * - First attempts to retrieve a mapped source using {@link FrameworkService.getSourceMap}.\n * - Falls back to file snapshots via {@link FilesModel.getSnapshot} if no source map exists.\n * - Creates a minimal {@link SourceService} implementation for snapshot-based sources.\n * - Returns null if neither a source map nor snapshot is available.\n * - The created service implements `getPositionWithCode` to extract code snippets with context lines.\n *\n * @example\n * ```ts\n * const source = getSource.call(context, frame);\n * if (source) {\n * const position = source.getPositionWithCode(10, 5, Bias.LOWER_BOUND);\n * }\n * ```\n *\n * @see SourceService\n * @see StackContextInterface\n * @see FilesModel.getSnapshot\n * @see FrameworkService.getSourceMap\n *\n * @since 2.0.0\n */\n\nexport function getSource(fileName: string = ''): SourceService | null {\n const framework = inject(FrameworkService);\n const mapped = framework.getSourceMap(fileName);\n if (mapped) return mapped;\n\n const snapshot = inject(FilesModel).getOrTouchFile(fileName);\n const code = snapshot?.contentSnapshot?.text;\n\n if (!snapshot || !code) return null;\n const lines = code.split('\\n');\n\n return {\n getPositionWithCode: (line, column, _bias, options) => {\n const before = options?.linesBefore ?? 3;\n const after = options?.linesAfter ?? 3;\n\n const startLine = Math.max(line - before, 0);\n const endLine = Math.min(line + after, lines.length);\n\n return {\n line,\n column: column + 1,\n code: lines.slice(startLine, endLine).join('\\n'),\n source: fileName,\n name: null,\n startLine,\n endLine,\n sourceRoot: null,\n sourceIndex: -1,\n generatedLine: -1,\n generatedColumn: -1\n };\n }\n } as SourceService;\n}\n\n/**\n * Extracts a parsed stack trace from either an Error object or an esbuild PartialMessage.\n *\n * @param raw - Either an {@link Error} object or an esbuild {@link PartialMessage}\n * @returns A {@link ParsedStackTraceInterface} containing structured stack frame data\n *\n * @remarks\n * - If `raw` is an Error instance, parses it directly using {@link parseErrorStack}.\n * - If `raw.detail` is an Error, parses that instead.\n * - For esbuild messages without location info, returns a minimal parsed stack.\n * - For esbuild messages with location, creates a single-frame stack from the location data.\n *\n * @example\n * ```ts\n * const error = new Error(\"Something went wrong\");\n * const parsed = getErrorStack(error);\n * console.log(parsed.stack); // Array of stack frames\n * ```\n *\n * @see parseErrorStack\n * @see ParsedStackTraceInterface\n *\n * @since 2.0.0\n */\n\nexport function getErrorStack(raw: Partial<PartialMessage> | Error): ParsedStackTraceInterface {\n if (raw instanceof Error) return parseErrorStack(raw);\n if (raw.detail instanceof Error) return parseErrorStack(raw.detail);\n\n if (!raw.location) {\n return { stack: [], name: 'esBuildMessage', message: raw.text ?? '', rawStack: '' };\n }\n\n return {\n name: 'esBuildMessage',\n message: raw.text ?? '',\n rawStack: '',\n stack: [\n {\n source: `@${ raw.location.file }`,\n line: raw.location.line,\n column: raw.location.column,\n fileName: raw.location.file,\n eval: false,\n async: false,\n native: false,\n constructor: false\n }\n ]\n };\n}\n\n\n/**\n * Parses error metadata into a structured stack representation with enhanced source information.\n *\n * @param raw - Either an esbuild {@link PartialMessage} or an {@link Error} object\n * @param options - Optional {@link StackTraceInterface} configuration for controlling stack parsing\n * @returns A {@link ResolveMetadataInterface} object containing formatted stack frames and code context\n *\n * @remarks\n * - Creates a {@link ResolveMetadataInterface} using injected services for file and framework resolution.\n * - Respects the `verbose` configuration setting to control native and framework frame visibility.\n * - Uses {@link getErrorStack} to parse the raw error into stack frames.\n * - Processes each frame via {@link resolveError}, filtering out empty results.\n * - Returns structured metadata including formatted code, line/column positions, and stack traces.\n * - Line offsets are applied to all resolved positions for alignment with external systems.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Something went wrong\");\n * } catch (error) {\n * const metadata = getErrorMetadata(error, { linesBefore: 5, linesAfter: 5 });\n * console.log(metadata.stacks); // Array of formatted stack lines\n * console.log(metadata.formatCode); // Highlighted code snippet\n * }\n * ```\n *\n * @see stackEntry\n * @see getErrorStack\n * @see StackInterface\n * @see StackTraceInterface\n * @see StackContextInterface\n * @see ConfigurationService\n *\n * @since 2.0.0\n */\n\nexport function getErrorMetadata(raw: PartialMessage | Error, options?: StackTraceInterface): ResolveMetadataInterface {\n const framework = inject(FrameworkService);\n const verbose = inject(ConfigurationService).getValue(c => c.verbose) ?? false;\n const parsed = getErrorStack(raw);\n const resolved: ResolveMetadataInterface = resolveError(parsed, {\n ...options,\n withNativeFrames: verbose || (options?.withFrameworkFrames ?? false),\n getSource(path: string): SourceService | null {\n return getSource(path);\n }\n });\n\n resolved.stack.filter(frame => {\n if (!(options?.withFrameworkFrames ?? false) && framework.isFrameworkFile(frame)) return false;\n if(!resolved.formatCode && frame.code) {\n resolved.formatCode = formatErrorCode(\n {\n code: highlightCode(frame.code),\n line: frame.line ?? 0,\n column: frame.column ?? 0,\n startLine: frame.stratLine ?? 0\n },\n { color: xterm.brightPink }\n );\n }\n });\n\n return resolved;\n}\n\n/**\n * Formats error metadata into a human-readable string with enhanced styling.\n *\n * @param metadata - The {@link ResolveMetadataInterface} object containing parsed stack trace information\n * @param name - The error name (e.g., \"TypeError\", \"ReferenceError\")\n * @param message - The error message describing what went wrong\n * @param notes - Optional array of esbuild {@link PartialMessage} notes to display\n * @returns A string containing the formatted error output with colorized text, code snippet, and stack trace\n *\n * @remarks\n * - Constructs a formatted error output from pre-parsed stack metadata.\n * - Displays the error name and message at the top with {@link xterm.lightCoral} highlighting.\n * - Includes any additional notes in gray text below the error message.\n * - Appends syntax-highlighted code snippet if available in metadata.\n * - Appends formatted stack trace frames with proper indentation under \"Enhanced Stack Trace\".\n * - All formatting and syntax highlighting should be pre-applied in the metadata.\n *\n * @example\n * ```ts\n * const metadata: StackInterface = {\n * code: \"const x = undefined;\\nx.toString();\",\n * line: 2,\n * column: 1,\n * source: \"/path/to/file.ts\",\n * stacks: [\"at Object.<anonymous> (/path/to/file.ts:2:1)\"],\n * formatCode: \"1 | const x = undefined;\\n2 | x.toString();\\n ^\"\n * };\n *\n * const notes = [{ text: \"Did you forget to check for null?\" }];\n * console.log(formatStack(metadata, \"TypeError\", \"Cannot read property 'toString' of undefined\", notes));\n * ```\n *\n * @see xterm\n * @see PartialMessage\n * @see StackInterface\n * @see getErrorMetadata\n *\n * @since 2.0.0\n */\n\nexport function formatStack(metadata: ResolveMetadataInterface, name: string, message: string, notes: PartialMessage['notes'] = []): string {\n const parts = [ `\\n${ name }: ${ xterm.lightCoral(message) }` ];\n for (const note of notes ?? []) {\n if(note.text) parts.push('\\n ' + xterm.gray(note.text));\n }\n\n if (metadata.formatCode) parts.push(`\\n\\n${ metadata.formatCode }`);\n if (metadata.stack.length) {\n parts.push(`\\n\\nEnhanced Stack Trace:\\n ${ metadata.stack.map(stack => stack.format).join('\\n ') }\\n`);\n }\n\n return parts.join('');\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { InjectableOptionsInterface, ProvidersType } from './interfaces/symlinks.interface';\nimport type { ProviderUseFactoryInterface, ProviderUseValueInterface } from './interfaces/symlinks.interface';\nimport type { ProviderUseClassInterface, ConstructorType, ConstructorLikeType } from './interfaces/symlinks.interface';\n\n/**\n * A collection of singleton instances for injectable classes.\n *\n * @remarks\n * This map stores instances of classes marked as `singleton` in `@Injectable` metadata.\n * It ensures that only one instance exists for the lifetime of the application.\n *\n * @see ConstructorType\n * @since 2.0.0\n */\n\nexport const SINGLETONS = new Map<ConstructorType, unknown>();\n\n/**\n * Stores metadata for all classes marked with the `@Injectable` decorator.\n *\n * @remarks\n * The metadata includes scope, factory function, and provider dependencies.\n *\n * @see Injectable\n * @since 2.0.0\n */\n\nexport const INJECTABLES = new Map<ConstructorType, InjectableOptionsInterface>();\n\n/**\n * Type guard to check if a provider uses a class.\n *\n * @param provider - The provider to check.\n * @returns True if the provider is a {@link ProviderUseClassInterface}.\n *\n * @see ProviderUseClassInterface\n * @since 2.0.0\n */\n\nexport function isProviderUseClass(provider: unknown): provider is ProviderUseClassInterface {\n return typeof provider === 'object' && provider !== null && 'useClass' in provider;\n}\n\n/**\n * Type guard to check if a provider uses a factory function.\n *\n * @param provider - The provider to check.\n * @returns True if the provider is a {@link ProviderUseFactoryInterface}.\n *\n * @see ProviderUseFactoryInterface\n * @since 2.0.0\n */\n\nexport function isProviderUseFactory(provider: unknown): provider is ProviderUseFactoryInterface {\n return typeof provider === 'object' && provider !== null && 'useFactory' in provider;\n}\n\n/**\n * Type guard to check if a provider uses a value.\n *\n * @param provider - The provider to check.\n * @returns True if the provider is a {@link ProviderUseValueInterface}.\n *\n * @see ProviderUseValueInterface\n * @since 2.0.0\n */\n\nexport function isProviderUseValue(provider: unknown): provider is ProviderUseValueInterface {\n return typeof provider === 'object' && provider !== null && 'useValue' in provider;\n}\n\n/**\n * Marks a class as injectable, optionally providing metadata.\n *\n * @param options - Optional configuration for the injectable class.\n *\n * @remarks\n * The `@Injectable` decorator allows classes to be automatically instantiated\n * and injected with dependencies using the `inject` function.\n *\n * @example\n * ```ts\n * @Injectable({ scope: 'singleton' })\n * class MyService {}\n *\n * const instance = inject(MyService);\n * ```\n *\n * ```ts\n * @Injectable()\n * class Database {\n * }\n *\n * @Injectable({\n * providers: [ Database ]\n * })\n * class UserService {\n * constructor(private db: Database) {\n * console.log(db); // db instance\n * }\n * }\n *\n * const userService = inject(UserService);\n * ```\n *\n * ```ts\n * @Injectable()\n * class Cache {}\n *\n * @Injectable({\n * providers: [{ useClass: Cache }]\n * })\n * class UserService {\n * constructor(cache: Cache) {\n * console.log(cache); // cache instance\n * }\n * }\n *\n * const userService = inject(UserService);\n * ```\n *\n * ```ts\n * @Injectable({\n * providers: [\n * {\n * useFactory(): Date {\n * return new Date();\n * }\n * }\n * ]\n * })\n * class ClockService {\n * constructor(now: Date) {\n * console.log(now.toLocaleTimeString()); // get time from the factory\n * }\n * }\n *\n * const clockService = inject(ClockService);\n * ```\n *\n * ```ts\n * @Injectable({\n * providers: [\n * {\n * useValue: 'https://api.example.com'\n * }\n * ]\n * })\n * class ApiService {\n * constructor(baseUrl: string) {\n * console.log(baseUrl);\n * }\n * }\n *\n *\n * const apiService = inject(ApiService); // log https://api.example.com\n * const apiService2 = inject(ApiService, 'https://api2.example.com'); // log https://api2.example.com\n * ```\n *\n * ```ts\n * @Injectable()\n * class Logger {\n * }\n *\n * @Injectable({\n * providers: [\n * Logger,\n * { useValue: 10 },\n * { useFactory: (): string => 'prod' }\n * ]\n * })\n * class AppService {\n * constructor(\n * logger: Logger,\n * retries: number,\n * env: string\n * ) {\n * console.log(logger, retries, env);\n * }\n * }\n *\n * const appService = inject(AppService); // log Logger {} 10 prod\n * const appService2 = inject(AppService, inject(Logger), 50, 'test'); // log Logger {} 50 test\n * ```\n *\n * @see InjectableOptionsInterface\n * @since 2.0.0\n */\n\nexport function Injectable<T extends ConstructorType = ConstructorType>(options?: InjectableOptionsInterface<T>) {\n return function (target: T): void {\n INJECTABLES.set(target, <InjectableOptionsInterface>options || {});\n };\n}\n\n/**\n * Converts an array of providers into constructor arguments for injection.\n *\n * @param providers - An optional array of providers to resolve.\n * @param args - Optional initial arguments to prepend before resolving providers.\n * @returns An array of resolved arguments including the results from providers.\n *\n * @remarks\n * This function iterates over the provided `ProvidersType` array and converts each provider\n * into its resolved value. It supports class providers, factory providers, value providers,\n * and direct constructor functions. The returned array can be used to construct instances\n * with dependencies injected in the correct order.\n *\n * @example\n * ```ts\n * const args = providersIntoArgs([{ useValue: 42 }, { useFactory: () => 'hello' }]);\n * // args = [42, 'hello']\n * ```\n *\n * @see isProviderUseClass\n * @see isProviderUseValue\n * @see isProviderUseFactory\n *\n * @since 2.0.0\n */\n\nexport function providersIntoArgs(providers?: ProvidersType, args: Array<unknown> = []): Array<unknown> {\n if (!providers) return args;\n\n const scopeAgs: Array<unknown> = args;\n for (const provider of providers.slice(scopeAgs.length)) {\n if (isProviderUseClass(provider)) {\n scopeAgs.push(inject(provider.useClass, ...providersIntoArgs(provider.providers)));\n } else if (isProviderUseFactory(provider)) {\n scopeAgs.push(provider.useFactory(...providersIntoArgs(provider.providers)));\n } else if (isProviderUseValue(provider)) {\n scopeAgs.push(provider.useValue);\n } else if (typeof provider === 'function') {\n scopeAgs.push(inject(provider));\n } else {\n throw new Error(`Unknown provider type: ${ typeof provider }`);\n }\n }\n\n return scopeAgs;\n}\n\n/**\n * Resolves and instantiates a class with its dependencies.\n *\n * @param token - The constructor function or class to instantiate.\n * @param args - Optional arguments to pass to the constructor, which can override\n * or supplement provider-resolved values.\n * @returns An instance of the class with all dependencies injected.\n *\n * @remarks\n * The `inject` function looks up metadata for the class marked with `@Injectable`.\n * It resolves all providers recursively using `providersIntoArgs`. If the class is\n * marked as a `singleton`, the same instance will be returned on further calls.\n *\n * @example\n * ```ts\n * @Injectable({ scope: 'singleton' })\n * class MyService {}\n *\n * const instance = inject(MyService);\n * ```\n *\n * @see Injectable\n * @see providersIntoArgs\n *\n * @since 2.0.0\n */\n\nexport function inject<T, Args extends Array<unknown>>(token: ConstructorLikeType<T, Args>, ...args: Partial<Args>): T {\n if (SINGLETONS.has(token)) return <T>SINGLETONS.get(token);\n\n const metadata = INJECTABLES.get(token);\n if (!metadata) throw new Error(`Cannot inject ${ token.name } – not marked @Injectable`);\n\n const scopeAgs = providersIntoArgs(metadata.providers, args);\n const instance: T = metadata.factory\n ? <T>metadata.factory(...scopeAgs)\n : new token(...scopeAgs as Args);\n\n if (metadata?.scope === 'singleton') {\n SINGLETONS.set(token, instance);\n }\n\n return instance;\n}\n\n/**\n * Forces the instantiation of a class bypassing any existing singleton instance.\n *\n * @param token - The constructor function or class to instantiate.\n * @param args - Optional arguments to pass to the constructor, which can override\n * or supplement provider-resolved values.\n * @returns A new instance of the class, even if a singleton instance already exists.\n *\n * @remarks\n * Unlike the `inject` function, `forceInject` will delete any existing singleton\n * instance for the given class before creating a new one. This is useful when you\n * need a fresh instance regardless of the singleton scope.\n *\n * @example\n * ```ts\n * @Injectable({ scope: 'singleton' })\n * class MyService {}\n *\n * const freshInstance = forceInject(MyService);\n * ```\n *\n * @see inject\n * @since 2.0.0\n */\n\nexport function forceInject<T, Args extends Array<unknown>>(token: ConstructorLikeType<T, Args>, ...args: Partial<Args>): T {\n if (SINGLETONS.has(token)) SINGLETONS.delete(token);\n\n return inject<T, Args>(token, ...args);\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { FileSnapshotInterface, ScriptSnapshotType } from './interfaces/files-model.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { resolve } from '@remotex-labs/xmap';\nimport { Injectable } from '@symlinks/symlinks.module';\nimport { closeSync, fstatSync, openSync, readFileSync } from 'fs';\n\n/**\n * In-memory cache that maintains lightweight snapshots of file contents (as TypeScript `IScriptSnapshot`)\n * together with modification time and version counters.\n *\n * Primarily used by language servers, transpiler, and incremental build systems to avoid unnecessary\n * file system reads and snapshot recreation when files have not changed.\n *\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class FilesModel {\n /**\n * Cache that maps original (possibly relative) paths → normalized absolute paths with forward slashes\n * @since 2.0.0\n */\n\n private readonly resolvedPathCache = new Map<string, string>();\n\n /**\n * Main storage: resolved absolute path → current file snapshot state\n * @since 2.0.0\n */\n\n private readonly snapshotsByPath = new Map<string, FileSnapshotInterface>();\n\n /**\n * Removes all cached paths and snapshots.\n * @since 2.0.0\n */\n\n clear(): void {\n this.snapshotsByPath.clear();\n this.resolvedPathCache.clear();\n }\n\n /**\n * Returns the current known snapshot state for the given file path, or `undefined`\n * if the file has never been touched/observed by this cache.\n *\n * @param path - filesystem path (relative or absolute)\n * @returns current snapshot data or `undefined` if not tracked yet\n *\n * @since 2.0.0\n */\n\n getSnapshot(path: string): FileSnapshotInterface | undefined {\n return this.snapshotsByPath.get(this.resolve(path));\n }\n\n /**\n * Returns an existing snapshot entry for the given file path, or creates/updates it if not tracked yet.\n *\n * @param path - Filesystem path (relative or absolute).\n * @returns The current snapshot entry for the file (existing or newly created).\n *\n * @remarks\n * This is a convenience method combining:\n * - {@link getSnapshot} (fast path when already tracked), and\n * - {@link touchFile} (tracks the file, reads content if needed, updates version/mtime).\n *\n * Use this when you need a snapshot entry and don't want to handle the `undefined` case.\n *\n * @see {@link touchFile}\n * @see {@link getSnapshot}\n *\n * @since 2.0.0\n */\n\n getOrTouchFile(path: string): FileSnapshotInterface {\n return this.snapshotsByPath.get(this.resolve(path)) ?? this.touchFile(path);\n }\n\n /**\n * Returns array containing all currently tracked resolved absolute paths.\n *\n * @returns list of normalized absolute paths (using forward slashes)\n *\n * @since 2.0.0\n */\n\n getTrackedFilePaths(): Array<string> {\n return [ ...this.snapshotsByPath.keys() ];\n }\n\n /**\n * Ensures the file is tracked and returns an up-to-date snapshot state.\n *\n * @param path - Filesystem path (relative or absolute)\n * @returns Shallow copy of the current (possibly just updated) snapshot entry\n *\n * @remarks\n * This method implements incremental file tracking with three possible outcomes:\n *\n * **Fast path (no changes):**\n * - mtime hasn't changed → returns existing state without I/O\n *\n * **Update path (file changed):**\n * - mtime changed or file is new → reads content and creates fresh `ScriptSnapshot`\n * - Increments version number for TypeScript language service invalidation\n *\n * **Error path (file unavailable):**\n * - File cannot be read (deleted/permission denied) → clears snapshot and bumps version\n * - Version increment only occurs if there was previous content (prevents silent no-ops)\n *\n * Always returns a shallow copy to prevent accidental mutation of internal state.\n *\n * Typically used in watch mode to notify TypeScript of file changes without full rebuilds.\n *\n * @example\n * ```ts\n * const snapshot = filesModel.touchFile('./src/index.ts');\n *\n * if (snapshot.contentSnapshot) {\n * languageServiceHost.getScriptSnapshot = () => snapshot.contentSnapshot;\n * languageServiceHost.getScriptVersion = () => String(snapshot.version);\n * }\n * ```\n *\n * @see {@link getSnapshot}\n * @see {@link FileSnapshotInterface}\n *\n * @since 2.0.0\n */\n\n touchFile(path: string): FileSnapshotInterface {\n const resolvedPath = this.resolve(path);\n const entry = this.snapshotsByPath.get(resolvedPath) ?? this.createEntry(resolvedPath);\n\n try {\n this.syncEntry(resolvedPath, entry);\n } catch {\n /**\n * Currently, the catch block only increments the version if the snapshot exists, otherwise silently ignores errors.\n * Suggestion: always increase the version if the file cannot be read, so TS will treat it as changed.\n */\n\n if(entry.contentSnapshot !== undefined || entry.version > 0) {\n entry.version++;\n entry.mtimeMs = 0;\n entry.contentSnapshot = undefined;\n }\n }\n\n return { ...entry };\n }\n\n /**\n * Normalizes the given path to an absolute path using forward slashes.\n * Results are cached to avoid repeated `path.resolve` + replace calls.\n *\n * @param path - any filesystem path\n * @returns normalized absolute path (always `/` separators)\n *\n * @since 2.0.0\n */\n\n resolve(path: string): string {\n const cached = this.resolvedPathCache.get(path);\n if (cached) return cached;\n\n const resolved = resolve(path);\n this.resolvedPathCache.set(path, resolved);\n\n return resolved;\n }\n\n /**\n * Creates a new snapshot entry for a resolved file path and registers it in the cache.\n *\n * @param resolvedPath - Normalized absolute file path\n * @returns A new {@link FileSnapshotInterface} with initial state (version 0, no content)\n *\n * @remarks\n * This method initializes a new file tracking entry with default values:\n * - `version`: 0 (will increment on first read)\n * - `mtimeMs`: 0 (will update on first sync)\n * - `contentSnapshot`: undefined (will populate on first sync)\n *\n * The entry is immediately added to {@link snapshotsByPath} to prevent duplicate creation.\n *\n * Called internally by {@link touchFile} when encountering a previously unseen file path.\n *\n * @since 2.1.5\n */\n\n private createEntry(resolvedPath: string): FileSnapshotInterface {\n const entry: FileSnapshotInterface = { version: 0, mtimeMs: 0, contentSnapshot: undefined };\n this.snapshotsByPath.set(resolvedPath, entry);\n\n return entry;\n }\n\n /**\n * Synchronizes a snapshot entry with the current file system state.\n *\n * @param resolvedPath - Normalized absolute path to the file\n * @param entry - The snapshot entry to update\n *\n * @remarks\n * This method performs efficient incremental updates:\n *\n * **Optimization check:**\n * - Compares current mtime with cached mtime\n * - Returns immediately if file hasn't changed (fast path)\n *\n * **Update logic:**\n * - Reads file content only when mtime differs\n * - Increments version for TypeScript invalidation\n * - Updates mtime to current value\n * - Creates TypeScript `ScriptSnapshot` from content\n *\n * **File descriptor handling:**\n * - Opens file in read mode (`'r'`)\n * - Ensures file descriptor closure via `finally` block\n * - Throws on read errors (handled by caller)\n *\n * Empty file content results in `undefined` snapshot rather than empty snapshot,\n * signaling that the file has no compilable content.\n *\n * @throws Will propagate file system errors (ENOENT, EACCES, etc.) to caller\n *\n * @since 2.1.5\n */\n\n private syncEntry(resolvedPath: string, entry: FileSnapshotInterface): void {\n const fd = openSync(resolvedPath, 'r');\n\n try {\n const { mtimeMs } = fstatSync(fd);\n if (mtimeMs === entry.mtimeMs) return;\n const content = readFileSync(fd, 'utf-8');\n\n entry.version++;\n entry.mtimeMs = mtimeMs;\n entry.contentSnapshot = content\n ? <ScriptSnapshotType> ts.ScriptSnapshot.fromString(content)\n : undefined;\n } finally {\n closeSync(fd);\n }\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { PositionInterface, FormatStackFrameInterface } from '@remotex-labs/xmap';\n\n/**\n * Imports\n */\n\nimport { readFileSync } from 'fs';\nimport { SourceService } from '@remotex-labs/xmap';\nimport { resolve, toPosix } from '@remotex-labs/xmap';\nimport { Injectable } from '@symlinks/symlinks.module';\n\n/**\n * Provides access to the framework's file paths and associated source maps.\n *\n * @remarks\n * This service manages the framework's source map files, including the main framework\n * file and any additional source files. It caches initialized {@link SourceService}\n * instances for performance.\n *\n * @example\n * ```ts\n * const frameworkService = new FrameworkService();\n * console.log(frameworkService.rootPath);\n * const sourceMap = frameworkService.sourceMap(frameworkService.filePath);\n * ```\n *\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class FrameworkService {\n /**\n * Absolute path to the current file.\n *\n * @readonly\n * @since 2.0.0\n */\n\n readonly filePath: string;\n\n /**\n * Absolute path to the distribution directory.\n *\n * @readonly\n * @since 2.0.0\n */\n\n readonly distPath: string;\n\n /**\n * Absolute path to the project root directory.\n *\n * @readonly\n * @since 2.0.0\n */\n\n readonly rootPath: string;\n\n /**\n * Cached {@link SourceService} instances for additional source files.\n * @since 2.0.0\n */\n\n private readonly sourceMaps = new Map<string, SourceService>();\n\n /**\n * Initializes a new {@link FrameworkService} instance.\n *\n * @remarks\n * Sets up the main framework source map, as well as root and distribution paths.\n *\n * @since 2.0.0\n */\n\n constructor() {\n this.filePath = import.meta.filename;\n this.setSourceFile(this.filePath);\n\n this.rootPath = this.getRootDir();\n this.distPath = this.getDistDir();\n }\n\n /**\n * Determines whether a given {@link PositionInterface} refers to a framework file.\n *\n * @param position - The position information to check\n * @returns `true` if the position is from the framework (contains \"xJet\"), otherwise `false`\n *\n * @see PositionInterface\n * @see FormatStackFrameInterface\n *\n * @since 2.2.5\n */\n\n isFrameworkFile(position: PositionInterface | FormatStackFrameInterface): boolean {\n const { source, sourceRoot } = position;\n const lowerCaseSource = source?.toLowerCase();\n\n return Boolean(\n (source && lowerCaseSource.includes('xbuild') && !lowerCaseSource.includes('xbuild.config')) ||\n (sourceRoot && sourceRoot.includes('xBuild'))\n );\n }\n\n /**\n * Retrieves a cached {@link SourceService} for a given file path.\n *\n * @param path - Absolute path to the file\n * @returns A {@link SourceService} instance if found, otherwise `undefined`\n *\n * @remarks\n * Paths are normalized before lookup. Only previously initialized source maps\n * (via {@link setSource} or {@link setSourceFile}) are available in the cache.\n *\n * @see SourceService\n * @since 2.0.0\n */\n\n getSourceMap(path: string): SourceService | undefined {\n path = resolve(path);\n if (this.sourceMaps.has(path))\n return this.sourceMaps.get(path)!;\n\n return undefined;\n }\n\n /**\n * Registers and initializes a new {@link SourceService} for a provided source map string.\n *\n * @param source - The raw source map content\n * @param path - Absolute file path associated with the source map\n * @returns A new or cached {@link SourceService} instance\n *\n * @throws Error if initialization fails\n *\n * @remarks\n * If a source map for the given path is already cached, the cached instance is returned.\n *\n * @see SourceService\n * @since 2.0.0\n */\n\n setSource(source: string, path: string): void {\n const key = resolve(path);\n\n try {\n return this.initializeSourceMap(source, key);\n } catch (error) {\n throw new Error(\n `Failed to initialize SourceService: ${ key }\\n${ error instanceof Error ? error.message : String(error) }`\n );\n }\n }\n\n /**\n * Loads and initializes a {@link SourceService} for a file and its `.map` companion.\n *\n * @param path - Absolute path to the file\n * @returns A new or cached {@link SourceService} instance\n *\n * @throws Error if the `.map` file cannot be read or parsed\n *\n * @remarks\n * This method attempts to read the `.map` file located next to the provided file.\n * If already cached, returns the existing {@link SourceService}.\n *\n * @see SourceService\n * @since 2.0.0\n */\n\n setSourceFile(path: string): void {\n if(!path) return;\n\n const key = resolve(path);\n const map = `${ path }.map`;\n\n if (this.sourceMaps.has(key))\n return;\n\n try {\n const sourceMapData = readFileSync(map, 'utf-8');\n\n return this.initializeSourceMap(sourceMapData, key);\n } catch (error) {\n throw new Error(\n `Failed to initialize SourceService: ${ key }\\n${ error instanceof Error ? error.message : String(error) }`\n );\n }\n }\n\n /**\n * Retrieves the project root directory.\n * @returns Absolute path to the project root\n *\n * @since 2.0.0\n */\n\n private getRootDir(): string {\n return toPosix(process.cwd());\n }\n\n /**\n * Retrieves the distribution directory.\n * @returns Absolute path to the distribution folder\n *\n * @since 2.0.0\n */\n\n private getDistDir(): string {\n return toPosix(import.meta.dirname);\n }\n\n /**\n * Creates and caches a new {@link SourceService} instance for a given source map.\n *\n * @param source - Raw source map content\n * @param path - Normalized file path used as the cache key\n * @returns The newly created {@link SourceService} instance\n *\n * @remarks\n * This method is only used internally by {@link setSource} and {@link setSourceFile}.\n * The instance is cached in {@link sourceMaps} for reuse.\n *\n * @see SourceService\n * @since 2.0.0\n */\n\n private initializeSourceMap(source: string, path: string): void {\n if(source?.includes('\"mappings\": \"\"'))\n return;\n\n const sourceMap = new SourceService(source, path);\n this.sourceMaps.set(path, sourceMap);\n }\n}\n","/**\n * Imports\n */\n\nimport { Observable } from '@observable/observable.module';\n\n/**\n * Transforms each emitted value using the provided transformation function.\n *\n * @template T - The input value type.\n * @template R - The output value type after transformation.\n *\n * @param project - Function that transforms each input value to an output value.\n * @returns An operator function that creates a new observable with transformed values.\n *\n * @throws Error - If the project function throws, the error is caught and emitted to the observer.\n *\n * @remarks\n * The `map` operator applies a transformation function to every value emitted by the source\n * observable and emits the transformed values. Errors thrown by the project function are\n * automatically caught and passed to the observer's error handler.\n *\n * Common use cases:\n * - Converting data formats (string to number, object property extraction)\n * - Mathematical transformations (doubling, negation)\n * - Type conversions and casting\n *\n * @example\n * ```ts\n * const numbers = new Observable<number>((observer) => {\n * observer.next?.(5);\n * observer.next?.(10);\n * });\n *\n * const doubled = numbers.pipe(map((x) => x * 2));\n *\n * doubled.subscribe((value) => console.log(value)); // Outputs: 10, 20\n * ```\n *\n * @see Observable\n * @see OperatorFunctionType\n *\n * @since 2.0.0\n */\n\nexport function map<T, R>(project: (value: T) => R) {\n return (source: Observable<T>): Observable<R> => {\n return new Observable<R>((observer) => {\n return source.subscribe({\n next: (value) => {\n try {\n const result = project(value);\n observer.next?.(result);\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: (err) => observer.error?.(err),\n complete: () => observer.complete?.()\n });\n });\n };\n}\n\n/**\n * Emits only values that are different from the previously emitted value.\n *\n * @template T - The type of values being compared.\n *\n * @param compareFn - Optional comparison function to determine equality. Defaults to strict equality (`===`).\n * @returns An operator function that creates a new observable with only distinct consecutive values.\n *\n * @remarks\n * The `distinctUntilChanged` operator filters out consecutive duplicate values using the provided\n * comparison function. Only values that differ from the last emitted value are passed through.\n * This is particularly useful for reducing redundant emissions when state changes are minimal.\n *\n * The comparison function receives the previous and current values and should return `true`\n * if they are considered equal (and thus should be filtered), or `false` if they are different\n * (and thus should be emitted).\n *\n * Errors thrown by the comparison function are caught and emitted to the observer's error handler.\n *\n * Common use cases:\n * - Avoiding redundant updates (e.g., state management)\n * - Filtering out echoed or repeated sensor data\n * - Preventing unnecessary re-renders in UI frameworks\n *\n * @example\n * ```ts\n * const values = new Observable<number>((observer) => {\n * observer.next?.(1);\n * observer.next?.(1);\n * observer.next?.(2);\n * observer.next?.(2);\n * observer.next?.(3);\n * });\n *\n * const distinct = values.pipe(distinctUntilChanged());\n *\n * distinct.subscribe((value) => console.log(value)); // Outputs: 1, 2, 3\n * ```\n *\n * @example\n * ```ts\n * // Custom comparison for objects\n * interface User { id: number; name: string; }\n *\n * const users = new Observable<User>((observer) => {\n * observer.next?.({ id: 1, name: 'Alice' });\n * observer.next?.({ id: 1, name: 'Alice' });\n * observer.next?.({ id: 2, name: 'Bob' });\n * });\n *\n * const distinctUsers = users.pipe(\n * distinctUntilChanged((prev, curr) => prev.id === curr.id)\n * );\n *\n * distinctUsers.subscribe((user) => console.log(user.name));\n * // Outputs: \"Alice\", \"Bob\"\n * ```\n *\n * @see Observable\n * @see OperatorFunctionType\n *\n * @since 2.0.0\n */\n\nexport function distinctUntilChanged<T>(\n compareFn: (previous: T, current: T) => boolean = (a, b) => a === b\n) {\n return (source: Observable<T>): Observable<T> => {\n return new Observable<T>((observer) => {\n let hasPrevious = false;\n let previous: T;\n\n return source.subscribe({\n next: (value) => {\n try {\n if(!hasPrevious) {\n previous = value;\n hasPrevious = true;\n observer.next?.(value);\n\n return;\n }\n\n if (!compareFn(previous, value)) {\n previous = value;\n observer.next?.(value);\n }\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: (err) => observer.error?.(err),\n complete: () => observer.complete?.()\n });\n });\n };\n}\n\n/**\n * Filters emitted values based on a predicate function.\n *\n * @template T - The type of values being filtered.\n *\n * @param predicate - Function that returns `true` if the value should pass through, `false` otherwise.\n * @returns An operator function that creates a new observable with only filtered values.\n *\n * @remarks\n * The `filter` operator only emits values that satisfy the predicate condition. Values that\n * do not match the condition are silently skipped. All other events (error, complete) are\n * passed through unchanged.\n *\n * Errors thrown by the predicate function are caught and passed to the observer's error handler.\n *\n * Common use cases:\n * - Filtering by value range (e.g., only positive numbers)\n * - Filtering by type or property (e.g., only objects with specific properties)\n * - Conditional emission based on complex logic\n *\n * @example\n * ```ts\n * const numbers = new Observable<number>((observer) => {\n * observer.next?.(1);\n * observer.next?.(2);\n * observer.next?.(3);\n * observer.next?.(4);\n * observer.next?.(5);\n * });\n *\n * const evens = numbers.pipe(filter((x) => x % 2 === 0));\n *\n * evens.subscribe((value) => console.log(value)); // Outputs: 2, 4\n * ```\n *\n * @see Observable\n * @see OperatorFunctionType\n *\n * @since 2.0.0\n */\n\nexport function filter<T>(predicate: (value: T) => boolean) {\n return (source: Observable<T>): Observable<T> => {\n return new Observable<T>((observer) => {\n return source.subscribe({\n next: (value) => {\n try {\n if (predicate(value)) {\n observer.next?.(value);\n }\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: (err) => observer.error?.(err),\n complete: () => observer.complete?.()\n });\n });\n };\n}\n\n/**\n * Performs a side effect for each emitted value without modifying the value.\n *\n * @template T - The type of values being processed.\n *\n * @param sideEffect - Function to execute for each emitted value. The return value is ignored.\n * @returns An operator function that creates a new observable with the side effect applied.\n *\n * @remarks\n * The `tap` operator is used for debugging, logging, or triggering side effects without\n * altering the data flow. The provided function is called for each emitted value, and the\n * original value is passed through unchanged to the resulting observable.\n *\n * Errors thrown by the side effect function are caught and passed to the observer's error handler.\n * The original value is NOT emitted if the side effect throws an error.\n *\n * Common use cases:\n * - Logging values for debugging\n * - Triggering analytics or tracking events\n * - Updating external state or UI without changing the stream\n * - Performance monitoring\n *\n * @example\n * ```ts\n * const numbers = new Observable<number>((observer) => {\n * observer.next?.(5);\n * observer.next?.(10);\n * });\n *\n * const logged = numbers.pipe(\n * tap((x) => console.log(`Processing: ${x}`))\n * );\n *\n * logged.subscribe((value) => console.log(`Received: ${value}`));\n * // Outputs:\n * // Processing: 5\n * // Received: 5\n * // Processing: 10\n * // Received: 10\n * ```\n *\n * @see Observable\n * @see OperatorFunctionType\n *\n * @since 2.0.0\n */\n\nexport function tap<T>(sideEffect: (value: T) => void) {\n return (source: Observable<T>): Observable<T> => {\n return new Observable<T>((observer) => {\n return source.subscribe({\n next: (value) => {\n try {\n sideEffect(value);\n observer.next?.(value);\n } catch (err) {\n observer.error?.(err);\n }\n },\n error: (err) => observer.error?.(err),\n complete: () => observer.complete?.()\n });\n });\n };\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { ObserverInterface, UnsubscribeType } from '@observable/observable.module';\nimport type { NextType, ErrorType, CompleteType, OperatorFunctionType } from '@observable/observable.module';\n\n/**\n * Represents a push-based collection of values that can be observed over time\n *\n * This is the core type of lightweight observable implementation.\n * It allows subscription, safe error handling and operator chaining via pipe.\n *\n * @template T - Type of values emitted by this observable\n *\n * @example\n * ```ts\n * const numbers = new Observable<number>(observer => {\n * [1, 2, 3].forEach(v => observer.next?.(v));\n * observer.complete?.();\n * return () => console.log('cleaned up');\n * });\n *\n * const sub = numbers.subscribe({\n * next: v => console.log(v),\n * complete: () => console.log('done')\n * });\n *\n * sub(); // triggers cleanup\n * ```\n *\n * @see {@link pipe}\n * @see {@link ObserverInterface}\n * @see {@link OperatorFunctionType}\n *\n * @since 2.0.0\n */\n\nexport class ObservableService<T = unknown> {\n /**\n * Creates a new observable service with a subscription handler.\n *\n * @param handler - Function called when someone subscribes.\n * It receives an observer and returns an optional cleanup function.\n *\n * @remarks\n * The handler function is called immediately when {@link subscribe} is invoked.\n * It receives the observer object and is responsible for:\n * - Calling `observer.next()` to emit values\n * - Calling `observer.error()` to emit errors\n * - Calling `observer.complete()` to signal completion\n * - Returning an optional cleanup function for resource management\n *\n * This design pattern allows for lazy initialization, external event binding and\n * fine-grained control over subscription lifecycle.\n *\n * @example\n * ```ts\n * const timerObservable = new ObservableService<number>((observer) => {\n * let count = 0;\n * const intervalId = setInterval(() => {\n * observer.next?.(count++);\n * }, 1000);\n *\n * // Return cleanup function\n * return () => clearInterval(intervalId);\n * });\n * ```\n *\n * @see ObserverInterface\n * @since 2.0.0\n */\n\n constructor(\n private readonly handler: (observer: ObserverInterface<T>) => UnsubscribeType | void\n ) {}\n\n /**\n * Subscribes to this observable and receives values, errors and completion\n *\n * @param observerOrNext - Either a full observer object or just the next handler\n * @param error - Optional error handler\n * @param complete - Optional completion handler\n * @returns Unsubscribe function — call it to stop receiving values and clean up\n *\n * @remarks\n * Supports three overload styles:\n * 1. Single observer object\n * 2. Separate next/error/complete callbacks\n * 3. Only the next callback (error and complete are optional)\n *\n * @example\n * ```ts\n * // Object style\n * subscription = source.subscribe({\n * next: v => console.log(v),\n * error: e => console.error(e),\n * complete: () => console.log('completed')\n * });\n *\n * // Callback style\n * subscription = source.subscribe(\n * v => console.log(v),\n * e => console.error(e),\n * () => console.log('completed')\n * );\n * ```\n *\n * @since 2.0.0\n */\n\n subscribe(\n observerOrNext?: ObserverInterface<T> | NextType<T>,\n error?: ErrorType,\n complete?: CompleteType\n ): UnsubscribeType {\n const observer = this.createSafeObserver(observerOrNext, error, complete);\n let cleanup: UnsubscribeType | void;\n\n try {\n cleanup = this.handler(observer);\n } catch (err) {\n observer.error?.(err);\n\n return () => {};\n }\n\n return () => {\n try {\n cleanup?.();\n } catch (err) {\n observer.error?.(err);\n }\n };\n }\n\n /**\n * Chains zero or more operators to transform this observable\n *\n * When called without arguments returns the same observable (identity).\n * Each operator receives the previous observable and returns a new one.\n *\n * @remarks\n * Type signatures are overloaded up to 5 explicit operators for best type inference.\n * After that, a rest version is used with weaker type information (the result is `Observable<T>`).\n *\n * @returns New observable (or same when no operators given)\n *\n * @since 2.0.0\n */\n\n pipe(): this;\n\n /**\n * Chains one observable operator to transform the observable.\n *\n * @template A - The output type of the first operator.\n *\n * @param op1 - First operator function to apply.\n * @returns An observable transformed by the operator.\n *\n * @see {@link pipe} for implementation details\n * @since 2.0.0\n */\n\n pipe<A>(\n op1: OperatorFunctionType<T, A>\n ): ObservableService<A>;\n\n /**\n * Chains two observable operators to transform the observable.\n *\n * @template A - The output type of the first operator.\n * @template B - The output type of the second operator.\n *\n * @param op1 - First operator function to apply.\n * @param op2 - Second operator function to apply.\n * @returns An observable transformed by both operators in sequence.\n *\n * @see {@link pipe} for implementation details\n * @since 2.0.0\n */\n\n pipe<A, B>(\n op1: OperatorFunctionType<T, A>, op2: OperatorFunctionType<A, B>\n ): ObservableService<B>;\n\n /**\n * Chains three observable operators to transform the observable.\n *\n * @template A - The output type of the first operator.\n * @template B - The output type of the second operator.\n * @template C - The output type of the third operator.\n *\n * @param op1 - First operator function to apply.\n * @param op2 - Second operator function to apply.\n * @param op3 - Third operator function to apply.\n * @returns An observable transformed by all three operators in sequence.\n *\n * @see {@link pipe} for implementation details\n * @since 2.0.0\n */\n\n pipe<A, B, C>(\n op1: OperatorFunctionType<T, A>,\n op2: OperatorFunctionType<A, B>,\n op3: OperatorFunctionType<B, C>\n ): ObservableService<C>;\n\n /**\n * Chains four observable operators to transform the observable.\n *\n * @template A - The output type of the first operator.\n * @template B - The output type of the second operator.\n * @template C - The output type of the third operator.\n * @template D - The output type of the fourth operator.\n *\n * @param op1 - First operator function to apply.\n * @param op2 - Second operator function to apply.\n * @param op3 - Third operator function to apply.\n * @param op4 - Fourth operator function to apply.\n * @returns An observable transformed by all four operators in sequence.\n *\n * @see {@link pipe} for implementation details\n * @since 2.0.0\n */\n\n pipe<A, B, C, D>(\n op1: OperatorFunctionType<T, A>,\n op2: OperatorFunctionType<A, B>,\n op3: OperatorFunctionType<B, C>,\n op4: OperatorFunctionType<C, D>\n ): ObservableService<D>;\n\n /**\n * Chains five observable operators to transform the observable.\n *\n * @template A - The output type of the first operator.\n * @template B - The output type of the second operator.\n * @template C - The output type of the third operator.\n * @template D - The output type of the fourth operator.\n * @template E - The output type of the fifth operator.\n *\n * @param op1 - First operator function to apply.\n * @param op2 - Second operator function to apply.\n * @param op3 - Third operator function to apply.\n * @param op4 - Fourth operator function to apply.\n * @param op5 - Fifth operator function to apply.\n * @returns An observable transformed by all five operators in sequence.\n *\n * @see {@link pipe} for implementation details\n * @since 2.0.0\n */\n\n pipe<A, B, C, D, E>(\n op1: OperatorFunctionType<T, A>,\n op2: OperatorFunctionType<A, B>,\n op3: OperatorFunctionType<B, C>,\n op4: OperatorFunctionType<C, D>,\n op5: OperatorFunctionType<D, E>\n ): ObservableService<E>;\n\n /**\n * Chains five or more observable operators to transform the observable.\n *\n * @template A - The output type of the first operator.\n * @template B - The output type of the second operator.\n * @template C - The output type of the third operator.\n * @template D - The output type of the fourth operator.\n * @template E - The output type of the fifth operator.\n * @template Ops - Tuple type of additional operator functions beyond the first five.\n *\n * @param op1 - First operator function to apply.\n * @param op2 - Second operator function to apply.\n * @param op3 - Third operator function to apply.\n * @param op4 - Fourth operator function to apply.\n * @param op5 - Fifth operator function to apply.\n * @param operations - Additional operator functions to apply sequentially.\n * @returns An observable transformed by all operators in sequence with the output type inferred from the final operator.\n *\n * @see {@link pipe} for implementation details\n * @since 2.0.0\n */\n\n pipe<A, B, C, D, E, Ops extends Array<OperatorFunctionType>>(\n op1: OperatorFunctionType<T, A>,\n op2: OperatorFunctionType<A, B>,\n op3: OperatorFunctionType<B, C>,\n op4: OperatorFunctionType<C, D>,\n op5: OperatorFunctionType<D, E>,\n ...operations: Ops\n ): ObservableService<\n Ops extends [...Array<unknown>, OperatorFunctionType<unknown, infer R>] ? R : T\n >;\n\n /**\n * Internal implementation of the pipe operator chain.\n *\n * @param operators - Array of operator functions to be reduced over the observable.\n * @returns The final transformed observable, or the original observable if no operators are provided.\n *\n * @remarks\n * This is the concrete implementation that executes the operator chain using a reducer pattern.\n * Each operator receives the current observable and returns a transformed observable, which becomes\n * the input for the next operator. The chain begins with the current observable instance.\n *\n * If the operator array is empty, the method returns the current observable unchanged, allowing\n * for safe calling of `pipe()` without arguments.\n *\n * Operators are applied sequentially from left to right, enabling composition of multiple\n * transformations such as mapping, filtering, debouncing and other value manipulations.\n *\n * @example\n * ```ts\n * const source = new ObservableService<number>((observer) => {\n * observer.next?.(10);\n * observer.next?.(20);\n * });\n *\n * // With operators\n * const doubled = source.pipe(\n * (obs) => new ObservableService((observer) =>\n * obs.subscribe((v) => observer.next?.(v * 2))\n * )\n * );\n *\n * // Without operators\n * const same = source.pipe();\n * ```\n *\n * @see OperatorFunctionType\n * @since 2.0.0\n */\n\n pipe<R = ObservableService<T>>(...operators: Array<OperatorFunctionType>): R {\n if (operators.length === 0) {\n return this as unknown as R;\n }\n\n return <R> operators.reduce<ObservableService>(\n (prev, op) => op(prev),\n this as ObservableService\n );\n }\n\n /**\n * Converts subscribe arguments into a consistent ObserverInterface shape\n *\n * @remarks Internal helper – not meant to be called directly\n *\n * @since 2.0.0\n */\n\n protected createSafeObserver(\n observerOrNext?: ObserverInterface<T> | NextType<T>,\n error?: ErrorType,\n complete?: CompleteType\n ): ObserverInterface<T> {\n return typeof observerOrNext === 'function'\n ? { next: observerOrNext, error, complete }\n : observerOrNext || {};\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { ObserverInterface } from '@observable/observable.module';\n\n/**\n * Imports\n */\n\nimport { ObservableService } from '@observable/services/observable.service';\n\n/**\n * A subject that acts as both an observable and an observer.\n *\n * @template T - The type of values emitted by the subject.\n *\n * @remarks\n * The `SubjectService` extends {@link Observable} to provide a multicast observable\n * that maintains a collection of active observers. Unlike a regular observable that executes\n * its handler once per subscription, a subject allows multiple subscribers to share the same\n * emission sequence and receive values emitted directly via {@link next}, {@link error},\n * and {@link complete} methods.\n *\n * This is particularly useful for:\n * - Event buses where multiple listeners need the same events\n * - Sharing a single data source across multiple subscribers\n * - Implementing pub-sub patterns\n *\n * When a subscriber unsubscribes, they are automatically removed from the observer's collection.\n *\n * @example\n * ```ts\n * const subject = new SubjectService<number>();\n *\n * // Multiple subscribers\n * subject.subscribe((value) => console.log('Observer 1:', value));\n * subject.subscribe((value) => console.log('Observer 2:', value));\n *\n * // Emit values to all subscribers\n * subject.next(42); // Both observers receive 42\n * subject.next(100); // Both observers receive 100\n *\n * // Complete the subject\n * subject.complete();\n * ```\n *\n * @see ObservableService\n * @see ObserverInterface\n *\n * @since 2.0.0\n */\n\nexport class SubjectService<T> extends ObservableService<T> {\n /**\n * Tracks whether the subject has completed.\n *\n * @remarks\n * Once the subject is completed, no further values or errors can be emitted,\n * and new subscribers will immediately receive the complete notification.\n *\n * @since 2.0.0\n */\n\n protected isCompleted = false;\n\n /**\n * Collection of all active observers subscribed to this subject.\n *\n * @remarks\n * This set maintains references to all current observers. When {@link next}, {@link error},\n * or {@link complete} is called, all observers in this collection are notified.\n *\n * @see ObserverInterface\n * @since 2.0.0\n */\n\n private observers = new Set<ObserverInterface<T>>();\n\n /**\n * Creates a new subject service with a shared observer management handler.\n *\n * @template T - The type of values emitted by the subject.\n *\n * @remarks\n * The subject initializes with a handler function that manages the observer's collection.\n * When a new subscriber is added via {@link subscribe}, the observer is added to the\n * collection and a cleanup function is returned that removes the observer when unsubscribed.\n *\n * @example\n * ```ts\n * const subject = new SubjectService<string>();\n * const unsub = subject.subscribe((value) => console.log(value));\n * subject.next('hello'); // Observer receives 'hello'\n * unsub(); // Remove observer from a subject\n * ```\n *\n * @since 2.0.0\n */\n\n constructor() {\n super((observer) => {\n if (this.isCompleted) {\n observer.complete?.();\n\n return;\n }\n\n this.observers.add(observer);\n\n return (): boolean => this.observers.delete(observer);\n });\n }\n\n /**\n * Emits a new value to all active observers.\n *\n * @template T - The type of values emitted by the subject.\n *\n * @param value - The value to emit to all observers.\n * @returns void\n *\n * @throws AggregateError - If one or more observer's `next` handler throws an error.\n *\n * @remarks\n * This method calls the `next` handler on all current observers with the provided value.\n * If an observer's next handler throws an error, it is caught and passed to that observer's\n * error handler (if provided). All errors from handlers are collected and thrown together\n * as an {@link AggregateError} after all observers have been notified.\n *\n * The observers are iterated over a snapshot of the collection to allow observers to\n * unsubscribe during emission without affecting iteration.\n *\n * @example\n * ```ts\n * const subject = new SubjectService<number>();\n *\n * subject.subscribe((value) => console.log('A:', value));\n * subject.subscribe((value) => {\n * if (value === 0) throw new Error('Zero not allowed');\n * console.log('B:', value);\n * });\n *\n * try {\n * subject.next(0); // Observer B throws, wrapped in AggregateError\n * } catch (err) {\n * if (err instanceof AggregateError) {\n * console.log(`${err.errors.length} observer(s) failed`);\n * }\n * }\n * ```\n *\n * @see AggregateError\n * @since 2.0.0\n */\n\n next(value: T): void {\n if (this.isCompleted) return;\n const errors: Array<unknown> = [];\n\n for (const o of [ ...this.observers ]) {\n try {\n o.next?.(value);\n } catch (err) {\n errors.push(err);\n try {\n o.error?.(err);\n } catch {}\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, `${ errors.length } observer(s) failed in next()`);\n }\n }\n\n /**\n * Emits an error to all active observers.\n *\n * @param err - The error to emit to all observers.\n * @returns void\n *\n * @throws AggregateError - If one or more observer's `error` handler throws an error.\n *\n * @remarks\n * This method calls the `error` handler on all current observers with the provided error.\n * If an observer's error handler throws an error, it is caught and collected. All errors\n * from handlers are thrown together as an {@link AggregateError} after all observers\n * have been notified.\n *\n * If an observer does not provide an error handler, it is skipped without any effect.\n *\n * The observers are iterated over a snapshot of the collection to allow observers to\n * unsubscribe during emission without affecting iteration.\n *\n * After an error is emitted, the subject behaves as completed (no further emissions allowed).\n *\n * @example\n * ```ts\n * const subject = new SubjectService<number>();\n *\n * subject.subscribe({\n * error: (err) => console.log('Observer A error:', err)\n * });\n *\n * subject.subscribe({\n * error: () => { throw new Error('Handler failed'); }\n * });\n *\n * try {\n * subject.error(new Error('Something went wrong'));\n * } catch (err) {\n * if (err instanceof AggregateError) {\n * console.log(`${err.errors.length} observer(s) failed`);\n * }\n * }\n * ```\n *\n * @see AggregateError\n * @since 2.0.0\n */\n\n error(err: unknown): void {\n if (this.isCompleted) return;\n const errors: Array<unknown> = [];\n\n for (const o of [ ...this.observers ]) {\n try {\n o.error?.(err);\n } catch (e) {\n errors.push(e);\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, `${ errors.length } observer(s) failed in error()`);\n }\n }\n\n /**\n * Signals completion to all observers and clears all subscriptions.\n *\n * @returns void\n *\n * @throws AggregateError - If one or more observer's `complete` handler throws an error.\n *\n * @remarks\n * This method calls the `complete` handler on all current observers, then clears the\n * observers collection to prevent further emissions. If an observer's complete handler\n * throws an error, it is caught and collected. All errors from handlers are thrown\n * together as an {@link AggregateError} after all observers have been notified.\n *\n * If an observer does not provide a complete handler, it is skipped without any effect.\n *\n * The observers are iterated over a snapshot of the collection to allow safe completion.\n * After completion, the subject will accept no further emissions and new subscribers\n * will immediately receive the complete notification.\n *\n * @example\n * ```ts\n * const subject = new SubjectService<number>();\n *\n * subject.subscribe({\n * complete: () => console.log('Observer A completed')\n * });\n *\n * subject.subscribe({\n * complete: () => { throw new Error('Handler failed'); }\n * });\n *\n * try {\n * subject.complete();\n * } catch (err) {\n * if (err instanceof AggregateError) {\n * console.log(`${err.errors.length} observer(s) failed`);\n * }\n * }\n * ```\n *\n * @see AggregateError\n * @since 2.0.0\n */\n\n complete(): void {\n if (this.isCompleted) return;\n const errors: Array<unknown> = [];\n\n\n for (const o of [ ...this.observers ]) {\n try {\n o.complete?.();\n } catch (err) {\n errors.push(err);\n }\n }\n\n this.observers.clear();\n this.isCompleted = true;\n if (errors.length > 0) {\n throw new AggregateError(errors, `${ errors.length } observer(s) failed in complete()`);\n }\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { CompleteType, NextType, ErrorType } from '@observable/observable.module';\nimport type { ObserverInterface, UnsubscribeType } from '@observable/observable.module';\n\n/**\n * Imports\n */\n\nimport { SubjectService } from '@observable/services/subject.service';\n\n/**\n * A subject that emits the most recent value to new subscribers immediately upon subscription.\n *\n * @template T - The type of values emitted by the behavior subject.\n *\n * @remarks\n * The `BehaviorSubject` extends {@link Subject} to maintain and replay the\n * latest emitted value to all new subscribers. Unlike a regular subject where new subscribers\n * only receive values emitted after subscription, behavior subjects guarantee that every new\n * subscriber immediately receives the current value.\n *\n * This is particularly useful for:\n * - State management where new subscribers need the current state\n * - Configuration or preference storage\n * - Real-time data feeds where latecomers need the latest snapshot\n *\n * The behavior subject always has a value available, even before any emission occurs, using\n * the initial value provided at construction.\n *\n * @example\n * ```ts\n * const count = new BehaviorSubject<number>(0);\n * count.subscribe((value) => console.log('Observer 1:', value)); // Immediately logs: 0\n * count.next(5);\n * count.subscribe((value) => console.log('Observer 2:', value)); // Immediately logs: 5\n * ```\n *\n * @see SubjectService\n * @see ObserverInterface\n *\n * @since 2.0.0\n */\n\nexport class BehaviorSubjectService<T> extends SubjectService<T> {\n /**\n * The most recently emitted value or the initial value.\n *\n * @remarks\n * This property stores the latest value that will be replayed to new subscribers.\n * It is initialized with the value provided to the constructor and updated whenever\n * {@link next} is called.\n *\n * @since 2.0.0\n */\n\n private lastValue: T;\n\n /**\n * Creates a new behavior subject with an initial or lazily-computed value.\n *\n * @template T - The type of values emitted by the behavior subject.\n *\n * @param initialValue - Either an initial value or a factory function that computes it.\n *\n * @remarks\n * The behavior subject requires an initial value at construction time. This value can be\n * provided in two ways:\n *\n * 1. **Direct value**: Pass the value directly (e.g., `new BehaviorSubject(0)`)\n * 2. **Factory function**: Pass a function that returns the value (e.g., `new BehaviorSubject(() => getInitialState())`)\n *\n * Using a factory function allows for lazy initialization and computation of the initial value,\n * which is useful when the initial state depends on side effects or is expensive to compute.\n *\n * @example\n * ```ts\n * // Direct value\n * const subject1 = new BehaviorSubject<number>(42);\n *\n * // Factory function for lazy initialization\n * const subject2 = new BehaviorSubject<string>(() => {\n * return localStorage.getItem('savedState') ?? 'default';\n * });\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(initialValue: T | (() => T)) {\n super();\n this.lastValue = typeof initialValue === 'function'\n ? (initialValue as () => T)()\n : initialValue;\n }\n\n /**\n * Retrieves the current value of the behavior subject.\n *\n * @template T - The type of the value.\n *\n * @returns The most recently emitted value or the initial value.\n *\n * @remarks\n * This getter provides read-only access to the current state of the behavior subject.\n * The value is always available and represents either the last emitted value or the\n * initial value if no emissions have occurred.\n *\n * @example\n * ```ts\n * const subject = new BehaviorSubject<number>(10);\n * console.log(subject.value); // Output: 10\n *\n * subject.next(20);\n * console.log(subject.value); // Output: 20\n * ```\n *\n * @since 2.0.0\n */\n\n get value(): T {\n return this.lastValue;\n }\n\n /**\n * Subscribes to the behavior subject with immediate replay of the current value.\n *\n * @template T - The type of values emitted by the behavior subject.\n *\n * @param observerOrNext - Either an observer object or a callback function for the `next` event.\n * @param error - Optional error handler callback.\n * @param complete - Optional completion handler callback.\n * @returns An unsubscribe function that removes the subscription.\n *\n * @remarks\n * This override adds behavior-specific subscription logic: immediately after the observer\n * is registered with the parent {@link SubjectService}, the current value is emitted to\n * the new observer. This ensures all subscribers, even those who join late, receive the\n * most recent value.\n *\n * The subscription follows the same modes as the parent:\n * 1. **Observer mode**: Pass a full {@link ObserverInterface}\n * 2. **Callback mode**: Pass a `next` callback with optional error and complete handlers\n * 3. **Empty mode**: Pass nothing to subscribe without any handlers\n *\n * @example\n * ```ts\n * const subject = new BehaviorSubject<number>(5);\n *\n * // Observer mode\n * const unsub1 = subject.subscribe({\n * next: (value) => console.log('A:', value)\n * }); // Immediately logs: \"A: 5\"\n *\n * subject.next(10);\n *\n * // Callback mode (late subscriber)\n * const unsub2 = subject.subscribe(\n * (value) => console.log('B:', value)\n * ); // Immediately logs: \"B: 10\"\n *\n * subject.next(15); // Both log their respective updates\n * ```\n *\n * @see ObserverInterface\n * @see SubjectService.subscribe\n *\n * @since 2.0.0\n */\n\n override subscribe(\n observerOrNext?: ObserverInterface<T> | NextType<T>,\n error?: ErrorType,\n complete?: CompleteType\n ): UnsubscribeType {\n if(this.isCompleted) return () => {};\n\n const observer = this.createSafeObserver(observerOrNext, error, complete);\n const unsub = super.subscribe(observer);\n observer.next?.(this.lastValue);\n\n return unsub;\n }\n\n /**\n * Emits a new value and updates the current state.\n *\n * @template T - The type of values emitted by the behavior subject.\n *\n * @param value - The new value to emit to all observers.\n * @returns void\n *\n * @throws AggregateError - If one or more observer's `next` handler throws an error.\n *\n * @remarks\n * This override extends the parent {@link SubjectService.next} method by storing the\n * emitted value as the current state before broadcasting to all observers. This ensures\n * that any new subscribers added after this emission will receive this value.\n *\n * Error handling follows the parent behavior: if an observer's next handler throws,\n * the error is passed to that observer's error handler (if provided), and all errors\n * are collected and thrown together as an {@link AggregateError}.\n *\n * @example\n * ```ts\n * const subject = new BehaviorSubject<number>(0);\n *\n * subject.subscribe((value) => console.log('Observer 1:', value));\n *\n * subject.next(42); // Updates internal state and notifies observers\n *\n * subject.subscribe((value) => console.log('Observer 2:', value));\n * // Immediately logs: \"Observer 2: 42\" (receives the updated state)\n * ```\n *\n * @see AggregateError\n * @see SubjectService.next\n *\n * @since 2.0.0\n */\n\n override next(value: T): void {\n if (this.isCompleted) return;\n\n this.lastValue = value;\n super.next(value);\n }\n}\n","/**\n * Checks whether a value is a plain object (not null, not an array, but an object).\n *\n * @param item - The value to check\n *\n * @returns `true` if the value is a plain object, `false` otherwise\n *\n * @remarks\n * This type guard function narrows the type to `Record<string, unknown>` when it returns `true`.\n * A value is considered a plain object if it meets all criteria:\n * - Is truthy (not `null`, `undefined`, `false`, `0`, `''`, etc.)\n * - Has type `'object'`\n * - Is not an array\n *\n * This function treats class instances, dates, and other object types as plain objects since\n * they satisfy the criteria. Use more specific checks if you need to exclude these.\n *\n * @example\n * ```ts\n * isObject({}); // true\n * isObject({ key: 'value' }); // true\n * isObject(null); // false\n * isObject([]); // false\n * isObject('string'); // false\n * isObject(new Date()); // true (it's an object, not an array)\n * ```\n *\n * @see {@link deepMerge}\n *\n * @since 2.0.0\n */\n\nexport function isObject(item: unknown): item is Record<string, unknown> {\n return !!item && typeof item === 'object' && !Array.isArray(item);\n}\n\n/**\n * Recursively merges multiple source objects into a target object with deep property merging.\n *\n * @template T - The type of the target object must extend `object`\n *\n * @param target - The target object to merge into\n * @param sources - One or more source objects to merge from\n *\n * @returns The target object with all sources merged into it\n *\n * @remarks\n * This function performs a deep merge with the following behavior:\n * - Primitive values in sources overwrite values in target\n * - Arrays are concatenated (target items first, then source items)\n * - Objects are recursively merged\n * - Sources are processed left-to-right, with later sources overwriting earlier ones\n * - The target object is mutated and returned\n *\n * Merge strategy by type:\n * - **Both arrays**: Concatenates `[...targetValue, ...sourceValue]`\n * - **Both objects**: Recursively merges properties\n * - **Source is object, target is not**: Creates a new object with source properties\n * - **Other cases**: Source value overwrites target value\n *\n * @example\n * ```ts\n * const target = { a: 1, b: { x: 10 } };\n * const source = { b: { y: 20 }, c: 3 };\n *\n * const result = deepMerge(target, source);\n * // { a: 1, b: { x: 10, y: 20 }, c: 3 }\n * ```\n *\n * @example\n * ```ts\n * // Array concatenation\n * const target = { items: [1, 2] };\n * const source = { items: [3, 4] };\n *\n * deepMerge(target, source);\n * // { items: [1, 2, 3, 4] }\n * ```\n *\n * @example\n * ```ts\n * // Multiple sources\n * const result = deepMerge(\n * { a: 1 },\n * { b: 2 },\n * { c: 3 }\n * );\n * // { a: 1, b: 2, c: 3 }\n * ```\n *\n * @see {@link isObject}\n *\n * @since 2.0.0\n */\nexport function deepMerge<T extends object>(target: T, ...sources: Array<object>): T {\n if (!sources.length) return target;\n const source = sources.shift();\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (Array.isArray(sourceValue) && Array.isArray(targetValue)) {\n Object.assign(target, { [key]: [ ...targetValue, ...sourceValue ] });\n } else if (isObject(sourceValue)) {\n Object.assign(target, {\n [key]: deepMerge(\n isObject(targetValue) ? targetValue : {},\n sourceValue\n )\n });\n } else {\n Object.assign(target, { [key]: sourceValue });\n }\n }\n\n return deepMerge(target, ...sources);\n }\n\n return target;\n}\n\n/**\n * Performs deep equality comparison between two values with support for primitives, objects, arrays, and special types.\n *\n * @param a - The first value to compare\n * @param b - The second value to compare\n * @param strictCheck - When `true`, requires arrays and objects to have the same length/key count; defaults to `true`\n *\n * @returns `true` if values are deeply equal, `false` otherwise\n *\n * @remarks\n * This function performs comprehensive equality checking with special handling for:\n * - **Primitives**: Uses strict equality (`===`) and `Object.is()` for `NaN` and `-0` handling\n * - **Dates**: Compares timestamps using `getTime()`\n * - **RegExp**: Compares source patterns and flags\n * - **URLs**: Compares full `href` strings\n * - **Arrays**: Recursively compares elements\n * - **Objects**: Recursively compares properties\n *\n * The `strictCheck` parameter controls comparison behavior:\n * - `true` (default): Arrays must have the same length, objects must have the same key count.\n * - `false`: Allows partial matches (subset comparison)\n *\n * **Null handling**:\n * Returns `false` if either value is `null` (unless both are `null`, caught by `===` check).\n *\n * @example\n * ```ts\n * equals(1, 1); // true\n * equals('test', 'test'); // true\n * equals(NaN, NaN); // true (via Object.is)\n * equals(null, null); // true\n * ```\n *\n * @example\n * ```ts\n * // Date comparison\n * const date1 = new Date('2024-01-01');\n * const date2 = new Date('2024-01-01');\n * equals(date1, date2); // true\n * ```\n *\n * @example\n * ```ts\n * // Deep object comparison\n * equals(\n * { a: 1, b: { c: 2 } },\n * { a: 1, b: { c: 2 } }\n * ); // true\n * ```\n *\n * @example\n * ```ts\n * // Strict vs non-strict array comparison\n * equals([1, 2], [1, 2, 3], true); // false (different lengths)\n * equals([1, 2], [1, 2, 3], false); // true (subset match)\n * ```\n *\n * @see {@link deepEquals}\n * @see {@link hasKey}\n *\n * @since 2.0.0\n */\n\nexport function equals(a: unknown, b: unknown, strictCheck = true): boolean {\n if (a === b) return true;\n if (Object.is(a, b)) return true;\n if (a === null || b === null) return false;\n\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n\n if (a instanceof RegExp && b instanceof RegExp)\n return a.source === b.source && a.flags === b.flags;\n\n if (URL && a instanceof URL && b instanceof URL)\n return a.href === b.href;\n\n if (typeof a === 'object' && typeof b === 'object') {\n return deepEquals(a, b, strictCheck);\n }\n\n return false;\n}\n\n/**\n * Checks whether an object or function has a specific property key.\n *\n * @param obj - The object or function to check\n * @param key - The property key to search for (string or symbol)\n *\n * @returns `true` if the key exists on the object, `false` otherwise\n *\n * @remarks\n * This function performs two checks to determine the key existence:\n * 1. Uses the `in` operator to check the prototype chain\n * 2. Uses `Object.prototype.hasOwnProperty.call()` for own properties\n *\n * Returns `false` if the value is:\n * - `null` or `undefined`\n * - Not an object or function (primitives like strings, numbers, booleans)\n *\n * This function is safer than direct property access when dealing with unknown objects,\n * as it handles `null` and `undefined` gracefully without throwing errors.\n *\n * @example\n * ```ts\n * const obj = { name: 'test' };\n * hasKey(obj, 'name'); // true\n * hasKey(obj, 'age'); // false\n * hasKey(null, 'key'); // false\n * hasKey('string', 'length'); // true\n * ```\n *\n * @example\n * ```ts\n * // Symbol keys\n * const sym = Symbol('key');\n * const obj = { [sym]: 'value' };\n * hasKey(obj, sym); // true\n * ```\n *\n * @see {@link deepEquals}\n *\n * @since 2.0.0\n */\n\nexport function hasKey(obj: unknown, key: string | symbol): boolean {\n if (obj == null || (typeof obj !== 'object' && typeof obj !== 'function'))\n return false;\n\n return key in obj || Object.prototype.hasOwnProperty.call(obj, key);\n}\n\n/**\n * Performs deep equality comparison on objects and arrays with configurable strictness.\n *\n * @param a - The first object to compare\n * @param b - The second object to compare\n * @param strictCheck - When `true`, requires same length/key count; defaults to `true`\n *\n * @returns `true` if objects are deeply equal, `false` otherwise\n *\n * @remarks\n * This internal helper function is called by {@link equals} to handle object and array comparisons.\n * It recursively compares nested structures using the following logic:\n *\n * **Array comparison**:\n * - In strict mode: Arrays must have identical length\n * - Compares elements by index using {@link equals}\n * - Order matters (different order means not equal)\n *\n * **Object comparison**:\n * - In strict mode: Objects must have same number of keys\n * - Iterates through keys of the first object\n * - Checks if each key exists in the second object\n * - Recursively compares property values using {@link equals}\n *\n * **Non-strict mode** allows partial matches where the first value can be a subset of the second.\n *\n * @example\n * ```ts\n * // Arrays\n * deepEquals([1, 2, 3], [1, 2, 3], true); // true\n * deepEquals([1, 2], [1, 2, 3], false); // true (subset)\n * deepEquals([1, 2], [1, 2, 3], true); // false (different lengths)\n * ```\n *\n * @example\n * ```ts\n * // Nested objects\n * deepEquals(\n * { user: { name: 'Alice', age: 30 } },\n * { user: { name: 'Alice', age: 30 } },\n * true\n * ); // true\n * ```\n *\n * @see {@link equals}\n * @see {@link hasKey}\n *\n * @since 2.0.0\n */\n\nfunction deepEquals(a: object, b: object, strictCheck: boolean = true): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n if(strictCheck && a.length !== b.length) return false;\n\n return a.every((val, i) => equals(val, b[i], strictCheck));\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (strictCheck && aKeys.length !== bKeys.length) return false;\n\n for (const key of aKeys) {\n if (!hasKey(b, key)) return false;\n if (!equals((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key], strictCheck)) {\n return false;\n }\n }\n\n return true;\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { PartialBuildConfigType } from '@interfaces/configuration.interface';\n\n/**\n * Default build configuration shared across all variants.\n * Provides sensible defaults for common build settings including TypeScript compilation and esbuild options.\n *\n * @remarks\n * This frozen configuration object serves as the foundation for all builds when no custom\n * common configuration is provided. It establishes defaults for:\n * - Type checking enabled\n * - Declaration file generation enabled\n * - Bundle mode with minification\n * - CommonJS output format\n * - Browser platform target\n * - Output to `dist` directory\n *\n * All nested objects are deeply frozen using `Object.freeze()` to prevent accidental mutation\n * and ensure configuration immutability. This makes the defaults safe to reference without\n * defensive copying.\n *\n * These defaults are merged with user-provided configuration, with user values taking precedence.\n * Individual variants can override any of these settings for their specific build targets.\n *\n * @example\n * ```ts\n * // User config merges with defaults\n * const userConfig: BuildConfigInterface = {\n * ...DEFAULTS_COMMON_CONFIG,\n * common: {\n * ...DEFAULTS_COMMON_CONFIG.common,\n * esbuild: {\n * ...DEFAULTS_COMMON_CONFIG.common?.esbuild,\n * format: 'esm', // Override default 'cjs'\n * minify: false // Override default true\n * }\n * },\n * variants: { ... }\n * };\n * ```\n *\n * @example\n * ```ts\n * // Accessing default values\n * const defaultFormat = DEFAULTS_COMMON_CONFIG.common?.esbuild?.format;\n * // 'cjs'\n *\n * const defaultOutDir = DEFAULTS_COMMON_CONFIG.common?.esbuild?.outdir;\n * // 'dist'\n * ```\n *\n * @see {@link PartialBuildConfigType}\n *\n * @since 2.0.0\n */\n\nexport const DEFAULTS_COMMON_CONFIG: PartialBuildConfigType = Object.freeze({\n verbose: false,\n common: Object.freeze({\n types: true,\n declaration: true,\n esbuild: Object.freeze({\n write: true,\n bundle: true,\n minify: true,\n format: 'cjs',\n outdir: 'dist',\n platform: 'browser',\n absWorkingDir: process.cwd()\n })\n })\n});\n","/**\n * Import will remove at compile time\n */\n\nimport type { UnsubscribeType, Observable } from '@observable/observable.module';\nimport type { BuildConfigInterface, DeepPartialType } from '@interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { Injectable } from '@symlinks/symlinks.module';\nimport { BehaviorSubject } from '@observable/observable.module';\nimport { deepMerge, equals } from '@components/object.component';\nimport { map, distinctUntilChanged } from '@observable/observable.module';\nimport { DEFAULTS_COMMON_CONFIG } from '@constants/configuration.constant';\n\n/**\n * Provides a centralized service for managing and observing configuration state.\n *\n * @template T - The configuration object type must extend {@link BuildConfigInterface}\n *\n * @remarks\n * Configuration changes are deeply merged with existing values, preserving unmodified properties.\n * Type-safe selectors enable reactive access to nest or derived configuration properties.\n *\n * @example\n * ```ts\n * // Initialize with default or custom configuration\n * const configService = new ConfigurationService({ name: 'myApp' });\n *\n * // Get current configuration value\n * const config = configService.getValue();\n *\n * // Get a specific configuration property\n * const name = configService.getValue(cfg => cfg.name);\n *\n * // Subscribe to configuration changes\n * const unsubscribe = configService.subscribe((config) => {\n * console.log('Config updated:', config);\n * });\n *\n * // Select and observe specific properties reactively\n * configService.select(cfg => cfg.name)\n * .subscribe(name => console.log('Name changed:', name));\n *\n * // Update configuration (deep merge)\n * configService.patch({ name: 'newApp' });\n *\n * // Cleanup subscription\n * unsubscribe();\n * ```\n *\n * @see {@link BuildConfigInterface} for the configuration contract\n * @see {@link BehaviorSubject} for the underlying reactive implementation\n *\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class ConfigurationService<T extends BuildConfigInterface> {\n /**\n * Internal configuration state managed by a {@link BehaviorSubject}.\n *\n * @remarks\n * This private property holds the current configuration and emits changes\n * to all active subscribers. All public methods delegate state access through this subject.\n *\n * @see {@link BehaviorSubject}\n *\n * @since 2.0.0\n */\n\n private readonly config$: BehaviorSubject<T>;\n\n /**\n * Initializes a new {@link ConfigurationService} instance.\n *\n * @param initialConfig - The initial configuration object (defaults to {@link DEFAULTS_COMMON_CONFIG})\n *\n * @remarks\n * - Creates a deep copy of the provided configuration to prevent external mutations\n * - If no configuration is provided, uses the default configuration\n * - The configuration is wrapped in a {@link BehaviorSubject} for reactive updates\n *\n * @example\n * ```ts\n * // With default configuration\n * const service = new ConfigurationService();\n *\n * // With custom configuration\n * const service = new ConfigurationService({ name: 'customApp' });\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(private initialConfig: T = DEFAULTS_COMMON_CONFIG as T) {\n this.config$ = new BehaviorSubject<T>(deepMerge({}, initialConfig) as T);\n }\n\n /**\n * Retrieves the current configuration value synchronously.\n *\n * @overload\n * @returns The complete current configuration object\n *\n * @example\n * ```ts\n * const config = configService.getValue();\n * console.log(config.name);\n * ```\n *\n * @since 2.0.0\n */\n\n getValue(): T;\n\n /**\n * Retrieves a computed value derived from the current configuration.\n *\n * @overload\n * @typeParam R - The return type of the selector function\n * @param selector - A function that extracts or transforms a value from the configuration\n * @returns The computed value returned by the selector function\n *\n * @remarks\n * This overload allows synchronous extraction of specific configuration properties\n * or computed values without creating an Observable subscription.\n *\n * @example\n * ```ts\n * const name = configService.getValue(cfg => cfg.name);\n * const nameLength = configService.getValue(cfg => cfg.name?.length ?? 0);\n * ```\n *\n * @since 2.0.0\n */\n\n getValue<R>(selector: (config: T) => R): R;\n\n /**\n * Implementation of getValue that handles both overloads.\n *\n * @param selector - Optional selector function for computed values\n * @returns The current configuration or a computed value derived from it\n *\n * @remarks\n * When no selector is provided, it returns the complete configuration.\n * When a selector is provided, applies it to the current configuration value\n * and returns the result.\n *\n * @since 2.0.0\n */\n\n getValue<R>(selector?: (config: T) => R): T | R {\n if (!selector)\n return this.config$.value;\n\n return selector(this.config$.value);\n }\n\n /**\n * Subscribes to configuration changes and executes a callback for each update.\n *\n * @param observer - A callback function invoked with the new configuration value on each change\n * @returns An unsubscribe function that removes this subscription when called\n *\n * @remarks\n * - The observer is immediately called with the current configuration value\n * - Subsequent calls occur whenever the configuration is updated via {@link patch}\n * - Returns an unsubscribe function for cleanup; it should be called to prevent memory leaks\n * - For more sophisticated reactive operations, consider using {@link select} instead\n *\n * @example\n * ```ts\n * const unsubscribe = configService.subscribe((config) => {\n * console.log('Configuration changed:', config);\n * });\n *\n * // Later, stop listening to changes\n * unsubscribe();\n * ```\n *\n * @see {@link select} for reactive selector-based subscriptions\n *\n * @since 1.0.0\n */\n\n subscribe(observer: (value: T) => void): UnsubscribeType {\n return this.config$.subscribe(observer);\n }\n\n /**\n * Creates an Observable that emits selected configuration values whenever they change.\n *\n * @typeParam R - The return type of the selector function\n * @param selector - A function that extracts or transforms a value from the configuration\n * @returns An Observable that emits distinct selector results on configuration changes\n *\n * @remarks\n * - Uses the provided selector to extract a computed value from the configuration\n * - Only emits values that are distinct from the previous emission (via {@link distinctUntilChanged})\n * - Distinction is determined using the {@link equals} utility for deep equality comparison\n * - Allows reactive composition using RxJS operators and subscriptions\n * - Ideal for observing nested properties or computed values without pollution from unchanged properties\n *\n * @example\n * ```ts\n * // Observe a specific property\n * configService.select(cfg => cfg.name)\n * .subscribe(name => console.log('Name is now:', name));\n *\n * // Observe a derived value\n * configService.select(cfg => cfg.name?.toUpperCase() ?? '')\n * .subscribe(uppercaseName => console.log('Upper name:', uppercaseName));\n *\n * // Compose with other RxJS operators\n * configService.select(cfg => cfg.name)\n * .pipe(\n * filter(name => name?.length > 0),\n * map(name => name.toUpperCase())\n * )\n * .subscribe(uppercaseName => console.log('Valid uppercase name:', uppercaseName));\n * ```\n *\n * @see {@link equals} for equality comparison logic\n * @see {@link distinctUntilChanged} for deduplication behavior\n * @see {@link subscribe} for simple subscription-based value access\n *\n * @since 2.0.0\n */\n\n select<R>(selector: (config: T) => R): Observable<R> {\n return this.config$.pipe(\n map(selector),\n distinctUntilChanged((prev, curr) => equals(prev, curr))\n ) as Observable<R>;\n }\n\n /**\n * Updates the configuration with partial changes, performing a deep merge.\n *\n * @param partial - A partial configuration object containing the properties to update\n *\n * @remarks\n * - Performs a deep merge of the provided partial configuration with the current configuration\n * - Unmodified properties are preserved from the current configuration\n * - The merge operation uses {@link deepMerge} to ensure nested objects are properly merged\n * - After merging, emits the updated configuration to all active subscribers via the BehaviorSubject\n * - For complete replacement rather than merging, create a new ConfigurationService instance\n *\n * @example\n * ```ts\n * // Update a single property\n * configService.patch({ name: 'updatedApp' });\n *\n * // Update multiple properties (existing properties are preserved)\n * configService.patch({\n * name: 'newApp',\n * // other properties remain unchanged\n * });\n *\n * // Patch with nested updates\n * configService.patch({\n * name: 'app',\n * // nested properties would be merged deeply if they existed\n * });\n * ```\n *\n * @see {@link subscribe} to observe changes\n * @see {@link deepMerge} for the merging implementation\n * @see {@link select} to observe specific properties reactively\n *\n * @since 1.0.0\n */\n\n patch(partial: DeepPartialType<T>): void {\n const mergedConfig = deepMerge<T>(\n {} as T,\n this.config$.value,\n partial\n );\n\n this.config$.next(mergedConfig);\n }\n\n /**\n * Replaces the entire configuration with a new configuration object.\n *\n * @param config - The complete configuration object to set\n *\n * @remarks\n * - Performs a complete replacement of the configuration (unlike {@link patch} which merges)\n * - The provided configuration object is used directly without deep cloning\n * - Emits the new configuration to all active subscribers via the BehaviorSubject\n * - Useful when you need to reset or swap the entire configuration state\n * - No properties are preserved from the previous configuration\n *\n * @example\n * ```ts\n * // Replace entire configuration\n * configService.reload({\n * verbose: true,\n * variants: { production: { esbuild: { minify: true } } },\n * common: { esbuild: { write: true } }\n * });\n *\n * // Reset to default configuration\n * configService.reload(DEFAULTS_COMMON_CONFIG);\n *\n * // Swap between different configuration profiles\n * const prodConfig = loadProductionConfig();\n * configService.reload(prodConfig);\n * ```\n *\n * @see {@link patch} for partial configuration updates with deep merging\n * @see {@link subscribe} to observe configuration changes\n * @see {@link select} to observe specific configuration properties reactively\n *\n * @since 2.0.0\n */\n\n reload(config: Partial<T>): void {\n this.config$.next(deepMerge({}, this.initialConfig, config) as T);\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface, ResolveMetadataInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { formatStack, getErrorMetadata } from '@providers/stack.provider';\n\n/**\n * A base class for custom errors with enhanced stack trace formatting and source code information.\n *\n * @remarks\n * The `xBuildBaseError` class extends the native `Error` class, adding functionality to:\n * - Parse and store structured stack trace metadata via {@link ResolveMetadataInterface}\n * - Format stack traces with syntax highlighting and source mapping\n * - Provide enhanced console output through custom Node.js inspection\n *\n * This is particularly useful for debugging errors in compiled or transpiled code by providing\n * clearer information about the original source of the error, including\n * - Original source file paths (from source maps)\n * - Highlighted code snippets showing the error location\n * - Enhanced stack frame formatting with proper indentation\n *\n * @example\n * ```ts\n * class ValidationError extends xBuildBaseError {\n * constructor(message: string, field: string) {\n * super(message, 'ValidationError');\n * this.reformatStack(this, { withFrameworkFrames: false });\n * }\n * }\n *\n * throw new ValidationError('Invalid email format', 'email');\n * ```\n *\n * @see {@link formatStack} for stack formatting\n * @see {@link getErrorMetadata} for stack parsing\n * @see {@link StackTraceInterface} for formatting options\n * @see {@link ResolveMetadataInterface} for the metadata structure\n *\n * @since 2.0.0\n */\n\nexport abstract class xBuildBaseError extends Error {\n /**\n * Structured metadata from the parsed stack trace.\n *\n * @remarks\n * Contains the parsed stack information including\n * - Original source code snippet\n * - Line and column numbers\n * - Source file path (from source maps)\n * - Formatted stack frames\n * - Syntax-highlighted code\n *\n * This property is populated by calling {@link reformatStack}.\n *\n * @since 2.0.0\n */\n\n protected errorMetadata: ResolveMetadataInterface | undefined;\n\n /**\n * Pre-formatted stack trace string ready for display.\n *\n * @remarks\n * Contains the complete formatted output including\n * - Error name and message\n * - Syntax-highlighted code snippet (if available)\n * - Enhanced stack trace with proper indentation\n *\n * This is generated by {@link formatStack} and used by the custom\n * Node.js inspector for console output.\n *\n * @since 2.0.0\n */\n\n protected formattedStack: string | undefined;\n\n /**\n * Creates a new instance of the base error class.\n *\n * @param message - The error message describing the problem\n * @param name - The error type name; defaults to `'xBuildBaseError'`\n *\n * @remarks\n * This constructor:\n * - Properly sets up the prototype chain to ensure `instanceof` checks work for derived classes\n * - Captures the stack trace if supported by the runtime environment\n * - Sets the error name for identification\n *\n * **Important:** This is a protected constructor and should only be called by derived classes.\n * Subclasses should call {@link reformatStack} after construction to enable enhanced formatting.\n *\n * @example\n * ```ts\n * class DatabaseError extends xBuildBaseError {\n * constructor(message: string, public readonly query: string) {\n * super(message, 'DatabaseError');\n * this.reformatStack(this);\n * }\n * }\n * ```\n *\n * @since 2.0.0\n */\n\n protected constructor(message: string, name: string = 'xBuildBaseError') {\n super(message);\n\n // Ensure a correct prototype chain (important for `instanceof`)\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Gets the structured stack trace metadata.\n *\n * @returns The parsed stack metadata, or `undefined` if {@link reformatStack} has not been called\n *\n * @remarks\n * Provides read-only access to the error's structured stack information,\n * which can be used for:\n * - Custom error logging\n * - Error reporting services\n * - Debugging tools\n * - Stack analysis\n *\n * @example\n * ```ts\n * try {\n * throw new ValidationError('Invalid input');\n * } catch (error) {\n * if (error instanceof xBuildBaseError) {\n * const meta = error.metadata;\n * console.log(`Error at ${meta?.source}:${meta?.line}:${meta?.column}`);\n * }\n * }\n * ```\n *\n * @since 2.0.0\n */\n\n get metadata(): ResolveMetadataInterface | undefined {\n return this.errorMetadata;\n }\n\n /**\n * Custom inspect behavior for Node.js console output.\n *\n * @returns The enhanced formatted stack trace if available, otherwise falls back to the raw stack trace\n *\n * @remarks\n * This method is automatically called by Node.js when the error is logged to the console\n * using `console.log()`, `console.error()`, or `util.inspect()`.\n *\n * The formatted output includes:\n * - Colored and styled error name and message\n * - Syntax-highlighted code snippet showing the error location\n * - Enhanced stack frames with source-mapped paths\n *\n * @example\n * ```ts\n * const error = new ValidationError('Invalid data');\n * console.log(error); // Automatically uses this method for formatting\n * ```\n *\n * @see {@link https://nodejs.org/api/util.html#custom-inspection-functions-on-objects | Node.js Custom Inspection}\n *\n * @since 2.0.0\n */\n\n [Symbol.for('nodejs.util.inspect.custom')](): string | undefined {\n return this.formattedStack || this.stack;\n }\n\n /**\n * Parses the error stack trace and generates enhanced formatting with metadata.\n *\n * @param error - The error object to parse and format\n * @param options - Optional configuration for stack trace parsing and formatting\n *\n * @remarks\n * This method performs two operations:\n * 1. Parses the error's stack trace using {@link getErrorMetadata} to extract structured metadata\n * 2. Formats the metadata using {@link formatStack} to create a styled, human-readable output\n *\n * The parsed metadata is stored in {@link errorMetadata} and the formatted string in {@link formattedStack}.\n *\n * **Typical usage:** Call this method in the constructor of derived error classes to enable\n * enhanced stack trace formatting.\n *\n * @example\n * ```ts\n * class NetworkError extends xBuildBaseError {\n * constructor(message: string, public readonly statusCode: number) {\n * super(message, 'NetworkError');\n * // Enable enhanced formatting without framework frames\n * this.reformatStack(this, {\n * withFrameworkFrames: false,\n * withNativeFrames: true\n * });\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * class CustomError extends xBuildBaseError {\n * constructor(message: string) {\n * super(message, 'CustomError');\n * // Use default options\n * this.reformatStack(this);\n * }\n * }\n * ```\n *\n * @see {@link formatStack} for formatting logic\n * @see {@link getErrorMetadata} for parsing logic\n * @see {@link StackTraceInterface} for available options\n *\n * @since 2.0.0\n */\n\n protected reformatStack(error: Error, options?: StackTraceInterface): void {\n this.errorMetadata = getErrorMetadata(error, options);\n this.formattedStack = formatStack(this.errorMetadata, error.name, error.message);\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { Argv, Options } from 'yargs';\nimport type { BaseArgumentsInterface } from '@argv/interfaces/argv-module.interface';\nimport type { UserExtensionInterface, ArgumentsInterface } from '@argv/interfaces/argv-module.interface';\n\n/**\n * Imports\n */\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { Injectable } from '@symlinks/symlinks.module';\nimport { CLI_DEFAULT_OPTIONS, CLI_USAGE_EXAMPLES } from '@argv/constants/argv.constant';\n\n/**\n * Command-line argument parser and processor for xBuild.\n *\n * @remarks\n * This module provides three levels of argument parsing to support different stages\n * of the build tool's initialization and execution:\n *\n * - **Configuration file parsing**: Early-stage parsing to locate custom config files\n * - **User extension parsing**: Parses custom options defined in configuration files\n * - **Enhanced parsing**: Full-featured CLI with help, version, examples, and validation\n *\n * The module is designed as a singleton service, ensuring consistent argument parsing\n * across the entire application lifecycle. It integrates with yargs to provide a\n * comprehensive command-line interface with:\n * - Automatic help generation with custom branding\n * - Usage examples and documentation links\n * - Type-safe argument validation\n * - Support for custom user-defined options\n * - Strict mode to catch typos and invalid options\n *\n * **Parsing Strategy:**\n *\n * The three-stage parsing approach allows xBuild to:\n * 1. First, parse just the `--config` flag to locate a configuration file\n * 2. Load configuration and discover user-defined CLI options\n * 3. Reparse all arguments with a complete option set for full validation\n *\n * This strategy enables configuration files to extend the CLI dynamically while\n * maintaining type safety and proper error handling.\n *\n * @example\n * ```ts\n * const argvModule = inject(ArgvModule);\n *\n * // Parse config path only\n * const { config } = parseConfigFile(process.argv);\n *\n * // Load config and get user extensions\n * const userOptions = await configFileProvider(config);\n *\n * // Full parse with all options\n * const args = argvModule.enhancedParse(process.argv, userOptions.userArgv);\n *\n * // User argv\n * const userArgs = argvService.parseUserArgv(process.argv, userOptions.userArgv);\n * ```\n *\n * @see {@link bannerComponent}\n * @see {@link CLI_USAGE_EXAMPLES}\n * @see {@link CLI_DEFAULT_OPTIONS}\n *\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class ArgvModule {\n /**\n * Parses command-line arguments to extract the configuration file path.\n *\n * @param argv - Raw command-line arguments array\n * @returns Parsed arguments containing the config file path\n *\n * @remarks\n * This method performs minimal parsing focused solely on extracting the `--config`\n * option. It's used during the initial bootstrap phase before the configuration\n * file is loaded, enabling xBuild to locate and load custom configuration files.\n *\n * **Parsing behavior:**\n * - Only processes the `config` option\n * - Disables help and version flags to prevent premature exit\n * - Returns a default config path if not specified\n * - Ignores all other arguments for performance\n *\n * The returned config path is used to load the build configuration file,\n * which may define additional CLI options that require reparsing with\n * the complete option set.\n *\n * This is the first step in a multi-stage parsing strategy that allows\n * configuration files to extend the CLI dynamically.\n *\n * @example\n * ```ts\n * const argvModule = inject(ArgvModule);\n * const result = argvModule.parseConfigFile(process.argv);\n *\n * console.log(result.config);\n * // Output: 'config.xbuild.ts' (default)\n * // Or: 'custom.xbuild.ts' (if --config custom.xbuild.ts was passed)\n * ```\n *\n * @example\n * ```ts\n * // Command: xBuild --config build/prod.xbuild.ts src/index.ts\n * const { config } = argvModule.parseConfigFile(process.argv);\n * // Result: { config: 'build/prod.xbuild.ts', _: [...], $0: '...' }\n * ```\n *\n * @see {@link enhancedParse}\n * @see {@link CLI_DEFAULT_OPTIONS}\n *\n * @since 2.0.0\n */\n\n parseConfigFile(argv: Array<string>): BaseArgumentsInterface & { config: string } {\n return yargs(argv)\n .help(false)\n .version(false)\n .options({\n config: CLI_DEFAULT_OPTIONS.config\n }).parseSync() as BaseArgumentsInterface & { config: string };\n }\n\n /**\n * Parses user-defined command-line options from configuration files.\n *\n * @param argv - Raw command-line arguments array\n * @param argvOptions - Optional user-defined CLI options from configuration\n * @returns Parsed arguments containing user-defined option values\n *\n * @remarks\n * This method parses custom CLI options defined in the build configuration file,\n * allowing users to extend xBuild's command-line interface with project-specific\n * arguments. It's used after loading the configuration file but before the final\n * enhanced parse.\n *\n * **Parsing behavior:**\n * - Only processes user-defined options (not xBuild defaults)\n * - Returns an empty object if no user options are provided\n * - Disables help and version to prevent premature exit\n * - Maintains type safety with generic return type\n *\n * User-defined options can include custom flags for:\n * - Build environment selection (staging, production)\n * - Feature flags and conditional compilation\n * - Custom output paths or naming schemes\n * - Integration with other build tools\n *\n * The parsed values are available in lifecycle hooks and configuration functions,\n * enabling dynamic build behavior based on CLI arguments.\n *\n * @example\n * ```ts\n * // In config.xbuild.ts\n * export default {\n * cliOptions: {\n * env: {\n * describe: 'Build environment',\n * type: 'string',\n * choices: ['dev', 'staging', 'prod']\n * }\n * }\n * };\n * ```\n *\n * @example\n * ```ts\n * const argvModule = inject(ArgvModule);\n * const userArgs = argvModule.parseUserArgv<{ env: string }>(\n * process.argv,\n * config.cliOptions\n * );\n *\n * console.log(userArgs.env);\n * // Output: 'prod' (if --env prod was passed)\n * ```\n *\n * @example\n * ```ts\n * // No user options defined\n * const userArgs = argvModule.parseUserArgv(process.argv);\n * // Returns: {}\n * ```\n *\n * @see {@link enhancedParse}\n * @see {@link parseConfigFile}\n *\n * @since 2.0.0\n */\n\n parseUserArgv<T extends BaseArgumentsInterface>(argv: Array<string>, argvOptions?: Record<string, Options>): T {\n if (!argvOptions) return <T>{};\n\n return yargs(argv)\n .help(false)\n .version(false)\n .options(argvOptions).parseSync() as T;\n }\n\n /**\n * Performs comprehensive argument parsing with full CLI features and validation.\n *\n * @param argv - Raw command-line arguments array\n * @param userExtensions - Optional user-defined CLI options from configuration\n * @returns Fully parsed and validated arguments with all xBuild and user options\n *\n * @remarks\n * This method provides the complete command-line interface experience with all\n * features enabled. It combines xBuild's default options with user-defined extensions\n * to create a unified, fully validated CLI.\n *\n * **Enhanced features:**\n * - **Custom help formatting**: Displays xBuild banner and grouped options\n * - **Usage examples**: Shows common command patterns with descriptions\n * - **Strict validation**: Catches unknown options and invalid values\n * - **Help and version**: Standard `--help` and `--version` flags\n * - **Documentation links**: Provides epilogue with documentation URL\n * - **Positional arguments**: Supports file paths as positional parameters\n *\n * **Help output structure:**\n * 1. xBuild ASCII banner\n * 2. Usage syntax\n * 3. Commands section\n * 4. xBuild Options (grouped)\n * 5. User Options (grouped, if any)\n * 6. Examples\n * 7. Documentation link\n *\n * **Option grouping:**\n * - Separates xBuild core options from user-defined options\n * - Improves help readability for complex configurations\n * - Makes custom options clearly identifiable\n *\n * The method overrides yargs' `showHelp` to inject custom branding and option\n * grouping, providing a polished CLI experience consistent with xBuild's design.\n *\n * This is the final parsing stage and should be called after configuration loading\n * is complete and all user extensions have been discovered.\n *\n * @example\n * ```ts\n * const argvModule = inject(ArgvModule);\n * const args = argvModule.enhancedParse(process.argv, {\n * env: {\n * describe: 'Build environment',\n * type: 'string',\n * choices: ['dev', 'prod']\n * }\n * });\n *\n * console.log(args.entryPoints); // ['src/index.ts']\n * console.log(args.minify); // true\n * console.log(args.env); // 'prod'\n * ```\n *\n * @example\n * ```ts\n * // Command: xBuild src/app.ts --bundle --minify --env prod\n * const args = argvModule.enhancedParse(process.argv, userOptions);\n * // Result: {\n * // entryPoints: ['src/app.ts'],\n * // bundle: true,\n * // minify: true,\n * // ...\n * // }\n * ```\n *\n * @example\n * ```ts\n * // Displaying help\n * // Command: xBuild --help\n * // Shows:\n * // - ASCII banner\n * // - Usage: xBuild [files..] [options]\n * // - xBuild Options: (--bundle, --minify, etc.)\n * // - User Options: (--env, custom options)\n * // - Examples: Common usage patterns\n * // - Documentation link\n * ```\n *\n * @see {@link parseUserArgv}\n * @see {@link parseConfigFile}\n * @see {@link bannerComponent}\n * @see {@link CLI_USAGE_EXAMPLES}\n * @see {@link CLI_DEFAULT_OPTIONS}\n *\n * @since 2.0.0\n */\n\n enhancedParse(argv: Array<string>, userExtensions: UserExtensionInterface = {}): ArgumentsInterface {\n const parser = yargs(hideBin(argv)).locale('en');\n const originalShowHelp = parser.showHelp;\n parser.showHelp = function (consoleFunction?: string | ((s: string) => void)): Argv<unknown> {\n this.group(Object.keys(CLI_DEFAULT_OPTIONS), 'xBuild Options:');\n this.group(Object.keys(userExtensions), 'user Options:');\n\n return originalShowHelp.call(this, consoleFunction as (s: string) => void);\n };\n\n parser\n .usage('Usage: xBuild [files..] [options]')\n .command('* [entryPoints..]', 'Specific files to build (supports glob patterns)', (yargs) => {\n return yargs.positional('entryPoints', {\n describe: 'Specific files to build (supports glob patterns)',\n type: 'string',\n array: true\n });\n })\n .options(userExtensions)\n .options(CLI_DEFAULT_OPTIONS)\n .epilogue('For more information, check the documentation https://remotex-labs.github.io/xBuild/')\n .help()\n .alias('help', 'h')\n .strict()\n .version();\n\n CLI_USAGE_EXAMPLES.forEach(([ command, description ]) => {\n parser.example(command, description);\n });\n\n return parser.parseSync();\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { Options } from 'yargs';\n\n/**\n * Default path to the xBuild configuration file.\n *\n * @remarks\n * This constant defines the standard location for xBuild's build configuration.\n * Used as the default value for the `--config` CLI option when no custom path is provided.\n *\n * The configuration file contains:\n * - Build variant definitions (production, development, etc.)\n * - Common build settings shared across variants\n * - esbuild compiler options\n * - TypeScript integration settings\n * - Custom lifecycle hooks\n * - Define replacements and injections\n *\n * The file is a TypeScript module that exports build configuration, enabling\n * type-safe configuration with IDE autocomplete support.\n *\n * @example\n * ```ts\n * // Default usage\n * xBuild src/index.ts\n * // Automatically looks for: config.xbuild.ts\n * ```\n *\n * @example\n * ```ts\n * // Custom config path\n * xBuild src/index.ts --config build/custom.xbuild.ts\n * ```\n *\n * @since 2.0.0\n */\n\nexport const CLI_CONFIG_PATH = 'config.xbuild.ts' as const;\n\n/**\n * Default command-line interface options and their configurations.\n *\n * @remarks\n * This constant defines all available CLI flags and arguments for the xBuild tool,\n * providing comprehensive build customization from the command line. Each option\n * includes type validation, aliases, descriptions, and default values.\n *\n * **Option Categories:**\n *\n * **Input/Output:**\n * - `entryPoints`: Source files to compile (supports glob patterns)\n * - `outdir`: Output directory for compiled files\n *\n * **Build Modes:**\n * - `watch`: Enable watch mode for automatic rebuilds\n * - `serve`: Start development server\n * - `typeCheck`: Type check only without output\n *\n * **Build Configuration:**\n * - `bundle`: Bundle dependencies into output\n * - `minify`: Minify output code\n * - `format`: Module format (cjs, esm, iife)\n * - `platform`: Target platform (browser, node, neutral)\n *\n * **TypeScript:**\n * - `declaration`: Generate .d.ts files\n * - `types`: Enable type checking during build\n * - `failOnError`: Fail build on type errors\n * - `tsconfig`: Custom tsconfig.json path\n *\n * **Configuration:**\n * - `config`: Custom build configuration file path\n * - `verbose`: Enable detailed error messages\n *\n * All options can be used individually or combined to create complex build workflows.\n * Options specified on the command line override configuration file settings.\n *\n * @example\n * ```ts\n * // Single file build with defaults\n * xBuild src/index.ts\n * ```\n *\n * @example\n * ```ts\n * // Production build with bundling and minification\n * xBuild src/app.ts --bundle --minify --format esm\n * ```\n *\n * @example\n * ```ts\n * // Development mode with watch and server\n * xBuild src/app.ts --watch --serve dist\n * ```\n *\n * @example\n * ```ts\n * // Library build with type definitions\n * xBuild src/lib.ts --declaration --format esm --outdir dist\n * ```\n *\n * @example\n * ```ts\n * // Type checking only (no output)\n * xBuild --typeCheck\n * ```\n *\n * @see {@link TSCONFIG_PATH}\n * @see {@link CLI_CONFIG_PATH}\n * @see {@link CLI_USAGE_EXAMPLES}\n *\n * @since 2.0.0\n */\n\nexport const CLI_DEFAULT_OPTIONS: Record<string, Options> = {\n entryPoints: {\n describe: 'Source files to build (supports glob patterns)',\n type: 'string',\n array: true\n },\n typeCheck: {\n describe: 'Perform type checking without building output',\n alias: 'tc',\n type: 'boolean'\n },\n platform: {\n describe: 'Target platform for the build output',\n alias: 'p',\n type: 'string',\n choices: [ 'browser', 'node', 'neutral' ] as const\n },\n serve: {\n describe: 'Start server to the <folder>',\n alias: 's',\n type: 'string'\n },\n outdir: {\n describe: 'Directory for build output files',\n alias: 'o',\n type: 'string'\n },\n declaration: {\n describe: 'Generate TypeScript declaration files (.d.ts)',\n alias: 'de',\n type: 'boolean'\n },\n watch: {\n describe: 'Watch mode - rebuild on file changes',\n alias: 'w',\n type: 'boolean'\n },\n config: {\n describe: 'Path to build configuration file',\n alias: 'c',\n type: 'string',\n default: CLI_CONFIG_PATH\n },\n tsconfig: {\n describe: 'Path to TypeScript configuration file',\n alias: 'tsc',\n type: 'string'\n },\n minify: {\n describe: 'Minify the build output',\n alias: 'm',\n type: 'boolean'\n },\n bundle: {\n describe: 'Bundle dependencies into output files',\n alias: 'b',\n type: 'boolean'\n },\n types: {\n describe: 'Enable type checking during build process',\n alias: 'btc',\n type: 'boolean'\n },\n failOnError: {\n describe: 'Fail build when TypeScript errors are detected',\n alias: 'foe',\n type: 'boolean'\n },\n format: {\n describe: 'Output module format',\n alias: 'f',\n type: 'string',\n choices: [ 'cjs', 'esm', 'iife' ]\n },\n verbose: {\n describe: 'Verbose error stack traces',\n alias: 'v',\n type: 'boolean'\n },\n build: {\n describe: 'Select an build configuration variant by names (as defined in your config file)',\n alias: 'xb',\n type: 'string',\n array: true\n }\n} as const;\n\n/**\n * Example command-line usage patterns demonstrating common build scenarios.\n *\n * @remarks\n * This constant provides a curated collection of practical CLI usage examples\n * that demonstrate how to combine xBuild options for common development workflows.\n * Each example includes the complete command and a description of its purpose.\n *\n * **Example Categories:**\n *\n * **Basic Builds:**\n * - Single file compilation with defaults\n * - Multi-file bundling with optimization\n *\n * **Development Workflows:**\n * - Watch mode with development server\n * - Custom server directory configuration\n *\n * **Library Publishing:**\n * - ESM library with type definitions\n * - Platform-specific builds\n *\n * **Validation:**\n * - Type checking without output\n * - Custom configuration files\n *\n * These examples are displayed in CLI help output and serve as quick-start\n * templates for developers learning the tool.\n *\n * @example\n * ```ts\n * // Displayed when running: xBuild --help\n * // Shows all usage examples with descriptions\n * ```\n *\n * @example\n * ```ts\n * // Example: Production library build\n * xBuild src/lib.ts --format esm --declaration\n * // Generates: dist/lib.js and dist/lib.d.ts as ESM\n * ```\n *\n * @example\n * ```ts\n * // Example: Development with hot reload\n * xBuild src/app.ts -s dist\n * // Starts: Watch mode + dev server serving from dist/\n * ```\n *\n * @see {@link CLI_DEFAULT_OPTIONS}\n *\n * @since 2.0.0\n */\n\nexport const CLI_USAGE_EXAMPLES = [\n [ 'xBuild src/index.ts', 'Build a single file with default settings' ],\n [ 'xBuild src/**/*.ts --bundle --minify', 'Bundle and minify all TypeScript files' ],\n [ 'xBuild src/app.ts -s', 'Development mode with watch and dev server' ],\n [ 'xBuild src/app.ts -s dist', 'Development mode with watch and dev server from dist folder' ],\n [ 'xBuild src/lib.ts --format esm --declaration', 'Build ESM library with type definitions' ],\n [ 'xBuild src/server.ts --platform node --outdir dist', 'Build Node.js application to dist folder' ],\n [ 'xBuild --typeCheck', 'Type check only without generating output' ],\n [ 'xBuild --config custom.xbuild.ts', 'Use custom configuration file' ]\n] as const;\n","/**\n * Imports\n */\n\nimport readline from 'readline';\nimport { exec } from 'child_process';\nimport { patchConfig } from '../index';\nimport { inject } from '@symlinks/symlinks.module';\nimport { prefix } from '@components/banner.component';\nimport { platform, exit, stdin, stdout } from 'process';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { EXIT_SIGNALS, KEY_MAPPINGS, COMMAND_MAP } from '@components/constants/interactive.constant';\n\n/**\n * Generates a formatted help message displaying available keyboard shortcuts.\n *\n * @param activeUrl - Whether to include URL-related shortcuts (show/open in browser)\n * @returns A formatted multi-line string containing all available shortcuts\n *\n * @remarks\n * Dynamically builds a help menu based on the current context. When a server is active\n * (indicated by `activeUrl`), additional shortcuts for URL display and browser opening are included.\n *\n * The output uses ANSI styling via {@link xterm} for visual hierarchy:\n * - Dimmed prefix text \"press\"\n * - Bold key name\n * - Dimmed action description\n *\n * **Shortcuts included**:\n * - `u` - Show server URL (when `activeUrl` is true)\n * - `o` - Open in browser (when `activeUrl` is true)\n * - `v` - Toggle verbose mode\n * - `r` - Reload/restart build\n * - `c` - Clear console\n * - `q` - Quit application\n *\n * @example\n * ```ts\n * const helpText = generateHelp(true);\n * console.log(helpText);\n * // Output:\n * // 🚀 Shortcuts\n * // press u to show server url\n * // press o to open in browser\n * // press v to enable / disable verbose mode\n * // ...\n * ```\n *\n * @see {@link xterm} for ANSI styling\n * @see {@link KEY_MAPPINGS} for key definitions\n *\n * @since 2.0.0\n */\n\nexport function generateHelp(activeUrl: boolean = false): string {\n const shortcuts: Array<string> = [ '🚀 Shortcuts' ];\n const prefix = xterm.dim(' press ');\n\n const addShortcut = (key: string, description: string): void => {\n shortcuts.push(`${ prefix }${ xterm.bold(key) }${ xterm.dim(description) }`);\n };\n\n if (activeUrl) {\n addShortcut(KEY_MAPPINGS.SHOW_URL, ' to show server url');\n addShortcut(KEY_MAPPINGS.OPEN_BROWSER, ' to open in browser');\n }\n\n addShortcut(KEY_MAPPINGS.VERBOSE, ' to enable / disable verbose mode');\n addShortcut(KEY_MAPPINGS.RELOAD, ' to reload');\n addShortcut(KEY_MAPPINGS.CLEAR, ' to clear console');\n addShortcut(KEY_MAPPINGS.QUIT, ' to quit\\n');\n\n return shortcuts.join('\\n');\n}\n\n/**\n * Clears the terminal screen without scrollback, moving the cursor to the top.\n *\n * @remarks\n * Performs a visual clear by:\n * 1. Calculating available terminal rows (minus 2 for buffer)\n * 2. Printing newlines to push content out of view\n * 3. Moving cursor to position (0, 0)\n * 4. Clearing all content from the cursor downward\n *\n * This approach ensures a clean visual reset without modifying scrollback history.\n * The function is safe to call regardless of terminal size; it handles small terminals\n * gracefully by ensuring `repeatCount` is never negative.\n *\n * @example\n * ```ts\n * // User presses 'c' to clear console\n * clearScreen();\n * // Terminal is cleared, cursor at top-left\n * ```\n *\n * @see {@link handleKeypress} for usage in keypress handling\n *\n * @since 2.0.0\n */\n\nexport function clearScreen(): void {\n const repeatCount = Math.max(0, stdout.rows - 2);\n if (repeatCount > 0) {\n console.log('\\n'.repeat(repeatCount));\n }\n\n readline.cursorTo(stdout, 0, 0);\n readline.clearScreenDown(stdout);\n}\n\n/**\n * Opens the specified URL in the system's default browser.\n *\n * @param url - The URL to open in the browser\n *\n * @remarks\n * Provides cross-platform browser opening by executing the appropriate shell command\n * for the current operating system:\n * - **Windows**: `start <url>`\n * - **macOS**: `open <url>`\n * - **Linux**: `xdg-open <url>` (also used as fallback)\n *\n * The function uses Node.js {@link exec} to spawn the command asynchronously.\n * No error handling is performed; if the command fails, it silently continues.\n *\n * @example\n * ```ts\n * // User presses 'o' to open server URL\n * openInBrowser('http://localhost:3000');\n * // Browser opens with the specified URL\n * ```\n *\n * @see {@link COMMAND_MAP} for platform-to-command mapping\n * @see {@link handleKeypress} for usage in keypress handling\n *\n * @since 2.0.0\n */\n\nexport function openInBrowser(url: string): void {\n const command = COMMAND_MAP[<keyof typeof COMMAND_MAP> platform] ?? 'xdg-open';\n exec(`${ command } ${ url }`);\n}\n\n/**\n * Handles keyboard input events and executes corresponding actions.\n *\n * @param code - The raw character code from the keypress event\n * @param key - The parsed key information including name, sequence, and modifiers\n * @param reload - Callback function to trigger a build reload/restart\n * @param help - Pre-generated help text to display when help key is pressed\n * @param url - Optional server URL for URL display and browser opening features\n *\n * @remarks\n * Acts as the central dispatcher for interactive terminal commands. Processes both\n * exit signals (Ctrl+C, Ctrl+D) and single-key shortcuts, executing appropriate actions\n * for each recognized input.\n *\n * **Processing flow**:\n * 1. Validates key information exists\n * 2. Checks for exit signals → exits with code 1\n * 3. Matches key name against {@link KEY_MAPPINGS}\n * 4. Executes corresponding action (clear, reload, toggle verbose, etc.)\n *\n * **Available actions**:\n * - **Clear** (`c`): Clears the terminal screen\n * - **Verbose** (`v`): Toggles verbose/debug mode via {@link ConfigurationService}\n * - **Reload** (`r`): Clears screen and invokes the reload callback\n * - **Help** (`h`): Displays the help menu\n * - **Show URL** (`u`): Prints the server URL (if provided)\n * - **Open Browser** (`o`): Opens the server URL in browser (if provided)\n * - **Quit** (`q`): Exits the process with a goodbye message\n *\n * The function safely handles cases where `url` is undefined by checking existence\n * before executing URL-dependent actions.\n *\n * @example Basic usage\n * ```ts\n * handleKeypress('r', { name: 'r' }, async () => rebuild(), helpText);\n * // Clears screen and triggers rebuild\n * ```\n *\n * @example Exit signal\n * ```ts\n * handleKeypress('\\x03', { name: 'c', sequence: '\\x03' }, reload, help);\n * // Prints \"👋 Exiting...\" and exits with code 1\n * ```\n *\n * @example Toggle verbose\n * ```ts\n * // Current verbose: false\n * handleKeypress('v', { name: 'v' }, reload, help);\n * // Prints: \"🐞 Debug mode: ENABLED\"\n * // Updates config: { verbose: true }\n * ```\n *\n * @see {@link init} for event listener setup\n * @see {@link EXIT_SIGNALS} for exit signal codes\n * @see {@link KEY_MAPPINGS} for recognized key names\n *\n * @since 2.0.0\n */\n\nexport function handleKeypress(code: string, key: readline.Key, reload: () => void, help: string, url?: string): void {\n if (!key?.name) return;\n if (key.sequence === KEY_MAPPINGS.QUIT || code === EXIT_SIGNALS.SIGINT || code === EXIT_SIGNALS.SIGQUIT) {\n console.log('\\n👋 Exiting...');\n exit(0);\n }\n\n switch (key.name) {\n case KEY_MAPPINGS.CLEAR:\n clearScreen();\n break;\n case KEY_MAPPINGS.VERBOSE:\n const verbose = inject(ConfigurationService).getValue(cfg => cfg.verbose);\n console.log(`🐞 Debug mode: ${ !verbose ? 'ENABLED' : 'DISABLED' }`);\n patchConfig({ verbose: !verbose });\n break;\n case KEY_MAPPINGS.RELOAD:\n clearScreen();\n reload();\n break;\n case KEY_MAPPINGS.HELP:\n clearScreen();\n console.log(help);\n break;\n case KEY_MAPPINGS.SHOW_URL:\n if (url) {\n console.log(`${ prefix() } ${ xterm.canaryYellow(url) }`);\n }\n break;\n case KEY_MAPPINGS.OPEN_BROWSER:\n if (url) {\n openInBrowser(url);\n }\n break;\n }\n}\n\n/**\n * Initializes the interactive terminal interface for watch mode.\n *\n * @param reload - Callback function to trigger a build reload/restart when requested\n * @param url - Optional server URL to enable URL-related shortcuts and functionality\n *\n * @remarks\n * Sets up the interactive development environment by configuring the terminal for raw\n * input mode and registering keypress event handlers. This function should be called\n * once during watch mode initialization.\n *\n * **Initialization flow**:\n * 1. **TTY check**: Exits early if stdin is not a TTY (e.g., piped input, CI environment)\n * 2. **Help generation**: Creates context-aware help text based on URL availability\n * 3. **Help display**: Prints the shortcuts menu immediately\n * 4. **Raw mode**: Enables character-by-character input without requiring Enter\n * 5. **Event setup**: Configures keypress event emission and registers handler\n *\n * **TTY requirement**:\n * Interactive mode is disabled when stdin is not a TTY. This prevents issues in:\n * - CI/CD pipelines\n * - Piped/redirected input scenarios\n * - Non-interactive shells\n *\n * **Raw mode implications**:\n * - Characters are processed immediately without buffering\n * - Standard terminal line editing (backspace, etc.) is disabled\n * - Allows single-key shortcuts without an Enter key\n *\n * The function keeps the process alive by registering an event listener, which should\n * persist for the duration of the watch session.\n *\n * @example Basic initialization\n * ```ts\n * // In watch mode without server\n * init(async () => {\n * await rebuild();\n * });\n * // Displays shortcuts without URL options\n * ```\n *\n * @example With server URL\n * ```ts\n * // In watch mode with dev server\n * init(async () => {\n * await rebuild();\n * }, 'http://localhost:3000');\n * // Displays all shortcuts including 'u' and 'o'\n * ```\n *\n * @example Non-TTY environment (CI)\n * ```ts\n * // stdin.isTTY === false\n * init(reload, url);\n * // Function returns immediately without setup\n * ```\n *\n * @see {@link generateHelp} for help text generation\n * @see {@link handleKeypress} for keypress handling logic\n *\n * @since 2.0.0\n */\n\nexport function init(reload: () => void, url?: string): void {\n if (!stdin.isTTY) return;\n const helpString = generateHelp(!!url);\n console.log(helpString);\n\n stdin.setRawMode(true);\n readline.emitKeypressEvents(stdin);\n stdin.on('keypress', (code, key) => {\n handleKeypress(code, key, reload, helpString, url);\n });\n}\n\n","/**\n * Import will remove at compile time\n */\n\nimport type { ParseGlobInterface } from '@components/interfaces/glob-component.interface';\n\n/**\n * Imports\n */\n\nimport { cwd } from 'process';\nimport { readdirSync } from 'fs';\nimport { matchesGlob } from 'path';\nimport { join } from '@remotex-labs/xmap';\n\n/**\n * Separates glob patterns into include and exclude arrays.\n *\n * @param globs - Array of glob patterns (patterns starting with '!' are treated as excludes)\n * @returns Object containing separate include and exclude pattern arrays\n *\n * @example\n * ```ts\n * const { include, exclude } = parseGlobs([\n * '**\\/*.ts',\n * '!**\\/*.test.ts',\n * '**\\/*.js',\n * '!node_modules/**'\n * ]);\n * // include: ['**\\/*.ts', '**\\/*.js']\n * // exclude: ['**\\/*.test.ts', 'node_modules/**']\n * ```\n *\n * @since 2.0.0\n */\n\nexport function parseGlobs(globs: Array<string>): ParseGlobInterface {\n const include: Array<string> = [];\n const exclude: Array<string> = [];\n\n for (const g of globs) {\n if (g.startsWith('!')) {\n exclude.push(g.slice(1));\n } else {\n include.push(g);\n }\n }\n\n return { include, exclude };\n}\n\n/**\n * Checks if a path matches any pattern in the provided array.\n *\n * @param p - Path to test against patterns\n * @param patterns - Array of glob patterns to match against\n * @returns True if a path matches at least one pattern, false otherwise\n *\n * @remarks\n * Uses early exit optimization - stops checking as soon as a match is found.\n * A pattern is treated as a match when either:\n * - The pattern string ends with the provided path\n * - `matchesGlob(p, pattern)` returns true\n *\n * @example\n * ```ts\n * matchesAny('src/app.ts', ['**\\/*.ts', '**\\/*.js']); // true\n * matchesAny('src/app.ts', ['prefix/src/app.ts']); // true (suffix check)\n * matchesAny('README.md', ['**\\/*.ts', '**\\/*.js']); // false\n * ```\n *\n * @see matchesGlob\n * @since 2.0.0\n */\n\nexport function matchesAny(p: string, patterns: Array<string>): boolean {\n for (const pattern of patterns) {\n if (pattern.endsWith(p) || matchesGlob(p, pattern)) return true;\n }\n\n return false;\n}\n\n/**\n * Determines if a directory should be excluded from traversal.\n *\n * @param relativePath - Relative path of the directory to check\n * @param exclude - Array of glob patterns for exclusion\n * @returns True if directory matches any exclude pattern, false otherwise\n *\n * @remarks\n * Checks both the directory path itself and the directory with `/**` appended\n * to properly handle patterns like `node_modules/**`.\n *\n * @example\n * ```ts\n * isDirectoryExcluded('node_modules', ['node_modules/**']); // true\n * isDirectoryExcluded('src', ['node_modules/**']); // false\n * ```\n *\n * @see matchesGlob\n * @since 2.0.0\n */\n\nexport function isDirectoryExcluded(relativePath: string, exclude: Array<string>): boolean {\n const dirWithGlob = relativePath + '/**';\n\n for (const pattern of exclude) {\n if (matchesGlob(relativePath, pattern) || matchesGlob(dirWithGlob, pattern)) {\n return true;\n }\n }\n\n return false;\n}\n\n\n/**\n * Determines if a file should be included based on include and exclude patterns.\n *\n * @param relativePath - Relative path of the file to check\n * @param include - Array of glob patterns for inclusion\n * @param exclude - Array of glob patterns for exclusion\n * @returns True if file matches include patterns and not exclude patterns, false otherwise\n *\n * @remarks\n * A file must match at least one include pattern AND not match any exclude pattern\n * to be considered for inclusion.\n *\n * @example\n * ```ts\n * shouldIncludeFile('src/app.ts', ['**\\/*.ts'], ['**\\/*.test.ts']); // true\n * shouldIncludeFile('src/app.test.ts', ['**\\/*.ts'], ['**\\/*.test.ts']); // false\n * ```\n *\n * @see matchesAny\n * @since 2.0.0\n */\n\nexport function shouldIncludeFile(relativePath: string, include: Array<string>, exclude: Array<string>): boolean {\n // Must match at least one an include pattern\n if (!matchesAny(relativePath, include)) return false;\n\n // Must NOT match any exclude pattern\n return !matchesAny(relativePath, exclude);\n}\n\n/**\n * Collects files matching glob patterns from a directory tree.\n *\n * @param baseDir - Base directory to start searching from\n * @param globs - Array of glob patterns (use '!' prefix to exclude)\n * @returns Record mapping file paths without extension to full file paths\n *\n * @remarks\n * This function performs a depth-first traversal with several optimizations:\n * - Separates include/exclude patterns once upfront\n * - Early exits on excluded directories to avoid unnecessary traversal\n * - Returns Record instead of Array for O(1) lookups\n * - Keys are relative to baseDir (without extension)\n * - Values are relative to process.cwd() (with extension)\n * - Optimized with cached length calculations and index-based loops\n * - Avoids unnecessary string allocations\n *\n * @example\n * ```ts\n * // If baseDir is 'src' and file is at <cwd>/src/errors/uncaught-error.spec.ts\n * const files = collectFilesFromGlob('src', ['**\\/*.ts']);\n * // Returns: { 'errors/uncaught-error.spec': 'src/errors/uncaught-error.spec.ts' }\n * ```\n *\n * @since 2.0.0\n */\n\nexport function collectFilesFromGlob(baseDir: string, globs: Array<string>): Record<string, string> {\n const { include, exclude } = parseGlobs(globs);\n const collected: Record<string, string> = Object.create(null);\n const cwdPath = cwd();\n const rootDirLength = cwdPath.length + 1; // +1 for trailing slash\n const baseDirLength = baseDir.length + 1; // +1 for trailing slash\n const hasExcludes = exclude.length > 0;\n\n function walk(dir: string): void {\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n const len = entries.length;\n for (let i = 0; i < len; i++) {\n const entry = entries[i];\n const fullPath = join(dir, entry.name);\n const relativeFromBase = fullPath.slice(baseDirLength);\n\n if (entry.isDirectory()) {\n if (!hasExcludes || !isDirectoryExcluded(relativeFromBase, exclude)) walk(fullPath);\n continue;\n }\n\n if (hasExcludes && matchesAny(relativeFromBase, exclude)) continue;\n if (matchesAny(relativeFromBase, include)) {\n const relativeFromRoot = fullPath.slice(rootDirLength);\n const lastDotIndex = relativeFromBase.lastIndexOf('.');\n const keyPath = lastDotIndex > 0 ? relativeFromBase.slice(0, lastDotIndex) : relativeFromBase;\n\n collected[keyPath] = relativeFromRoot;\n }\n }\n }\n\n walk(baseDir);\n\n return collected;\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { DiagnosticInterface } from '@typescript/typescript.module';\n\n/**\n * Represents a TypeScript type checking error with associated diagnostic information.\n *\n * @remarks\n * The `TypesError` class extends the native `Error` class to provide enhanced error reporting\n * for TypeScript type checking failures. It captures and preserves diagnostic information\n * from TypeScript's type checker, allowing structured access to individual diagnostics.\n *\n * **Error context**:\n * Each `TypesError` can contain zero or more {@link DiagnosticInterface} objects that provide:\n * - Source file location (file path, line, column)\n * - Diagnostic code for error identification\n * - Detailed error messages\n *\n * @example\n * ```ts\n * import { TypesError } from '@errors/types.error';\n * import type { DiagnosticInterface } from '@typescript/interfaces/typescript.interface';\n *\n * // Create error with diagnostics from type checker\n * const diagnostics: DiagnosticInterface[] = [\n * {\n * file: 'src/index.ts',\n * line: 10,\n * column: 5,\n * code: 2322,\n * message: 'Type \"string\" is not assignable to type \"number\"'\n * }\n * ];\n *\n * throw new TypesError('Type checking failed', diagnostics);\n * ```\n *\n * @see {@link Typescript.check} for type checking context\n * @see {@link DiagnosticInterface} for diagnostic structure\n *\n * @since 2.0.0\n */\n\nexport class TypesError extends Error {\n\n /**\n * Array of diagnostic information from TypeScript type checking.\n *\n * @remarks\n * Contains all diagnostics collected during type checking that led to this error.\n * May be empty if the error is not directly related to specific diagnostics.\n *\n * Each diagnostic includes:\n * - **file**: Source file path relative to project root\n * - **line**: 1-based line number where the issue occurred\n * - **column**: 1-based column number where the issue occurred\n * - **code**: TypeScript error code for identifying error type\n * - **message**: Human-readable error description\n *\n * Read-only to prevent modification after error creation.\n *\n * @example\n * ```ts\n * const error = new TypesError('Type check failed', diagnostics);\n * for (const diag of error.diagnostics) {\n * console.log(`${diag.file}:${diag.line}:${diag.column} - ${diag.message}`);\n * }\n * ```\n *\n * @see {@link DiagnosticInterface}\n *\n * @since 2.0.0\n */\n\n readonly diagnostics: Array<DiagnosticInterface>;\n\n /**\n * Creates a new instance of `TypesError`.\n *\n * @param message - Optional error message describing the type checking failure\n * @param diagnostics - Optional array of diagnostic information (defaults to an empty array)\n *\n * @remarks\n * Initializes the error with:\n * 1. Message passed to parent `Error` class\n * 2. Error name set to `'TypesError'` for identification\n * 3. Stored diagnostics array for later inspection\n * 4. Prototype chain properly configured for instanceof checks\n *\n * **Prototype chain setup**:\n * Sets the prototype explicitly to ensure `instanceof` checks work correctly\n * across different execution contexts and transpilation scenarios.\n *\n * @example\n * ```ts\n * // Create error with message and diagnostics\n * const error = new TypesError('Type checking failed', [{\n * file: 'src/app.ts',\n * line: 42,\n * column: 15,\n * code: 2339,\n * message: 'Property \"config\" does not exist'\n * }]);\n *\n * // Create error with a message only\n * const simple = new TypesError('Type checking failed');\n *\n * // Create error with diagnostics only\n * const diag = new TypesError(undefined, diagnostics);\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(message?: string, diagnostics: Array<DiagnosticInterface> = []) {\n super(message);\n this.name = 'TypesError';\n this.diagnostics = diagnostics;\n\n Object.setPrototypeOf(this, TypesError.prototype);\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xBuildBaseError } from '@errors/base.error';\n\n/**\n * Represents a generic xBuild framework error.\n *\n * Extends {@link xBuildBaseError} and automatically formats the stack trace\n * according to the provided options.\n *\n * @remarks\n * This class is intended for general-purpose errors within the xBuild framework.\n * The stack trace is formatted automatically during construction, with\n * framework-specific frames included by default.\n *\n * @example\n * ```ts\n * throw new xBuildError('An unexpected error occurred');\n * ```\n *\n * @since 1.0.0\n */\n\nexport class xBuildError extends xBuildBaseError {\n\n /**\n * Creates a new instance of `xBuildError`.\n *\n * @param message - The error message to display\n * @param options - Optional stack trace formatting options (default includes framework frames)\n *\n * @remarks\n * The constructor passes the message to the base `xBuildBaseError` class,\n * then reformats the stack trace using {@link xBuildBaseError.reformatStack}.\n *\n * @since 1.0.0\n */\n\n constructor(message: string, options: StackTraceInterface = { withFrameworkFrames: true }) {\n super(message);\n this.reformatStack(this, options);\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { PartialMessage } from 'esbuild';\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xBuildBaseError } from '@errors/base.error';\nimport { getErrorMetadata, formatStack } from '@providers/stack.provider';\n\n/**\n * Normalized runtime error wrapper for esbuild diagnostics.\n *\n * @remarks\n * `esBuildError` converts an esbuild {@link PartialMessage} into an {@link xBuildBaseError}\n * with framework-aware metadata and a formatted stack string.\n *\n * Construction behavior:\n * - Uses `message.text` as the runtime error message (defaults to empty string)\n * - Copies `message.id` to {@link id} (defaults to empty string)\n * - Builds structured metadata via {@link getErrorMetadata}\n * - Replaces `stack` using {@link formatStack}, including any diagnostic notes\n *\n * @example\n * ```ts\n * const message = {\n * id: 'transform',\n * text: 'Unexpected token',\n * location: { file: 'src/index.ts', line: 1, column: 5 },\n * notes: [{ text: 'Check syntax near this token' }]\n * };\n *\n * const error = new esBuildError(message);\n * console.error(error.id); // \"transform\"\n * console.error(error.stack);\n * ```\n *\n * @see {@link xBuildBaseError}\n * @see {@link getErrorMetadata}\n * @see {@link formatStack}\n *\n * @since 2.0.0\n */\n\nexport class esBuildError extends xBuildBaseError {\n /**\n * Optional esbuild diagnostic identifier copied from `PartialMessage.id`.\n *\n * @remarks\n * This value is useful for categorizing diagnostics by producer (for example,\n * plugin- or phase-specific IDs). When absent in the source message, it defaults\n * to an empty string.\n *\n * @since 2.0.0\n */\n\n readonly id: string;\n\n /**\n * Creates a new esbuild error with formatted output and metadata.\n *\n * @param message - The esbuild {@link PartialMessage} containing diagnostic details\n * @param options - Optional stack parsing/formatting options used when deriving metadata\n *\n * @remarks\n * The constructor:\n * 1. Initializes the base error with `message.text ?? ''`\n * 2. Persists `message.id ?? ''` on {@link id}\n * 3. If `message.detail` is an `Error`, uses its `message` and `stack` as runtime values\n * 4. Builds structured metadata from either the original message or `detail` error\n * 5. Produces formatted output (stack replacement for message-based diagnostics, or\n * formatted inspector output for `detail`-based diagnostics)\n *\n * The error name is always set to `'esBuildError'`. Formatted output includes:\n * - Error name and message with color coding\n * - Any diagnostic notes from esbuild\n * - Highlighted code snippet showing the error location\n * - Enhanced stack trace with file path and position\n *\n * @see {@link getErrorMetadata} for formatting logic\n * @see {@link PartialMessage} for esbuild message structure\n *\n * @since 2.0.0\n */\n\n constructor(message: PartialMessage, options?: StackTraceInterface) {\n super(message.text ?? '', 'esBuildError');\n\n this.id = message.id ?? '';\n if(message.detail instanceof Error) {\n this.stack = message.detail.stack;\n this.message = message.detail.message;\n this.reformatStack(message.detail, options);\n } else {\n this.errorMetadata = getErrorMetadata(message, { withFrameworkFrames: true });\n this.stack = formatStack(this.errorMetadata, this.name, this.message, message.notes);\n }\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { BuildResult, Message } from 'esbuild';\nimport type { BuildResultInterface } from './interfaces/esbuild-messages-provider.interface';\n\n/**\n * Imports\n */\n\nimport { TypesError } from '@errors/types.error';\nimport { xBuildError } from '@errors/xbuild.error';\nimport { xBuildBaseError } from '@errors/base.error';\nimport { esBuildError } from '@errors/esbuild.error';\n\n/**\n * Converts an esbuild message to a normalized Error instance.\n *\n * @param msg - The esbuild message object containing error or warning details\n * @returns A normalized Error instance appropriate for the message type\n *\n * @remarks\n * This function handles different types of esbuild messages and converts them to the appropriate\n * error classes used throughout the xBuild system. It prioritizes preserving existing error\n * instances while wrapping raw messages in appropriate error types.\n *\n * **Conversion priority**:\n * 1. If `msg.detail` is already an `xBuildBaseError` or `TypesError`, return it unchanged\n * 2. If `msg.detail` is any other Error, wrap it in `VMRuntimeError` with framework frames\n * 3. If `msg.location` exists, create an `esBuildError` with a formatted code snippet\n * 4. Otherwise, wrap the message text in a `VMRuntimeError`\n *\n * This normalization ensures consistent error handling and reporting throughout the build\n * pipeline, with appropriate context and formatting for each error type.\n *\n * @example\n * ```ts\n * // Message with location information\n * const msg: Message = {\n * text: 'Unexpected token',\n * location: { file: 'src/index.ts', line: 10, column: 5 }\n * };\n * const error = normalizeMessageToError(msg);\n * // Returns esBuildError with formatted code snippet\n *\n * // Message with existing error detail\n * const msgWithError: Message = {\n * text: 'Build failed',\n * detail: new TypesError('Type checking failed', [])\n * };\n * const error2 = normalizeMessageToError(msgWithError);\n * // Returns the TypesError unchanged\n * ```\n *\n * @see {@link TypesError}\n * @see {@link esBuildError}\n * @see {@link VMRuntimeError}\n * @see {@link xBuildBaseError}\n *\n * @since 2.0.0\n */\n\nexport function normalizeMessageToError(msg: Message | esBuildError): Error | undefined {\n if (msg instanceof xBuildBaseError)\n return msg;\n\n if (msg.detail instanceof xBuildBaseError || msg.detail instanceof TypesError)\n return msg.detail;\n\n if (msg.detail instanceof Error)\n return new esBuildError(msg, { withFrameworkFrames: true });\n\n if (msg.location)\n return new esBuildError(msg);\n\n if(msg.text)\n return new xBuildError(msg.text);\n}\n\n/**\n * Processes an array of esbuild messages and converts them to normalized errors.\n *\n * @param messages - Array of esbuild message objects to process\n * @param target - Array to populate with normalized error instances\n *\n * @remarks\n * This function iterates through esbuild messages and converts each one to a normalized\n * Error instance using {@link normalizeMessageToError}, appending the results to the\n * target array.\n *\n * The target array is modified in place, allowing errors and warnings from different\n * sources to be aggregated into the same collection.\n *\n * **Processing behavior**:\n * - Each message is converted independently\n * - Conversion failures do not stop processing of remaining messages\n * - a Target array is modified in place (no return value)\n * - Empty message arrays are handled gracefully\n *\n * Common use cases:\n * - Converting esbuild error arrays to normalized errors\n * - Converting esbuild warning arrays to normalized errors\n * - Aggregating messages from multiple build results\n *\n * @example\n * ```ts\n * const buildResult: BuildResult = await build({ ... });\n * const errors: Array<Error> = [];\n * const warnings: Array<Error> = [];\n *\n * // Process errors and warnings\n * processEsbuildMessages(buildResult.errors, errors);\n * processEsbuildMessages(buildResult.warnings, warnings);\n *\n * console.log(`Build completed with ${errors.length} errors and ${warnings.length} warnings`);\n * ```\n *\n * @see {@link enhancedBuildResult}\n * @see {@link normalizeMessageToError}\n *\n * @since 2.0.0\n */\n\nexport function processEsbuildMessages(messages: Array<Message> = [], target: Array<Error>): void {\n for (const msg of messages) {\n const error = normalizeMessageToError(msg);\n if(error) target.push(error);\n }\n}\n\n/**\n * Converts esbuild's BuildResult into xBuild's BuildResultInterface with normalized errors.\n *\n * @param source - Partial esbuild BuildResult containing build artifacts and messages\n * @returns A BuildResultInterface with normalized errors and warnings\n *\n * @remarks\n * This function transforms esbuild's build result into the xBuild-specific result interface,\n * converting all error and warning messages to normalized Error instances while preserving\n * build artifacts like metafiles, output files, and mangle cache.\n *\n * **Transformation process**:\n * 1. Creates a new BuildResultInterface with empty error/warning arrays\n * 2. Copies build artifacts (metafile, outputFiles, mangleCache) directly\n * 3. Processes errors array through {@link processEsbuildMessages}\n * 4. Processes warnings array through {@link processEsbuildMessages}\n * 5. Returns the fully populated result object\n *\n * **Preserved artifacts**:\n * - `metafile`: Build metadata including inputs, outputs, and dependencies\n * - `outputFiles`: Generated file contents when `write: false`\n * - `mangleCache`: Identifier mangling cache for consistent minification\n *\n * All esbuild Message objects are converted to Error instances, providing consistent\n * error handling throughout the xBuild system with proper stack traces, formatting,\n * and error classification.\n *\n * @example\n * ```ts\n * const esbuildResult = await build({\n * entryPoints: ['src/index.ts'],\n * write: false,\n * metafile: true\n * });\n *\n * const result = enhancedBuildResult(esbuildResult);\n * // result.errors: Array<Error> (normalized)\n * // result.warnings: Array<Error> (normalized)\n * // result.metafile: Metafile (preserved)\n * // result.outputFiles: OutputFile[] (preserved)\n *\n * console.log(`Build produced ${result.errors.length} errors`);\n * ```\n *\n * @see {@link BuildResultInterface}\n * @see {@link processEsbuildMessages}\n * @see {@link normalizeMessageToError}\n *\n * @since 2.0.0\n */\n\nexport function enhancedBuildResult(source: Partial<BuildResult>): BuildResultInterface {\n const target: BuildResultInterface = {\n errors: [],\n warnings: [],\n metafile: source.metafile,\n outputFiles: source.outputFiles,\n mangleCache: source.mangleCache\n };\n\n processEsbuildMessages(source.errors, target.errors);\n processEsbuildMessages(source.warnings, target.warnings);\n\n return target;\n}\n\n/**\n * Type guard that checks if an unknown value is an esbuild BuildResult error object.\n *\n * @param error - The value to check, typically from a catch block\n * @returns `true` if the value is a BuildResult with errors property, `false` otherwise\n *\n * @remarks\n * This type guard validates that an error object follows the esbuild BuildResult structure,\n * which includes an `errors` property. It's useful for distinguishing between esbuild-specific\n * errors and other error types during error handling.\n *\n * The function performs two checks:\n * 1. Verifies the value is an object (not null)\n * 2. Checks for the presence of an `errors` property\n *\n * When the function returns `true`, TypeScript will narrow the type of the parameter to\n * `BuildResult`, allowing type-safe access to BuildResult properties like `errors`,\n * `warnings`, `metafile`, etc.\n *\n * Common use cases:\n * - Catch block error type discrimination\n * - Conditional error handling based on an error source\n * - Type narrowing for BuildResult-specific error processing\n *\n * @example\n * ```ts\n * try {\n * await build({ entryPoints: ['src/index.ts'] });\n * } catch (error) {\n * if (isBuildResultError(error)) {\n * // TypeScript knows error is BuildResult here\n * console.error(`Build failed with ${error.errors.length} errors`);\n * processEsbuildMessages(error.errors, errorList);\n * } else if (error instanceof Error) {\n * // Handle generic errors\n * console.error(error.message);\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * // In error aggregation\n * const errors: Array<Error> = [];\n *\n * if (isBuildResultError(caughtError)) {\n * const result = enhancedBuildResult(caughtError);\n * errors.push(...result.errors);\n * } else {\n * errors.push(new Error(String(caughtError)));\n * }\n * ```\n *\n * @see {@link BuildResult}\n * @see {@link enhancedBuildResult}\n * @see {@link processEsbuildMessages}\n *\n * @since 2.0.0\n */\n\nexport function isBuildResultError(error: unknown): error is BuildResult {\n return typeof error === 'object' && error !== null && 'errors' in error;\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { IncomingMessage, ServerResponse } from 'http';\nimport type { ServerConfigurationInterface } from '@server/interfaces/server.interface';\n\n/**\n * Imports\n */\n\nimport * as http from 'http';\nimport * as https from 'https';\nimport { extname } from 'path';\nimport { readFileSync } from 'fs';\nimport html from './html/server.html';\nimport { resolve, join } from '@remotex-labs/xmap';\nimport { inject } from '@symlinks/symlinks.module';\nimport { prefix } from '@components/banner.component';\nimport { readdir, stat, readFile } from 'fs/promises';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * Provides a basic HTTP/HTTPS server module with static file serving\n * and directory listing capabilities.\n *\n * @remarks\n * The `ServerModule` supports serving static files, directories, and\n * optional HTTPS configuration. It handles request logging and error\n * responses and can invoke user-defined hooks via the configuration.\n *\n * @example\n * ```ts\n * const server = new ServerModule({ port: 3000, host: 'localhost' }, '/var/www');\n * server.start();\n * ```\n *\n * @see ServerConfigurationInterface\n * @since 2.0.0\n */\n\nexport class ServerModule {\n\n /**\n * The underlying HTTP or HTTPS server instance.\n *\n * @remarks\n * This property holds the active server instance created by either {@link startHttpServer}\n * or {@link startHttpsServer}. It remains undefined until {@link start} is called.\n * The server instance is used to manage the lifecycle of the HTTP/HTTPS server,\n * including stopping and restarting operations.\n *\n * @see start\n * @see stop\n * @see restart\n * @see startHttpServer\n * @see startHttpsServer\n *\n * @since 2.0.0\n */\n\n private server?: http.Server;\n\n /**\n * Normalized absolute root directory for serving files.\n *\n * @readonly\n * @since 2.0.0\n */\n\n private readonly rootDir: string;\n\n /**\n * Injected {@link FrameworkService} instance used for path resolution and framework assets.\n *\n * @readonly\n * @see FrameworkService\n *\n * @since 2.0.0\n */\n\n private readonly framework = inject(FrameworkService);\n\n /**\n * Initializes a new {@link ServerModule} instance.\n *\n * @param config - Server configuration including host, port, HTTPS options, and hooks.\n * @param dir - Root directory from which files will be served.\n *\n * @example\n * ```ts\n * import { ServerProvider } from './server-provider';\n *\n * const serverConfig = {\n * port: 8080,\n * keyfile: './path/to/keyfile',\n * certfile: './path/to/certfile',\n * onRequest: (req, res, next) => { /* custom request handling *\\/ }\n * };\n * const provider = new ServerProvider(serverConfig, './public');\n * provider.start();\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(readonly config: ServerConfigurationInterface, dir: string) {\n this.rootDir = resolve(dir);\n this.config.port ||= 0;\n this.config.host ||= 'localhost';\n }\n\n /**\n * Starts the HTTP or HTTPS server based on configuration.\n *\n * @returns A promise that resolves when the server is fully started and listening.\n *\n * @remarks\n * This method performs the following steps:\n * 1. Invokes the optional {@link ServerConfigurationInterface.onStart} hook if provided.\n * 2. Determines whether to start an HTTPS or HTTP server based on the {@link ServerConfigurationInterface.https} flag.\n * 3. Calls {@link startHttpsServer} if HTTPS is enabled, otherwise calls {@link startHttpServer}.\n *\n * @example\n * ```ts\n * const server = new ServerModule({\n * port: 3000,\n * host: 'localhost',\n * https: true,\n * onStart: () => console.log('Server starting...')\n * }, '/var/www');\n * await server.start();\n * ```\n *\n * @see stop\n * @see restart\n * @see startHttpServer\n * @see startHttpsServer\n * @see ServerConfigurationInterface\n *\n * @since 2.0.0\n */\n\n async start(): Promise<void> {\n if (this.config.https)\n return await this.startHttpsServer();\n\n await this.startHttpServer();\n }\n\n /**\n * Stops the running HTTP or HTTPS server.\n *\n * @returns A promise that resolves when the server is fully stopped.\n *\n * @remarks\n * This method gracefully shuts down the server by closing all active connections.\n * If no server is currently running, it logs a message and returns early.\n * Once stopped, the {@link server} instance is set to `undefined`.\n *\n * @example\n * ```ts\n * const server = new ServerModule({ port: 3000, host: 'localhost' }, '/var/www');\n * server.start();\n * // Later...\n * await server.stop();\n * ```\n *\n * @see start\n * @see server\n * @see restart\n *\n * @since 2.0.0\n */\n\n async stop(): Promise<void> {\n if (!this.server) {\n console.log(prefix(), xterm.gray('No server is currently running.'));\n\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.server!.close(err => {\n if (err) reject(err);\n else resolve();\n });\n });\n\n console.log(prefix(), xterm.dim('Server stopped.'));\n this.server = undefined;\n }\n\n /**\n * Restarts the HTTP or HTTPS server.\n *\n * @returns A promise that resolves when the server has been stopped and restarted.\n *\n * @remarks\n * This method performs a graceful restart by first calling {@link stop} to shut down\n * the current server instance, then calling {@link start} to create a new server\n * with the same configuration. This is useful when configuration changes need to be\n * applied or when recovering from errors.\n *\n * @example\n * ```ts\n * const server = new ServerModule({ port: 3000, host: 'localhost' }, '/var/www');\n * server.start();\n * // Later, restart the server...\n * await server.restart();\n * ```\n *\n * @see stop\n * @see start\n *\n * @since 2.0.0\n */\n\n async restart(): Promise<void> {\n console.log(prefix(), xterm.burntOrange('Restarting server...'));\n await this.stop();\n await this.start();\n }\n\n /**\n * Updates the configuration with the actual port assigned by the system.\n *\n * @remarks\n * This method is called after the server starts listening to retrieve and store the\n * actual port number when port `0` was specified in the configuration. When port `0`\n * is used, the operating system automatically assigns an available port, and this\n * method captures that assigned port for use throughout the application.\n *\n * **When this method is needed**:\n * - {@link ServerConfigurationInterface.port} is set to `0` (dynamic port allocation)\n * - The server has started and bound to a port\n * - The actual port needs to be known for logging, testing, or external configuration\n *\n * **Behavior**:\n * 1. Checks if the configured port is `0` (indicating dynamic allocation request)\n * 2. Retrieves the address information from the active server using {@link Server.address}\n * 3. Validates that the address is an object containing a port property\n * 4. Updates {@link config.port} with the system-assigned port number\n *\n * This is particularly useful in:\n * - Testing environments where multiple servers run simultaneously\n * - CI/CD pipelines where port conflicts must be avoided\n * - Containerized deployments with dynamic port mapping\n * - Development tools that spawn multiple server instances\n *\n * The method safely handles cases where the server address might not be available\n * or might not be in the expected format, preventing runtime errors.\n *\n * @example\n * ```ts\n * // Configuration with dynamic port\n * const config = { port: 0, host: 'localhost' };\n * const server = new ServerModule(config, '/var/www');\n *\n * await server.start();\n * // After start, setActualPort() is called internally\n *\n * console.log(config.port); // Now shows actual assigned port, e.g., 54321\n *\n * // Use case: Testing with dynamic ports\n * async function createTestServer() {\n * const config = { port: 0, host: 'localhost' };\n * const server = new ServerModule(config, './public');\n * await server.start();\n * // setActualPort() has updated config.port\n * return { server, port: config.port }; // Return actual port for tests\n * }\n *\n * const { server, port } = await createTestServer();\n * console.log(`Test server running on port ${port}`);\n * ```\n *\n * @see Server.address\n * @see startHttpServer\n * @see startHttpsServer\n * @see ServerConfigurationInterface.port\n *\n * @since 2.0.0\n */\n\n private setActualPort(): void {\n if (this.config.port === 0) {\n const address = this.server!.address();\n if(address && typeof address === 'object' && address.port)\n this.config.port = address.port;\n }\n }\n\n /**\n * Starts an HTTP server.\n *\n * @returns A promise that resolves when the server is listening and ready to accept connections.\n *\n * @remarks\n * Creates an HTTP server instance using Node.js's built-in {@link http} module.\n * All incoming requests are passed to {@link handleRequest}, which routes them to\n * {@link defaultResponse} for serving static files or directories.\n *\n * The server listens on the configured {@link ServerConfigurationInterface.host} and\n * {@link ServerConfigurationInterface.port} from the {@link config}.\n *\n * @example\n * ```ts\n * const server = new ServerModule({ port: 3000, host: 'localhost' }, '/var/www');\n * await server.start(); // Internally calls startHttpServer if HTTPS is not configured\n * ```\n *\n * @see start\n * @see handleRequest\n * @see defaultResponse\n * @see ServerConfigurationInterface\n *\n * @since 2.0.0\n */\n\n private startHttpServer(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.server = http.createServer((req, res) => {\n this.handleRequest(req, res, () => this.defaultResponse(req, res));\n });\n\n this.server.listen(this.config.port, this.config.host, () => {\n this.setActualPort();\n this.config.onStart?.({\n host: this.config.host!,\n port: this.config.port!,\n url: `http://${ this.config.host }:${ this.config.port }`\n });\n resolve();\n });\n });\n }\n\n /**\n * Starts an HTTPS server using configured certificate and key files.\n *\n * @returns A promise that resolves when the server is listening and ready to accept connections.\n *\n * @remarks\n * Creates an HTTPS server instance using Node.js's built-in {@link https} module.\n * If {@link ServerConfigurationInterface.key} or {@link ServerConfigurationInterface.cert}\n * are not provided in the configuration, defaults are loaded from the framework's\n * distribution path at `certs/server.key` and `certs/server.crt`.\n *\n * All incoming requests are passed to {@link handleRequest}, which routes them to\n * {@link defaultResponse} for serving static files or directories.\n *\n * The server listens on the configured {@link ServerConfigurationInterface.host} and\n * {@link ServerConfigurationInterface.port} from the {@link config}.\n *\n * @example\n * ```ts\n * const server = new ServerModule({\n * port: 3000,\n * host: 'localhost',\n * https: true,\n * key: './path/to/key.pem',\n * cert: './path/to/cert.pem'\n * }, '/var/www');\n * await server.start(); // Internally calls startHttpsServer\n * ```\n *\n * @see start\n * @see handleRequest\n * @see defaultResponse\n * @see FrameworkService\n * @see ServerConfigurationInterface\n *\n * @since 2.0.0\n */\n\n private startHttpsServer(): Promise<void> {\n return new Promise((resolve) => {\n const options = {\n key: readFileSync(this.config.key ?? join(this.framework.distPath, '..', 'certs', 'server.key')),\n cert: readFileSync(this.config.cert ?? join(this.framework.distPath, '..', 'certs', 'server.crt'))\n };\n\n this.server = https.createServer(options, (req, res) => {\n this.handleRequest(req, res, () => this.defaultResponse(req, res));\n });\n\n this.server.listen(this.config.port, this.config.host, () => {\n this.setActualPort();\n this.config.onStart?.({\n host: this.config.host!,\n port: this.config.port!,\n url: `https://${ this.config.host }:${ this.config.port }`\n });\n resolve();\n });\n });\n }\n\n /**\n * Handles incoming HTTP/HTTPS requests, optionally invoking user-defined hooks.\n *\n * @param req - Incoming HTTP request.\n * @param res - Server response object.\n * @param defaultHandler - Callback for default request handling.\n *\n * @remarks\n * If `config.verbose` is true, logs requests to the console.\n * Errors during handling are forwarded to {@link sendError}.\n *\n * @see sendError\n * @since 2.0.0\n */\n\n private handleRequest(req: IncomingMessage, res: ServerResponse, defaultHandler: () => void): void {\n try {\n if(this.config.verbose) {\n console.log(\n `${ prefix() } Request ${ xterm.lightCoral(req.url?.toString() ?? '') }`\n );\n }\n\n if (this.config.onRequest) {\n this.config.onRequest(req, res, defaultHandler);\n } else {\n defaultHandler();\n }\n } catch (error) {\n this.sendError(res, <Error> error);\n }\n }\n\n /**\n * Returns the MIME content type for a given file extension.\n *\n * @param ext - File extension without the leading dot.\n * @returns MIME type string for the provided extension.\n *\n * @since 2.0.0\n */\n\n private getContentType(ext: string): string {\n const contentTypes: Record<string, string> = {\n html: 'text/html',\n css: 'text/css',\n js: 'application/javascript',\n cjs: 'application/javascript',\n mjs: 'application/javascript',\n ts: 'text/plain',\n map: 'application/json',\n json: 'application/json',\n png: 'image/png',\n jpg: 'image/jpeg',\n gif: 'image/gif',\n txt: 'text/plain'\n };\n\n return contentTypes[ext] || 'application/octet-stream';\n }\n\n /**\n * Handles default responses for requests by serving files or directories.\n *\n * @param req - Incoming HTTP request.\n * @param res - Server response.\n *\n * @remarks\n * Ensures the requested path is within the server root.\n * Calls {@link handleDirectory} or {@link handleFile} depending on resource type.\n *\n * @see handleFile\n * @see sendNotFound\n * @see handleDirectory\n *\n * @since 2.0.0\n */\n\n private async defaultResponse(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const requestPath = req.url === '/' ? '' : req.url?.replace(/^\\/+/, '') || '';\n const fullPath = join(this.rootDir, requestPath);\n\n if (!fullPath.startsWith(this.rootDir)) {\n res.statusCode = 403;\n res.end();\n\n return;\n }\n\n try {\n const stats = await stat(fullPath);\n\n if (stats.isDirectory()) {\n await this.handleDirectory(fullPath, requestPath, res);\n } else if (stats.isFile()) {\n await this.handleFile(fullPath, res);\n }\n } catch (error) {\n const msg = (<Error> error).message;\n if (!msg.includes('favicon')) {\n console.log(prefix(), msg);\n }\n\n this.sendNotFound(res);\n }\n }\n\n /**\n * Handles directory listing for a request path.\n *\n * @param fullPath - Absolute directory path.\n * @param requestPath - Relative path from the server root.\n * @param res - Server response.\n *\n * @remarks\n * Generates an HTML listing with icons\n * Invalid filenames are skipped.\n *\n * @see fileIcons\n * @since 2.0.0\n */\n\n private async handleDirectory(fullPath: string, requestPath: string, res: ServerResponse): Promise<void> {\n const files = await readdir(fullPath);\n let fileList = files.map(file => {\n const fullPath = join(requestPath, file);\n const ext = extname(file).slice(1) || 'folder';\n\n if(ext === 'folder') {\n return `\n <a href=\"/${ fullPath }\" class=\"folder-row\">\n <div class=\"icon\"><i class=\"fa-solid fa-folder\"></i></div>\n <div class=\"meta\"><div class=\"name\">${ file }</div><div class=\"sub\">Folder</div></div>\n </a>\n `;\n }\n\n return `\n <a href=\"/${ fullPath }\" class=\"file-row\">\n <div class=\"icon\"><i class=\"fa-solid fa-file-code\"></i></div>\n <div class=\"meta\"><div class=\"name\">${ file }</div><div class=\"sub\">${ ext }</div></div>\n </a>\n `;\n }).join('');\n\n if(!fileList) {\n fileList = '<div class=\"empty\">No files or folders here.</div>';\n } else {\n fileList = `<div class=\"list\">${ fileList }</div>`;\n }\n\n let activePath = '/';\n const segments = requestPath.split('/').map(path => {\n activePath += `${ path }/`;\n\n return `<li><a href=\"${ activePath }\">${ path }</a></li>`;\n }).join('');\n\n const htmlResult = html.replace('${ fileList }', fileList)\n .replace('${ paths }', '<li><a href=\"/\">root</a></li>' + segments)\n .replace('${ up }', '/' + requestPath.split('/').slice(0, -1).join('/'));\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(htmlResult);\n }\n\n /**\n * Serves a static file.\n *\n * @param fullPath - Absolute path to the file.\n * @param res - Server response.\n *\n * @remarks\n * Determines MIME type using {@link getContentType}.\n *\n * @see getContentType\n * @since 2.0.0\n */\n\n private async handleFile(fullPath: string, res: ServerResponse): Promise<void> {\n const ext = extname(fullPath).slice(1) || 'txt';\n const contentType = this.getContentType(ext);\n\n const data = await readFile(fullPath);\n res.writeHead(200, { 'Content-Type': contentType });\n res.end(data);\n }\n\n /**\n * Sends a 404 Not Found response.\n *\n * @param res - Server response.\n *\n * @since 2.0.0\n */\n\n private sendNotFound(res: ServerResponse): void {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n }\n\n /**\n * Sends a 500 Internal Server Error response and logs the error.\n *\n * @param res - Server response.\n * @param error - Error object to log.\n *\n * @since 2.0.0\n */\n\n private sendError(res: ServerResponse, error: Error): void {\n console.error(prefix(), error.toString());\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end('Internal Server Error');\n }\n}\n","<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/><title>Dark File Browser — FTP-like</title><link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css\" integrity=\"sha512-2SwdPD6INVrV/lHTZbO2nodKhrnDdJK9/kg2XD1r9uGqPo1cUbujc+IYdlYdEErWNu69gVcYgdxlmVmzTWnetw==\" crossorigin=\"anonymous\" referrerpolicy=\"no-referrer\" /><style>:root{--bg:#0b0f14;--panel:#0f1720;--muted:#9aa4b2;--accent:#E5C07B;--glass:rgba(255,255,255,0.03);--card:#0c1116;--radius:12px;--gap:12px;--shadow:0 6px 18px rgba(0,0,0,0.4);--file-icon-size:40px;font-family:Inter,ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial}*{box-sizing:border-box;font-style:normal !important}html,body{height:100%;margin:0;font-size:14px;color:#dce7ef;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:radial-gradient(1200px 600px at 10% 10%,rgba(110,231,183,0.04),transparent 8%),linear-gradient(180deg,rgba(255,255,255,0.01),transparent 20%),var(--bg);padding:28px;display:flex;gap:20px;align-items:flex-start;justify-content:center}.app{width:1100px;max-width:98vw;display:flex;gap:18px;padding:18px;border-radius:16px;box-shadow:var(--shadow);border:1px solid rgba(255,255,255,0.03);background:linear-gradient(180deg,rgba(255,255,255,0.02),rgba(255,255,255,0));overflow:hidden}.sidebar{width:260px;background:linear-gradient(180deg,rgba(255,255,255,0.01),transparent);border-radius:var(--radius);padding:14px}.brand{display:flex;gap:12px;align-items:center;margin-bottom:10px}.logo{width:46px;height:46px;border-radius:10px;background:linear-gradient(135deg,#b65b9f 0%,#804b8f 100%);display:flex;align-items:center;justify-content:center;font-weight:700}.brand h1{font-size:16px;margin:0}.muted{color:var(--muted);font-size:13px}.search{margin:12px 0}.search input{width:100%;padding:10px 12px;border-radius:10px;border:1px solid rgba(255,255,255,0.03);background:var(--glass);color:inherit}.quick-list{margin-top:12px}.quick-list a{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;background:transparent;color:var(--muted);text-decoration:none;cursor:pointer;transition:color 0.15s ease}.quick-list a:hover{color:var(--accent)}.main{flex:1;display:flex;flex-direction:column}.topbar{display:flex;align-items:center;gap:12px;padding-bottom:12px}.breadcrumbs{list-style:none;display:flex;gap:8px;align-items:center;background:var(--glass);padding:8px 12px;border-radius:var(--radius);margin:0}.breadcrumbs li{display:flex;align-items:center}.breadcrumbs li:not(:last-child)::after{content:'>';margin-left:8px;color:var(--muted)}.breadcrumbs a{color:var(--muted);text-decoration:none;transition:color 0.15s ease}.breadcrumbs a:hover{color:var(--accent)}.list{margin-top:14px;display:grid;grid-template-columns:1fr;gap:10px}.list a{display:flex;text-decoration:none;color:inherit}.folder-row,.file-row{display:flex;gap:12px;align-items:center;padding:10px;border-radius:10px;background:linear-gradient(180deg,rgba(255,255,255,0.01),transparent);border:1px solid rgba(255,255,255,0.02);transition:color 0.25s ease}.icon{width:var(--file-icon-size);height:var(--file-icon-size);border-radius:10px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,0.02);flex-shrink:0;transition:background 0.25s ease,color 0.25s ease}.folder-row:hover,.file-row:hover{color:var(--accent)}.folder-row:hover .icon{background:rgba(152,195,121,0.2)}.file-row:hover .icon{background:rgba(224,108,117,0.2)}.folder-row:hover .icon i{color:#98C379}.file-row:hover .icon i{color:#e09c6c}.meta{display:flex;flex-direction:column}.name{font-weight:600}.sub{color:var(--muted);font-size:13px}.empty{padding:40px;text-align:center;color:var(--muted)}@media (max-width:880px){.app{flex-direction:column;padding:12px}.sidebar,.main{width:100%}}</style></head><body><div class=\"app\"><aside class=\"sidebar\"><div class=\"brand\"><div class=\"logo\">F</div><div><h1>xBuildFTP</h1><div class=\"muted\">Browse & serve files</div></div></div><div class=\"search\"><input placeholder=\"Search files & folders...\"/></div><div class=\"quick-list\"><a href=\"/\">🏠 Home</a><a href=\"${ up }\">⬆️ Up</a></div></aside><main class=\"main\"><div class=\"topbar\"><div class=\"topbar\"><ul class=\"breadcrumbs\"> ${ paths } </ul></div></div> ${ fileList } </main></div></body><script> const searchInput = document.querySelector('.search input'); const listItems = document.querySelectorAll('.list > .folder-row, .list > .file-row'); const emptyMessage = document.querySelector('.empty'); searchInput.addEventListener('input', () => { const query = searchInput.value.toLowerCase(); let anyVisible = false; listItems.forEach(item => { const name = item.querySelector('.name').textContent.toLowerCase(); if (name.includes(query)) { item.style.display = 'flex'; anyVisible = true; } else { item.style.display = 'none'; } }); emptyMessage.style.display = anyVisible ? 'none' : 'block'; }); </script></html>","/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * ASCII Logo and Version Information\n *\n * @remarks\n * The `asciiLogo` constant stores an ASCII representation of the project logo\n * that will be displayed in the banner. This banner is rendered in a formatted\n * string in the `bannerComponent` function.\n *\n * The `cleanScreen` constant contains an ANSI escape code to clear the terminal screen.\n */\n\nexport const asciiLogo = `\n ______ _ _ _\n | ___ \\\\ (_) | | |\n__ _| |_/ /_ _ _| | __| |\n\\\\ \\\\/ / ___ \\\\ | | | | |/ _\\` |\n > <| |_/ / |_| | | | (_| |\n/_/\\\\_\\\\____/ \\\\__,_|_|_|\\\\__,_|\n`;\n\n/**\n * Renders the banner with the ASCII logo and version information.\n *\n * @returns A formatted string containing the ASCII logo and version number with color formatting\n *\n * @remarks\n * This function constructs and returns a formatted banner string that includes:\n * - An ASCII logo rendered in burnt orange\n * - The current version number displayed in bright pink\n *\n * The function uses ANSI color codes through the xterm utility to create visually\n * distinct elements in the banner. The version number is retrieved from the global\n * `__VERSION` variable.\n *\n * The banner is designed with appropriate spacing and carriage returns to ensure\n * a consistent display across different terminal environments.\n *\n * @example\n * ```ts\n * // Display the banner in the console.\n * console.log(bannerComponent());\n * ```\n *\n * @since 1.0.0\n */\n\nexport function bannerComponent(): string {\n return `\n \\r${ xterm.burntOrange(asciiLogo) }\n \\rVersion: ${ xterm.brightPink(__VERSION) }\n \\r`;\n}\n\n/**\n * Returns a formatted prefix string for xBuild log messages.\n *\n * @returns A string containing the xBuild prefix formatted in light coral color\n *\n * @remarks\n * This function creates a consistent, visually distinct prefix for all xBuild\n * logging output. The prefix is formatted with light coral coloring using the\n * xterm color utility to make xBuild logs easily identifiable in console output.\n *\n * The function is used throughout the build system to maintain consistent\n * log formatting and improve readability when multiple tools or processes\n * are outputting to the same console.\n *\n * @example\n * ```ts\n * // Basic usage in log messages\n * console.log(`${prefix()} Starting build process...`);\n * // Output: \"[xBuild] Starting build process...\" (with \"[xBuild]\" in light coral)\n *\n * // In a logger utility\n * function log(message: string): void {\n * console.log(`${prefix()} ${message}`);\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport function prefix(): string {\n return xterm.lightCoral('[xBuild]');\n}\n","/**\n * Imports\n */\n\nimport { matchesGlob } from 'path';\nimport { stat, watch } from 'fs/promises';\nimport { inject } from '@symlinks/symlinks.module';\nimport { normalize, join } from '@remotex-labs/xmap';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * Provides a file-watching service that tracks changes in the framework's root directory.\n *\n * @remarks\n * This service sets up a recursive file system watcher, filters excluded files,\n * and debounces changes to optimize performance. It is mainly used for monitoring\n * source files or test files and triggering callbacks on changes.\n *\n * @example\n * ```ts\n * const watcher = new WatchService(['**\\/node_modules\\/**']);\n * await watcher.start((changedFiles) => {\n * console.log('Changed files:', changedFiles);\n * });\n * ```\n *\n * @see FrameworkService\n * @since 2.0.0\n */\n\nexport class WatchService {\n /**\n * Glob patterns that **exclude** paths from being emitted.\n *\n * @remarks\n * Patterns use **Node.js native glob semantics** via `matchesGlob`.\n * Negation syntax (`!pattern`) is **not supported** and must be expressed\n * through explicit include/exclude separation.\n *\n * Typical examples:\n *\n * - `**\\/node_modules\\/**`\n * - `**\\/dist\\/**`\n * - `**\\/*.spec.ts`\n *\n * @since 2.0.0\n */\n\n readonly excludes: Array<string>;\n\n /**\n * Glob patterns that **allow** paths to be emitted.\n *\n * @remarks\n * A file must match **at least one** an include pattern to be considered.\n * Defaults to `['**\\/*']`, meaning all files are eligible unless excluded.\n *\n * @since 2.0.0\n */\n\n readonly include: Array<string>;\n\n\n /**\n * Timer used for debouncing file change events.\n *\n * @remarks\n * When multiple file changes occur in quick succession, this timer ensures that\n * the `handleChangedFiles` method is called only once after a short delay,\n * preventing redundant executions and improving performance.\n *\n * @since 2.0.0\n */\n\n private debounceTimer: NodeJS.Timeout | null = null;\n\n /**\n * Reference to the core {@link FrameworkService}.\n *\n * @remarks\n * Injected via the {@link inject} helper, this service provides access to\n * framework-level configuration such as the project root path, runtime\n * environment, and shared utilities.\n * It is used here for resolving relative paths and coordinating with the\n * broader testing infrastructure.\n *\n * @see inject\n * @see FrameworkService\n *\n * @since 2.0.0\n */\n\n private readonly framework: FrameworkService = inject(FrameworkService);\n\n /**\n * Creates a new {@link WatchService}.\n *\n * @param excludes - Glob patterns to ignore.\n * @param include - Glob patterns to allow. Defaults to `['**\\/*']`.\n *\n * @remarks\n * Include and exclude rules are evaluated as:\n *\n * ```\n * included AND NOT excluded\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(excludes: Array<string> = [], include: Array<string> = [ '**/*' ]) {\n this.include = include;\n this.excludes = excludes;\n }\n\n /**\n * Start the file watcher.\n *\n * @param callback - Function to call with the changed file paths.\n * Expects a callback that accepts an array of files.\n * @returns A promise that resolves when the watcher is ready.\n *\n * @remarks\n * This method performs the following steps:\n * 1. Sets up a recursive file system watcher on the framework's root directory.\n * 2. On file changes, normalizes paths, filters excluded files, and schedules\n * handling of changed files with a debouncing to avoid excessive executions.\n *\n * @example\n * ```ts\n * const watcher = new WatchService();\n * await watcher.start((changedFiles) => {\n * console.log('Files changed:', changedFiles);\n * });\n * ```\n *\n * @see handleChangedFiles\n *\n * @since 2.0.0\n */\n\n async start(callback: (files: Array<string>) => void): Promise<void> {\n const changedFilesSet = new Set<string>();\n const watcher = watch(this.framework.rootPath, { recursive: true });\n for await (const { filename } of watcher) {\n if (!filename) continue;\n\n const fullPath = normalize(filename);\n if (fullPath.endsWith('~')) continue;\n\n if (!this.include.some((pattern) => matchesGlob(fullPath, pattern))) continue;\n if (this.excludes.some((pattern) => matchesGlob(fullPath, pattern))) continue;\n\n // Check if the path is a file (not a directory)\n const absolutePath = join(this.framework.rootPath, fullPath);\n try {\n const stats = await stat(absolutePath);\n if (!stats.isFile()) continue;\n } catch {\n // File might have been deleted or doesn't exist yet\n }\n\n changedFilesSet.add(fullPath);\n this.debounce(() => this.handleChangedFiles(callback, changedFilesSet));\n }\n }\n\n /**\n * Handles the changed files after debouncing.\n *\n * @param callback - Function to call with the changed file paths. Expects a callback that accepts an array of files.\n * @param changedFilesSet - Set of changed file paths containing normalized paths of modified files.\n *\n * @remarks\n * Executes the callback with a copy of the changed files and then clears the set\n * for the next batch of changes.\n *\n * @see start\n * @see debounce\n *\n * @since 2.0.0\n */\n\n private async handleChangedFiles(callback: (files: Array<string>) => void, changedFilesSet: Set<string>): Promise<void> {\n callback?.([ ...changedFilesSet ]);\n changedFilesSet.clear();\n }\n\n /**\n * Debounce the execution of a function to limit how frequently it runs.\n *\n * @param fn - The function to execute after the debounced delay.\n * @param delay - Optional debounce delay in milliseconds (default is 150 ms).\n *\n * @remarks\n * If multiple calls are made within the delay period, only the last one will execute.\n * This is used in the file watcher to prevent excessive calls to handle file changes\n * when multiple filesystem events occur in quick succession.\n *\n * @see debounceTimer\n * @see handleChangedFiles\n *\n * @since 2.0.0\n */\n\n private debounce(fn: () => void, delay = 150): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(fn, delay);\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { LifecycleProvider } from '@providers/lifecycle.provider';\nimport type { BuildOptions, OnStartResult, BuildResult } from 'esbuild';\nimport type { DiagnosticInterface } from '@typescript/typescript.module';\nimport type { VariantBuildInterface } from '@interfaces/configuration.interface';\nimport type { UnsubscribeType } from '@observable/interfaces/observable.interface';\nimport type { ResultContextInterface } from '@providers/interfaces/lifecycle-provider.interface';\nimport type { ConfigSubscriptionInterface } from '@services/interfaces/variant-service.interface';\nimport type { CommonBuildInterface, LifecycleHooksInterface } from '@interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { build } from 'esbuild';\nimport { TypesError } from '@errors/types.error';\nimport { xBuildError } from '@errors/xbuild.error';\nimport { inject } from '@symlinks/symlinks.module';\nimport { deepMerge } from '@components/object.component';\nimport { writeFile, mkdir, readFile } from 'fs/promises';\nimport { Typescript } from '@typescript/typescript.module';\nimport { analyzeDependencies } from '@services/transpiler.service';\nimport { relative, resolve, join, dirname } from '@remotex-labs/xmap';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { extractEntryPoints } from '@components/entry-points.component';\nimport { isBuildResultError } from '@providers/esbuild-messages.provider';\n\n/**\n * Manages a single build “variant” (e.g. `dev`, `prod`) end-to-end.\n *\n * @remarks\n * A variant combines:\n * - Variant-specific configuration (esbuild options, hooks, define/banner/footer)\n * - Common configuration shared across variants\n *\n * Responsibilities:\n * - Merge and normalize configuration (`initializeConfig`)\n * - Register lifecycle hooks (core + user-defined)\n * - Keep a TypeScript service instance in sync (type-checking + declaration emission)\n * - Build using esbuild\n * - Hot-reload on configuration changes (temporarily deactivating builds during updates)\n *\n * @example\n * ```ts\n * const variant = new VariantService('production', lifecycle, variantConfig, { watch: true });\n *\n * // Build once\n * await variant.build();\n *\n * // Access computed dependency entry points (only meaningful when bundle=false)\n * console.log(Object.keys(variant.dependencies));\n *\n * // Cleanup\n * variant.dispose();\n * ```\n *\n * @since 2.0.0\n */\n\nexport class VariantService {\n /**\n * Dependency-to-entry-point map produced by {@link buildDependencyMap}.\n *\n * @remarks\n * This map is always refreshed before each build. When `esbuild.bundle === false`,\n * it is assigned to `esbuild.entryPoints` so that every discovered input becomes an entry point.\n *\n * Keys are output-like paths (relative to `rootDir`) **without** file extensions.\n * Values are source file paths.\n *\n * @example\n * ```ts\n * // Example shape:\n * // {\n * // \"index\": \"/abs/path/src/index.ts\",\n * // \"utils/math\": \"/abs/path/src/utils/math.ts\"\n * // }\n * console.log(variant.dependencies);\n * ```\n *\n * @since 2.0.0\n */\n\n private dependenciesFile: undefined | Record<string, string>;\n\n /**\n * Indicates whether this variant is currently active and should execute builds.\n *\n * @remarks\n * Set to `false` temporarily during configuration updates to prevent builds from running\n * with stale configuration. Re-enabled after configuration is successfully reloaded.\n *\n * @since 2.0.0\n */\n\n private active: boolean = true;\n\n /**\n * Path of the TypeScript configuration file currently in use.\n *\n * @remarks\n * Tracks the tsconfig file for this variant. When configuration changes and a different\n * tsconfig is specified, the old TypeScript instance is disposed and a new one is created.\n *\n * @since 2.0.0\n */\n\n private tsConfigPath: string;\n\n /**\n * TypeScript language service instance for type checking and declaration generation.\n *\n * @remarks\n * Manages the TypeScript compiler for this variant, providing type checking diagnostics\n * and declaration file emission. Recreated when tsconfig changes.\n *\n * @since 2.0.0\n */\n\n private typescriptModule: Typescript;\n\n /**\n * Unsubscribe function for configuration change subscription.\n *\n * @remarks\n * Called during disposal to stop listening to configuration updates and prevent memory leaks.\n *\n * @since 2.0.0\n */\n\n private readonly configUnsubscribe: UnsubscribeType;\n\n /**\n * Configuration service instance providing reactive configuration access.\n *\n * @remarks\n * Injected dependency for accessing and subscribing to build configuration changes.\n *\n * @since 2.0.0\n */\n\n private readonly configService = inject(ConfigurationService);\n\n /**\n * Creates a new variant service instance.\n *\n * @param name - Variant name (used for configuration lookup and hook identification)\n * @param lifecycle - Lifecycle provider used to register build hooks/plugins\n * @param buildConfig - Initial variant build configuration\n * @param argv - Optional CLI/extra arguments passed to dynamic config functions\n *\n * @remarks\n * During construction this service:\n * - Initializes the TypeScript module using `esbuild.tsconfig` (default: `\"tsconfig.json\"`)\n * - Merges variant configuration with common configuration\n * - Normalizes/expands entry points\n * - Registers core lifecycle hooks (`start`/`end`)\n * - Subscribes to configuration changes for hot-reload\n *\n * @example\n * ```ts\n * const variant = new VariantService(\n * 'dev',\n * lifecycle,\n * config,\n * { watch: true }\n * );\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(\n readonly name: string,\n private lifecycle: LifecycleProvider,\n private buildConfig: VariantBuildInterface,\n private argv: Record<string, unknown> = {}\n ) {\n if (!this.buildConfig?.esbuild) {\n throw new xBuildError(`Variant '${ this.name }' not found configuration`);\n }\n\n this.tsConfigPath = this.buildConfig.esbuild.tsconfig ?? 'tsconfig.json';\n this.typescriptModule = new Typescript(this.tsConfigPath);\n this.buildConfig = this.initializeConfig(\n this.getConfig(this.buildConfig, this.configService.getValue().common)!\n );\n\n // todo optimize in case of glob\n // this.typescriptModule.languageHostService.touchFiles(\n // Object.values(<Record<string, string>>this.buildConfig.esbuild.entryPoints)\n // );\n\n this.lifecycle.onEnd(this.end.bind(this), `${ this.name }-core`);\n this.lifecycle.onStart(this.start.bind(this), `${ this.name }-core`);\n\n this.configUnsubscribe = this.configService.select(config => ({\n variantConfig: config.variants?.[this.name],\n commonConfig: config.common\n })).subscribe(\n this.handleConfigChange.bind(this),\n error => {\n throw error;\n }\n );\n }\n\n /**\n * Provides access to the TypeScript language service instance for this variant.\n *\n * @returns The TypeScript module instance used for type checking and declaration generation\n *\n * @remarks\n * This getter exposes the variant's TypeScript language service, which provides:\n * - Type checking and diagnostics\n * - Declaration file generation\n * - File change tracking\n * - TypeScript compiler integration\n *\n * The TypeScript module is initialized during construction with the variant's `tsconfig.json`\n * configuration and is recreated when the TypeScript configuration file path changes during\n * hot-reload. The instance is disposed when the variant service is disposed.\n *\n * Use this getter to access TypeScript functionality externally, such as\n * - Manually triggering type checks\n * - Accessing diagnostics without building\n * - Integrating with IDE tooling\n * - Custom declaration file processing\n *\n * @example\n * ```ts\n * const service = new VariantService('production', lifecycle);\n * const typescript = service.typescript;\n *\n * // Check for type errors\n * const diagnostics = typescript.check();\n * console.log(`Found ${diagnostics.length} type errors`);\n *\n * // Emit declarations manually\n * await typescript.emit('types');\n * ```\n *\n * @see {@link dispose}\n * @see {@link Typescript}\n * @see {@link touchFiles}\n *\n * @since 2.0.0\n */\n\n get typescript(): Typescript {\n return this.typescriptModule;\n }\n\n /**\n * Provides access to the merged build configuration for this variant.\n *\n * @returns The complete variant build configuration including esbuild options, TypeScript settings, and lifecycle hooks\n *\n * @remarks\n * This getter exposes the variant's fully merged configuration, which combines:\n * - Common configuration shared across all variants\n * - Variant-specific configuration overrides\n * - Applied to define replacements\n * - Configured lifecycle hooks\n * - TypeScript and declaration settings\n *\n * The configuration is automatically updated when hot-reload detects changes to the\n * configuration file. The returned object reflects the current active configuration\n * used for builds.\n *\n * Configuration structure includes:\n * - `esbuild`: esbuild compiler options (entry points, output, format, minification)\n * - `types`: TypeScript type checking settings\n * - `declaration`: Declaration file generation settings\n * - `define`: Compile-time constant replacements\n * - `banner`: Text to prepend to output files\n * - `footer`: Text to append to output files\n * - `lifecycle`: Custom build lifecycle hooks\n *\n * Use this getter to:\n * - Inspect current build settings\n * - Debug configuration merging\n * - Access configuration in custom lifecycle hooks\n * - Validate variant settings\n *\n * @example\n * ```ts\n * const service = new VariantService('production', lifecycle);\n * const config = service.config;\n *\n * console.log(`Minification: ${config.esbuild.minify}`);\n * console.log(`Output format: ${config.esbuild.format}`);\n * console.log(`Type checking: ${config.types !== false}`);\n * ```\n *\n * @example\n * ```ts\n * // Access in lifecycle hook\n * lifecycle.onStart(async (context) => {\n * const config = variantService.config;\n * if (config.esbuild.minify) {\n * console.log('Building minified output');\n * }\n * });\n * ```\n *\n * @see {@link getConfig}\n * @see {@link handleConfigChange}\n * @see {@link VariantBuildInterface}\n *\n * @since 2.0.0\n */\n\n get config(): VariantBuildInterface {\n return this.buildConfig;\n }\n\n /**\n * Returns the latest dependency entry-point map computed for this variant.\n *\n * @remarks\n * Mainly useful when `esbuild.bundle === false`, because in that mode the build\n * rewrites `esbuild.entryPoints` to this map.\n *\n * @example\n * ```ts\n * await variant.build();\n * for (const [outPath, sourcePath] of Object.entries(variant.dependencies)) {\n * console.log(outPath, '->', sourcePath);\n * }\n * ```\n *\n * @since 2.0.0\n */\n\n get dependencies(): Record<string, string> {\n return this.dependenciesFile ?? {};\n }\n\n /**\n * Disposes this variant service instance and releases resources.\n *\n * @remarks\n * Disposal performs two cleanup steps:\n * 1. Unsubscribes from configuration updates (stops hot-reload notifications)\n * 2. Releases the underlying TypeScript service resources for the current `tsconfig` path\n *\n * Call this when the variant is no longer needed to avoid keeping subscriptions alive and\n * to prevent TypeScript language service instances from lingering in memory.\n *\n * @example\n * ```ts\n * const variant = new VariantService('dev', lifecycle, config);\n *\n * // ... run builds, watch, etc. ...\n *\n * variant.dispose();\n * ```\n *\n * @since 2.0.0\n */\n\n dispose(): void {\n this.configUnsubscribe();\n this.typescriptModule.dispose(this.tsConfigPath);\n }\n\n /**\n * Notifies the TypeScript language service that files have been modified.\n *\n * @param files - Array of file paths that have been modified\n *\n * @remarks\n * This method updates the TypeScript language service's internal state to reflect\n * file changes, ensuring type checking and diagnostics remain accurate. Typically\n * called by file watchers when source files are modified.\n *\n * The TypeScript module will invalidate cached diagnostics for the touched files\n * and recalculate them on the next type check.\n *\n * @example\n * ```ts\n * // In a file watcher\n * watcher.on('change', (filePath) => {\n * service.touchFiles([filePath]);\n * });\n * ```\n *\n * @see {@link Typescript.touchFiles}\n *\n * @since 2.0.0\n */\n\n touchFiles(files: Array<string>): void {\n this.typescriptModule.touchFiles(files);\n }\n\n /**\n * Performs TypeScript type checking for all files in the variant's dependency graph.\n *\n * @returns Array of diagnostic information containing errors, warnings, and suggestions\n *\n * @remarks\n * This method executes type checking on all source files discovered through dependency\n * analysis. It ensures the dependency map is built before checking, building it lazily\n * on the first invocation if not already available.\n *\n * The type checking process:\n * 1. Builds the dependency map if not already cached (first invocation only)\n * 2. Extracts all source file paths from the dependency map\n * 3. Passes the file list to the TypeScript module for semantic analysis\n * 4. Returns diagnostics for all type errors, warnings, and suggestions\n *\n * This method can be called independently of the build process to perform\n * type checking without compilation. It's also used internally by the `start`\n * lifecycle hook during builds when type checking is enabled.\n *\n * The dependency file map is cached after the first build, so subsequent\n * type checks reuse the same file list unless the variant is rebuilt or\n * dependencies change.\n *\n * @example\n * ```ts\n * const service = new VariantService('production', lifecycle, config);\n *\n * // Check types without building\n * const diagnostics = await service.check();\n *\n * if (diagnostics.length > 0) {\n * console.error(`Found ${diagnostics.length} type issues`);\n * diagnostics.forEach(d => {\n * console.error(`${d.file}:${d.line}:${d.column} - ${d.message}`);\n * });\n * }\n * ```\n *\n * @example\n * ```ts\n * // Used in CI pipeline\n * const errors = (await service.check()).filter(\n * d => d.category === DiagnosticCategory.Error\n * );\n *\n * if (errors.length > 0) {\n * process.exit(1);\n * }\n * ```\n *\n * @see {@link start}\n * @see {@link Typescript.check}\n * @see {@link buildDependencyMap}\n * @see {@link DiagnosticInterface}\n *\n * @since 2.0.0\n */\n\n async check(): Promise<DiagnosticInterface[]> {\n if (!this.dependenciesFile)\n this.dependenciesFile = await this.buildDependencyMap();\n\n return this.typescriptModule.check(Object.values(this.dependenciesFile!));\n }\n\n /**\n * Executes a build for this variant.\n *\n * @returns The esbuild {@link BuildResult}, or `undefined` if the variant is inactive.\n *\n * @remarks\n * High-level steps:\n * 1. Skip if inactive (used during configuration hot-reload)\n * 2. Apply banner/footer injections\n * 3. Compute dependency map\n * 4. If `bundle === false`, replace `entryPoints` with the computed dependency map\n * 5. Run esbuild\n * 6. Write `package.json` with the correct `\"type\"` for the output format\n *\n * @example\n * ```ts\n * const result = await variant.build();\n * if (result) {\n * console.log('warnings:', result.warnings.length);\n * }\n * ```\n *\n * @since 2.0.0\n */\n\n async build(): Promise<BuildResult | undefined> {\n if (!this.active) return;\n this.applyInjections();\n\n const config: BuildOptions = Object.assign({}, this.buildConfig.esbuild);\n this.dependenciesFile = await this.buildDependencyMap();\n if (this.buildConfig.esbuild.bundle === false) {\n Object.assign(config, { entryPoints: this.dependenciesFile });\n }\n\n if(this.config.define && config.define) {\n for(const [ key, value ] of Object.entries(this.config.define)) {\n if(typeof value === 'function') {\n config.define[key] = JSON.stringify(value());\n }\n }\n }\n\n try {\n const result = await build(config);\n await this.packageTypeComponent();\n\n return result;\n } catch (error: unknown) {\n if (isBuildResultError(error)) {\n const errors = error.errors.filter(error => error.location);\n if (errors.length > 0) throw error;\n\n return {\n errors: error?.errors ?? [],\n warnings: error?.warnings ?? []\n } as BuildResult;\n }\n }\n }\n\n /**\n * Merges variant-specific configuration with common configuration.\n *\n * @param config - Variant-specific build configuration\n * @param common - Common build configuration shared across variants\n * @returns Merged configuration, or null if variant config is undefined\n *\n * @remarks\n * This method performs a deep merge where variant-specific settings override\n * common settings. The merge is performed using the `deepMerge` utility, which\n * recursively combines nested objects and arrays.\n *\n * Merge priority (highest to lowest):\n * 1. Variant-specific configuration\n * 2. Common configuration\n * 3. Empty object (default base)\n *\n * If the variant configuration is undefined, it returns null to signal that the\n * variant doesn't exist.\n *\n * @example\n * ```ts\n * const common = { esbuild: { minify: false } };\n * const variant = { esbuild: { minify: true, sourcemap: true } };\n * const merged = getConfig(variant, common);\n * // Result: { esbuild: { minify: true, sourcemap: true } }\n * ```\n *\n * @see {@link deepMerge}\n *\n * @since 2.0.0\n */\n\n private getConfig(config?: VariantBuildInterface, common: CommonBuildInterface = {}): VariantBuildInterface | null {\n if (!config) return null;\n\n return deepMerge<VariantBuildInterface>(\n {} as VariantBuildInterface,\n common,\n config\n );\n }\n\n /**\n * Core start hook handler that runs type checking and declaration generation.\n *\n * @returns Start result containing any type errors and warnings\n *\n * @remarks\n * This private method is registered as an onStart hook during construction and executes\n * at the beginning of each build. It runs two tasks concurrently:\n * 1. **Type checking**: Validates TypeScript types and reports diagnostics\n * 2. **Declaration generation**: Emits .d.ts declaration files\n *\n * Both tasks run in parallel using `Promise.all` for optimal performance.\n *\n * Type checking behavior depends on the `types` configuration:\n * - If `types.failOnError` is false, type errors become warnings\n * - If `types.failOnError` is true (default), type errors fail the build\n *\n * Declaration generation behavior depends on the `declaration` configuration:\n * - If `declaration.bundle` is true (default), declarations are bundled\n * - If `declaration.bundle` is false, individual declarations are emitted\n * - Custom output directory can be specified with `declaration.outDir`\n *\n * @since 2.0.0\n */\n\n private async start(): Promise<OnStartResult | undefined> {\n const result: OnStartResult = { errors: [], warnings: [] };\n if (!this.buildConfig.types) return result;\n\n const diagnostics = this.typescriptModule.check(\n Object.values(this.dependenciesFile ?? {})\n );\n\n if (diagnostics.length === 0) return result;\n const buildOnError = typeof this.buildConfig.types === 'object' &&\n !this.buildConfig.types.failOnError;\n\n if (buildOnError) {\n const error = new TypesError('Type checking failed', diagnostics);\n result.warnings?.push({ detail: error, location: undefined });\n } else {\n const errors: Array<DiagnosticInterface> = [];\n const warnings: Array<DiagnosticInterface> = [];\n const error = new TypesError('Type checking failed', errors);\n const warning = new TypesError('Type checking failed', warnings);\n\n for (const d of diagnostics) {\n (d.category === ts.DiagnosticCategory.Error ? errors : warnings).push(d);\n }\n\n if (errors.length)\n result.errors?.push({ detail: error, location: undefined });\n\n if (warnings.length)\n result.warnings?.push({ detail: warning, location: undefined });\n }\n\n return result;\n }\n\n /**\n * Core end hook handler that generates declaration files after a successful build.\n *\n * @param context - The result context containing build results and metadata\n *\n * @returns Start result containing any declaration generation warnings, or undefined if build has errors\n *\n * @remarks\n * This private method is registered as an onEnd hook during construction and executes\n * at the end of each build. It performs declaration file generation only if the build is\n * completed successfully without errors.\n *\n * The method follows this execution flow:\n * 1. Checks if the build produced any errors\n * 2. Returns early (undefined) if errors exist, skipping declaration generation\n * 3. Creates a new result object for collecting warnings\n * 4. Executes declaration file emission\n * 5. Returns the result with any warnings from the emission process\n *\n * Declaration generation only runs for successful builds to avoid creating declaration\n * files for code that failed to compile. This ensures type definitions remain consistent\n * with the compiled JavaScript output.\n *\n * Any errors during declaration generation are captured as warnings and included in the\n * returned result, allowing the build to complete while reporting the issue.\n *\n * @example\n * ```ts\n * // Registered during construction\n * this.lifecycle.onEnd(this.end.bind(this), `${this.name}-core`);\n *\n * // Called automatically by lifecycle provider after build\n * // If build succeeded: generates declarations\n * // If build failed: skips declaration generation\n * ```\n *\n * @see {@link ResultContextInterface}\n * @see {@link start} for the corresponding start hook\n *\n * @since 2.0.0\n */\n\n private async end(context: ResultContextInterface): Promise<OnStartResult | undefined> {\n if (context.buildResult.errors?.length > 0) return;\n const result: OnStartResult = { errors: [], warnings: [] };\n\n if (typeof context.buildResult.metafile?.outputs === 'object') {\n const files = Object.keys(context.buildResult.metafile?.outputs);\n for (const file of files) {\n if (!file.endsWith('.map')) continue;\n\n const distPath = dirname(file);\n const data = await readFile(file, 'utf8');\n const dataObject = JSON.parse(data);\n dataObject.sources = dataObject.sources.map((source: string) => {\n if (source.startsWith('http')) return source;\n\n return join(distPath, source);\n });\n\n await writeFile(file, JSON.stringify(dataObject), 'utf8');\n }\n }\n\n if (!this.buildConfig.declaration) return;\n const decl = this.buildConfig.declaration;\n const shouldBundle = typeof decl === 'object' ? decl.bundle !== false : true;\n const outDir = typeof decl === 'object' ? decl.outDir : undefined;\n\n try {\n if (shouldBundle) {\n await this.typescriptModule.emitBundle(\n <Record<string, string>>this.buildConfig.esbuild.entryPoints, outDir\n );\n } else {\n await this.typescriptModule.emit(outDir);\n }\n } catch (err) {\n result.warnings?.push({ detail: err, location: undefined });\n }\n\n return result;\n }\n\n /**\n * Registers lifecycle hooks from configuration with the lifecycle provider.\n *\n * @param hooks - Lifecycle hooks interface containing hook handlers\n *\n * @remarks\n * This method extracts individual hook handlers from the configuration and\n * registers them with the variant's lifecycle provider. Hooks are registered\n * using the default variant name identifier.\n *\n * Only defined hooks are registered; undefined hooks are skipped. This allows\n * partial hook configuration where only specific lifecycle stages need custom logic.\n *\n * Hook registration order:\n * 1. onStart\n * 2. onResolve\n * 3. onLoad\n * 4. onEnd\n * 5. onSuccess\n *\n * If no hooks are provided in the configuration, the method returns early\n * without registering anything.\n *\n * @example\n * ```ts\n * // In build configuration\n * {\n * lifecycle: {\n * onStart: async (context) => {\n * console.log('Custom start hook');\n * },\n * onSuccess: async (context) => {\n * console.log('Build succeeded!');\n * }\n * }\n * }\n * ```\n *\n * @see {@link LifecycleProvider.onStart}\n * @see {@link LifecycleProvider.onResolve}\n * @see {@link LifecycleProvider.onLoad}\n * @see {@link LifecycleProvider.onEnd}\n * @see {@link LifecycleProvider.onSuccess}\n *\n * @since 2.0.0\n */\n\n private registerConfigHooks(hooks?: LifecycleHooksInterface): void {\n if (!hooks) return;\n const { onStart, onResolve, onLoad, onEnd, onSuccess } = hooks;\n\n if (onStart) this.lifecycle.onStart(onStart);\n if (onResolve) this.lifecycle.onResolve(onResolve);\n if (onLoad) this.lifecycle.onLoad(onLoad);\n if (onEnd) this.lifecycle.onEnd(onEnd);\n if (onSuccess) this.lifecycle.onSuccess(onSuccess);\n }\n\n /**\n * Generates a `package.json` file with the appropriate `type` field\n * based on the format specified in the configuration.\n *\n * - If the format is `esm`, the `type` will be set to `\"module\"`.\n * - If the format is `cjs`, the `type` will be set to `\"commonjs\"`.\n *\n * The function will ensure that the specified output directory exists, and if it doesn't,\n * it will create the necessary directories before writing the `package.json` file.\n *\n * @throws Error - throw an error if there is a problem creating the directory or writing the file.\n *\n * @example\n * ```ts\n * const config = {\n * esbuild: {\n * format: 'esm'\n * }\n * };\n * packageTypeComponent(config);\n * // This will create 'dist/package.json' with the content: {\"type\": \"module\"}\n * ```\n *\n * @since 2.0.0\n */\n\n private async packageTypeComponent(): Promise<void> {\n const outDir = this.buildConfig.esbuild.outdir ?? 'dist';\n const type = this.buildConfig.esbuild.format === 'esm' ? 'module' : 'commonjs';\n\n await mkdir(outDir, { recursive: true });\n await writeFile(join(outDir, 'package.json'), `{\"type\": \"${ type }\"}`);\n }\n\n /**\n * Validates and normalizes the merged variant configuration.\n *\n * @param config - Merged variant configuration (common + variant)\n * @returns The normalized configuration used internally for builds.\n *\n * @remarks\n * This method:\n * - Ensures required config fields exist (e.g. `esbuild.entryPoints`)\n * - Registers configured lifecycle hooks\n * - Normalizes `esbuild.tsconfig` (default: `\"tsconfig.json\"`)\n * - Expands entry points relative to `rootDir`\n * - Applies computed esbuild options (`define`, `logLevel`, and lifecycle plugin)\n *\n * @example\n * ```ts\n * // Called internally during construction and config hot-reload.\n * // You typically don't call this directly.\n * ```\n *\n * @since 2.0.0\n */\n\n private initializeConfig(config: VariantBuildInterface): VariantBuildInterface {\n if (!config) {\n throw new xBuildError(`Variant '${ this.name }' not found configuration`);\n }\n\n if (!config.esbuild.entryPoints && !config.esbuild.stdin) {\n throw new xBuildError('Entry points are required in esbuild configuration');\n }\n\n const defineFromConfig = config.define;\n const define = defineFromConfig\n ? Object.fromEntries(\n Object.entries(defineFromConfig).flatMap(([ key, value ]) =>\n typeof value === 'function'\n ? []\n : [[ key, JSON.stringify(value) ]]\n )\n )\n : undefined;\n\n this.registerConfigHooks(config.lifecycle);\n config.esbuild.entryPoints = extractEntryPoints(\n this.typescriptModule.config.options.rootDir ?? process.cwd(), config.esbuild.entryPoints\n );\n\n config.esbuild = Object.assign({}, config.esbuild, {\n define,\n logLevel: 'silent',\n plugins: [ this.lifecycle.create() ]\n }) as BuildOptions;\n\n return config;\n }\n\n /**\n * Handles configuration change events and updates variant settings.\n *\n * @param variantConfig - Updated variant-specific configuration\n * @param commonConfig - Updated common configuration\n *\n * @remarks\n * This method is called whenever the configuration service detects changes to the\n * variant's configuration. It performs a hot-reload of all variant settings without\n * requiring a restart.\n *\n * The reload process:\n * 1. Temporarily deactivates the variant (prevents builds during reload)\n * 2. Merges new variant and common configuration\n * 3. Validates that the variant still exists (returns if removed)\n * 4. Reactivates the variant\n * 5. Updates the build configuration\n * 6. Recreates TypeScript module if tsconfig changed\n * 7. Re-registers lifecycle hooks from a new configuration\n * 8. Reapplies define replacements and esbuild options\n * 9. Rebuilds entry points mapping\n *\n * TypeScript module recreation logic:\n * - Disposes old TypeScript instance if tsconfig path changed\n * - Creates new instance with updated tsconfig\n * - Preserves TypeScript instance if tsconfig unchanged\n *\n * This enables configuration changes to take effect immediately without stopping\n * watch mode or restarting the build process.\n *\n * @example\n * ```ts\n * // Configuration changes from:\n * { minify: false, tsconfig: 'tsconfig.json' }\n * // To:\n * { minify: true, tsconfig: 'tsconfig.prod.json' }\n * // TypeScript module is recreated with new tsconfig\n * // All other settings are updated\n * ```\n *\n * @see {@link getConfig}\n * @see {@link registerConfigHooks}\n *\n * @since 2.0.0\n */\n\n private async handleConfigChange({ variantConfig, commonConfig }: ConfigSubscriptionInterface): Promise<void> {\n this.active = false;\n const config = this.getConfig(variantConfig, commonConfig);\n if (!config) return;\n\n this.active = true;\n this.buildConfig = this.initializeConfig(config);\n\n if (config.esbuild.outdir && config.esbuild.outfile)\n this.buildConfig.esbuild.outdir = undefined;\n\n if (config.esbuild.tsconfig && config.esbuild.tsconfig !== this.tsConfigPath) {\n this.typescriptModule.dispose(this.tsConfigPath);\n this.tsConfigPath = config.esbuild.tsconfig;\n this.typescriptModule = new Typescript(this.tsConfigPath);\n }\n }\n\n /**\n * Removes file extension from a path.\n *\n * @param filePath - Path with extension\n * @returns Path without extension\n *\n * @since 2.0.0\n */\n\n private stripExtension(filePath: string): string {\n const lastDotIndex = filePath.lastIndexOf('.');\n\n return lastDotIndex > 0 ? filePath.substring(0, lastDotIndex) : filePath;\n }\n\n /**\n * Analyzes build dependencies and maps all source files to their output paths.\n *\n * @returns Record mapping output paths (without extensions) to source file paths\n *\n * @remarks\n * This method performs the following steps:\n * - Analyzes the dependency graph using esbuild's metafile\n * - Extracts configured entry points\n * - Discovers all transitive dependencies from the build\n * - Maps each file to its relative output path based on rootDir\n *\n * Entry points are preserved as-is, while dependencies are mapped relative to the\n * TypeScript root directory with extensions removed for output path calculation.\n *\n * @example\n * ```ts\n * const fileMap = await this.buildDependencyMap();\n * // {\n * // 'index': 'src/index.ts',\n * // 'utils/helper': 'src/utils/helper.ts',\n * // 'components/button': 'src/components/button.ts'\n * // }\n * ```\n *\n * @since 2.0.0\n */\n\n private async buildDependencyMap(): Promise<Record<string, string>> {\n const { esbuild } = this.buildConfig;\n const analysisOptions: BuildOptions = { ...esbuild, plugins: undefined };\n const { metafile } = await analyzeDependencies(esbuild.entryPoints, analysisOptions);\n\n const result: Record<string, string> = {};\n for (const file of Object.keys(metafile.inputs)) {\n const relativePath = relative(this.typescriptModule.config.options.rootDir!, resolve(file));\n const path = this.stripExtension(relativePath);\n result[path] = file;\n }\n\n return result;\n }\n\n /**\n * Injects banner or footer text into esbuild output configuration.\n *\n * @param type - Type of text block to inject ('banner' or 'footer')\n *\n * @remarks\n * This method processes banner or footer configuration and injects the resulting\n * text into esbuild options. The configuration can specify text for different\n * output types (js, CSS).\n *\n * Text can be specified in two ways:\n * - **Static string**: Used directly as the banner/footer text\n * - **Function**: Called with variant name and argv, returns the text\n *\n * The function form allows dynamic text generation based on build context.\n *\n * If no banner/footer is configured for this variant, the method returns early\n * without modifying esbuild options.\n *\n * @example\n * ```ts\n * // Static banner\n * {\n * banner: {\n * js: '// Copyright 2024'\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * // Dynamic banner with function\n * {\n * banner: {\n * js: (variantName, argv) => `// Build: ${variantName} at ${new Date()}`\n * }\n * }\n * ```\n *\n * @since 2.0.0\n */\n\n private injectTextBlock(type: 'banner' | 'footer'): void {\n const content = this.buildConfig[type];\n if (!content) return;\n\n const esbuild: BuildOptions = this.buildConfig.esbuild;\n esbuild[type] ??= {};\n\n for (const [ target, value ] of Object.entries(content)) {\n esbuild[type][target] = typeof value === 'function'\n ? value(this.name, this.argv)\n : value;\n }\n }\n\n /**\n * Applies banner and footer text injections before build execution.\n *\n * @remarks\n * This method injects custom text into the build output by calling `injectTextBlock`\n * for both 'banner' and 'footer' configuration options. Banners are prepended to\n * output files, while footers are appended.\n *\n * This is called at the start of each build to ensure injections reflect the\n * current configuration state.\n *\n * @see {@link injectTextBlock}\n *\n * @since 2.0.0\n */\n\n private applyInjections(): void {\n this.injectTextBlock('banner');\n this.injectTextBlock('footer');\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { LanguageService, SourceFile } from 'typescript';\nimport type { LanguageHostService } from '@typescript/services/hosts.service';\nimport type { FileNodeInterface, ModuleInfoInterface } from '@typescript/models/interfaces/graph-model.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { FilesModel } from '@typescript/models/files.model';\nimport { inject, Injectable } from '@symlinks/symlinks.module';\nimport { cleanContent, removeExportModifiers } from '@typescript/components/transformer.component';\n\n/**\n * Builds a simplified, declaration-only dependency graph for TypeScript files.\n *\n * Analyzes source files to extract internal dependencies, named/default/namespace imports & exports,\n * and produces cleaned `.d.ts`-like content with imports and export keywords removed.\n *\n * Primarily used for module federation analysis, tree-shaking verification, public API extraction,\n * or generating documentation / type-only bundles.\n *\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class GraphModel {\n /**\n * Active TypeScript language service instance used to emit declaration files.\n *\n * Set temporarily during the ` scan () ` call via `Object.assign` trick\n * because we want to avoid passing it through every private method signature.\n *\n * @remarks\n * The `!` assertion is safe because `scan()` always assigns both services\n * before any method that uses them is called.\n *\n * @since 2.0.0\n */\n\n private languageService!: LanguageService;\n\n /**\n * Language host providing module resolution, file system access, and version tracking.\n *\n * Like `languageService`, it is temporarily attached during `scan()` execution.\n *\n * @remarks\n * The definite assignment assertion (`!`) is valid only because `scan()`\n * guarantees both fields are set before private methods are invoked.\n *\n * @since 2.0.0\n */\n\n private languageHostService!: LanguageHostService;\n\n /**\n * Printer used to serialize cleaned AST nodes back to text\n * @since 2.0.0\n */\n\n private readonly printer: ts.Printer;\n\n /**\n * Cache of already analyzed files → their dependency and export graph nodes\n * @since 2.0.0\n */\n\n private readonly nodesCache: Map<string, FileNodeInterface> = new Map();\n\n /**\n * Injected singleton instance of the file snapshot cache.\n *\n * Provides fast access to file versions, resolved paths, and content snapshots\n * without repeated disk I/O.\n *\n * @see {@link FilesModel}\n * @since 2.0.0\n */\n\n private readonly filesCache = inject(FilesModel);\n\n /**\n * Initializes a new {@link GraphModel} instance.\n *\n * @remarks\n * Creates a TypeScript printer configured for consistent line ending formatting.\n * The printer is reused across all analysis operations for efficiency.\n *\n * @since 2.0.0\n */\n\n constructor() {\n this.printer = ts.createPrinter({\n newLine: ts.NewLineKind.LineFeed\n });\n }\n\n /**\n * Clears all cached file analysis results.\n * @since 2.0.0\n */\n\n clear(): void {\n this.nodesCache.clear();\n }\n\n /**\n * Retrieves a previously analyzed graph node for a file if it exists.\n *\n * @param path - file path (relative or absolute)\n * @returns cached node or `undefined` if not yet scanned or invalidated\n *\n * @since 2.0.0\n */\n\n get(path: string): FileNodeInterface | undefined {\n const resolvedPath = this.filesCache.resolve(path);\n\n return this.nodesCache.get(resolvedPath);\n }\n\n /**\n * Scans a source file, emits its declaration file, analyzes imports/exports,\n * and returns a dependency & export graph node.\n *\n * @param source - already parsed TypeScript source file\n * @param languageService - active TS language service (used for emitting)\n * @param languageHostService - host providing resolution and file system access\n * @returns graph node containing version, cleaned content, internal deps, and import/export maps\n *\n * @remarks\n * Re-uses a cached result if a file version hasn't changed.\n *\n * Temporarily attaches `languageService` and `languageHostService` to `this` for private method calls.\n *\n * @example\n * ```ts\n * const sourceFile = program.getSourceFile(fileName, ts.ScriptTarget.Latest)!;\n * const node = graphModel.scan(sourceFile, languageService, hostService);\n *\n * console.log(node.internalDeps.size, 'internal dependencies');\n * console.log(Object.keys(node.externalImports.named), 'external named imports');\n * ```\n *\n * @see {@link FilesModel}\n * @see {@link FileNodeInterface}\n *\n * @since 2.0.0\n */\n\n scan(source: SourceFile, languageService: LanguageService, languageHostService: LanguageHostService): FileNodeInterface {\n const self = Object.assign(Object.create(Object.getPrototypeOf(this)), this, {\n languageService,\n languageHostService\n });\n\n const version = this.filesCache.getSnapshot(source.fileName)!.version.toString();\n const cached = this.nodesCache.get(source.fileName);\n if (cached?.version === version) return cached;\n\n const node = this.initDeclaration(source.fileName, version);\n const declarationSource = this.emitDeclaration.call(self, source);\n\n node.content = this.stripImportsExports.call(self, declarationSource, node);\n this.nodesCache.set(source.fileName, node);\n\n return node;\n }\n\n /**\n * Creates empty graph node skeleton with given file name and version.\n *\n * @param fileName - resolved absolute file path\n * @param version - snapshot version string\n * @returns initialized node structure\n *\n * @since 2.0.0\n */\n\n private initDeclaration(fileName: string, version: string): FileNodeInterface {\n return {\n version,\n fileName,\n content: '',\n internalDeps: new Set(),\n externalImports: {\n named: Object.create(null),\n default: Object.create(null),\n namespace: Object.create(null)\n },\n internalExports: {\n star: [],\n exports: [],\n namespace: Object.create(null)\n },\n externalExports: {\n star: [],\n exports: Object.create(null),\n namespace: Object.create(null)\n }\n };\n }\n\n /**\n * Resolves a module specifier to either an internal file path or external module name.\n *\n * @param moduleSpecifier - string literal from import/export declaration\n * @param currentFile - path of the file containing the import/export\n * @returns module info or `null` if resolution fails\n *\n * @since 2.0.0\n */\n\n private resolveModule(moduleSpecifier: ts.Expression, currentFile: string): ModuleInfoInterface | null {\n if (!ts.isStringLiteral(moduleSpecifier)) return null;\n\n const modulePath = moduleSpecifier.text;\n const resolvedFileName = this.languageHostService.resolveModuleName(modulePath, currentFile)\n .resolvedModule?.resolvedFileName;\n\n if (!resolvedFileName || resolvedFileName.includes('node_modules')) {\n return { fileName: modulePath, isExternal: true };\n }\n\n return { fileName: resolvedFileName, isExternal: false };\n }\n\n /**\n * Appends named import/export specifiers (with optional `as` aliases) to the target array.\n *\n * @param target - array to push names into\n * @param elements - import/export specifiers\n *\n * @since 2.0.0\n */\n\n private addNamedElements(target: Array<string>, elements: ts.NodeArray<ts.ImportSpecifier | ts.ExportSpecifier>): void {\n for (const element of elements) {\n const name = element.propertyName\n ? `${ element.propertyName.text } as ${ element.name.text }`\n : element.name.text;\n target.push(name);\n }\n }\n\n /**\n * Checks whether a statement has an `export` modifier.\n *\n * @param stmt - any statement node\n * @returns `true` if statement is exported\n *\n * @since 2.0.0\n */\n\n private hasExportModifier(stmt: ts.Statement): boolean {\n if (!ts.canHaveModifiers(stmt)) return false;\n const modifiers = ts.getModifiers(stmt);\n\n return modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;\n }\n\n /**\n * Emits a declaration file (.d.ts content) for a given source file using language service.\n *\n * @param source - source file to emit declarations from\n * @returns parsed declaration source file\n *\n * @throws Error when emit output is empty or missing\n *\n * @since 2.0.0\n */\n\n private emitDeclaration(source: SourceFile): SourceFile {\n const output = this.languageService.getEmitOutput(\n source.fileName,\n true,\n true\n );\n\n const declarationText = output.outputFiles[0]?.text;\n if (!declarationText) {\n throw new Error(`Failed to emit declaration: ${ source.fileName }`);\n }\n\n return ts.createSourceFile(\n source.fileName.replace(/\\.tsx?$/, '.d.ts'),\n declarationText,\n ts.ScriptTarget.Latest,\n true\n );\n }\n\n /**\n * Removes imports, exports, and export modifiers from a declaration file,\n * collects dependency/export information, and cleans alias references.\n *\n * @param sourceFile - emitted declaration source file\n * @param node - graph node being populated\n * @returns final cleaned declaration text (no imports/exports)\n *\n * @since 2.0.0\n */\n\n private stripImportsExports(sourceFile: SourceFile, node: FileNodeInterface): string {\n const namespaceImports: Array<string> = [];\n const aliasRenames: Array<[ original: string, local: string ]> = [];\n const keptStatements: Array<ts.Statement> = [];\n\n for (const stmt of sourceFile.statements) {\n if (ts.isImportDeclaration(stmt)) {\n this.handleImport(stmt, node, namespaceImports, aliasRenames);\n continue;\n }\n\n if (ts.isExportDeclaration(stmt)) {\n this.handleExport(stmt, node);\n continue;\n }\n\n if (this.hasExportModifier(stmt)) {\n this.extractExportName(stmt, node);\n }\n\n keptStatements.push(stmt);\n }\n\n const nodeArray = ts.factory.createNodeArray(keptStatements);\n const printed = this.printer.printList(\n ts.ListFormat.MultiLine,\n nodeArray,\n sourceFile\n );\n\n let content = removeExportModifiers(cleanContent(printed));\n for (const [ original, local ] of aliasRenames) {\n content = content.replace(new RegExp(`\\\\b${ local }\\\\b`, 'g'), original);\n }\n\n for (const namespace of namespaceImports) {\n content = content.replace(new RegExp(`\\\\b${ namespace }\\\\.`, 'g'), '');\n }\n\n return content;\n }\n\n /**\n * Processes import declaration → tracks dependencies and collects imported names.\n *\n * @param stmt - import declaration AST node\n * @param node - graph node to update\n * @param namespaceImports - mutable list of internal namespace-import names whose\n * `Name.` qualifier must be stripped after inlining\n * @param aliasRenames - mutable list of internal `[ original, local ]` pairs for\n * re-aliased named imports whose local name must be rewritten to the original\n *\n * @since 2.0.0\n */\n\n private handleImport(\n stmt: ts.ImportDeclaration,\n node: FileNodeInterface,\n namespaceImports: Array<string>,\n aliasRenames: Array<[ original: string, local: string ]>\n ): void {\n const { importClause, moduleSpecifier } = stmt;\n if (!importClause || !moduleSpecifier) return;\n\n const moduleInfo = this.resolveModule(moduleSpecifier, node.fileName);\n if (!moduleInfo) return;\n\n const { fileName, isExternal } = moduleInfo;\n\n if (!isExternal) {\n node.internalDeps.add(fileName);\n\n const { namedBindings } = importClause;\n if(!namedBindings) return;\n\n if (ts.isNamespaceImport(namedBindings)) {\n namespaceImports.push(namedBindings.name.text);\n } else if (ts.isNamedImports(namedBindings)) {\n for (const element of namedBindings.elements) {\n if (element.propertyName) {\n aliasRenames.push([ element.propertyName.text, element.name.text ]);\n }\n }\n }\n\n return;\n }\n\n if (!importClause) {\n // Side-effect import: import 'module'\n node.externalImports.namespace[fileName] = '';\n\n return;\n }\n\n // Default import: import Foo from 'module'\n if (importClause.name) {\n node.externalImports.default[fileName] = importClause.name.text;\n }\n\n const { namedBindings } = importClause;\n if (!namedBindings) return;\n\n if (ts.isNamespaceImport(namedBindings)) {\n // import * as Foo from 'module'\n node.externalImports.namespace[namedBindings.name.text] = fileName;\n } else if (ts.isNamedImports(namedBindings)) {\n // import { a, b as c } from 'module'\n this.addNamedElements(\n node.externalImports.named[fileName] ??= [],\n namedBindings.elements\n );\n }\n }\n\n /**\n * Processes re-export declaration (`export … from …`).\n *\n * @param stmt - export declaration AST node\n * @param node - graph node to update\n *\n * @since 2.0.0\n */\n\n private handleExport(stmt: ts.ExportDeclaration, node: FileNodeInterface): void {\n const { moduleSpecifier, exportClause } = stmt;\n if (!moduleSpecifier) return;\n\n const moduleInfo = this.resolveModule(moduleSpecifier, node.fileName);\n if (!moduleInfo) return;\n\n const { fileName, isExternal } = moduleInfo;\n\n // Track internal dependencies\n if (!isExternal) {\n node.internalDeps.add(fileName);\n }\n\n // export * from 'module'\n if (!exportClause) {\n if (isExternal) {\n node.externalExports.star.push(fileName);\n } else {\n node.internalExports.star.push(fileName);\n }\n\n return;\n }\n\n // export * as Foo from 'module'\n if (ts.isNamespaceExport(exportClause)) {\n if (isExternal) {\n node.externalExports.namespace[exportClause.name.text] = fileName;\n } else {\n node.internalExports.namespace[exportClause.name.text] = fileName;\n }\n\n return;\n }\n\n if (ts.isNamedExports(exportClause)) {\n // export { a, b as c } from 'module'\n if (isExternal) {\n this.addNamedElements(\n node.externalExports.exports[fileName] ??= [],\n exportClause.elements\n );\n } else {\n this.addNamedElements(\n node.internalExports.exports,\n exportClause.elements\n );\n }\n }\n }\n\n /**\n * Extracts locally declared export names from statements with the ` export ` modifier.\n *\n * @param stmt - statement with export modifier\n * @param node - graph node to update\n *\n * @since 2.0.0\n */\n\n private extractExportName(stmt: ts.Statement, node: FileNodeInterface): void {\n if (ts.isVariableStatement(stmt)) {\n for (const decl of stmt.declarationList.declarations) {\n if (ts.isIdentifier(decl.name)) {\n node.internalExports.exports.push(decl.name.text);\n }\n }\n\n return;\n }\n\n // Handle other named declarations\n if (ts.isEnumDeclaration(stmt) ||\n ts.isClassDeclaration(stmt) ||\n ts.isFunctionDeclaration(stmt) ||\n ts.isInterfaceDeclaration(stmt) ||\n ts.isTypeAliasDeclaration(stmt)) {\n if (stmt.name && ts.isIdentifier(stmt.name)) {\n node.internalExports.exports.push(stmt.name.text);\n }\n }\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { CompilerOptions } from 'typescript';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { dirname, relative, toPosix } from '@remotex-labs/xmap';\n\n/**\n * Matches Unix shebang lines at the beginning of files for removal during compilation.\n *\n * @remarks\n * Matches shebang lines (e.g., `#!/usr/bin/env node`) at the start of files,\n * including optional carriage return and line feed characters for cross-platform compatibility.\n *\n * Pattern breakdown:\n * - `^#!` - Start of line with `#!`\n * - `.*` - Any characters until the end of line\n * - `(\\r?\\n)?` - Optional CR+LF or LF line ending\n *\n * @example\n * ```ts\n * const content = '#!/usr/bin/env node\\nconsole.log(\"hello\");';\n * SHEBANG_REGEX.test(content); // true\n * ```\n *\n * @see {@link removeShebang}\n *\n * @since 2.0.0\n */\n\nexport const SHEBANG_REGEX = /^#!.*(\\r?\\n)?/;\n\n/**\n * Matches empty export statements that should be removed from declaration files.\n *\n * @remarks\n * Matches TypeScript empty export statements (`export {};`) which are often\n * generated during compilation but are invalid in final declaration files.\n *\n * Pattern breakdown:\n * - `export {};` - Literal empty export statement\n * - `\\n?` - Optional trailing newline\n *\n * The global flag ensures all occurrences are matched throughout the content.\n *\n * @example\n * ```ts\n * const content = 'export {};\\nexport const x = 1;';\n * EMPTY_EXPORT_REGEX.test(content); // true\n * ```\n *\n * @see {@link removeEmptyExports}\n *\n * @since 2.0.0\n */\n\nexport const EMPTY_EXPORT_REGEX = /export {};\\n?/g;\n\n/**\n * Matches orphaned JSDoc comment blocks that are not associated with any declaration.\n *\n * @remarks\n * Matches consecutive JSDoc comment blocks that appear without associated declarations.\n * These orphaned comments commonly appear in bundled files where comments are preserved\n * during bundling but lose their associated declarations.\n *\n * Pattern breakdown:\n * - `(?:\\/\\*\\*[\\s\\S]*?\\*\\/\\s*)+` - One or more JSDoc blocks with the following whitespace (non-capturing)\n * - `(\\/\\*\\*[\\s\\S]*?\\*\\/)` - Final JSDoc block (captured for potential reuse)\n *\n * The captured group allows preserving the last comment if needed during replacement.\n *\n * @example\n * ```ts\n * const content = '/** Comment 1 *\\/\\n/** Comment 2 *\\/\\nexport const x = 1;';\n * ORPHAN_COMMENT_REGEX.test(content); // true\n * ```\n *\n * @see {@link removeOrphanComments}\n *\n * @since 2.0.0\n */\n\nexport const ORPHAN_COMMENT_REGEX = /(?:\\/\\*\\*[\\s\\S]*?\\*\\/\\s*)+(\\/\\*\\*[\\s\\S]*?\\*\\/)/g;\n\n/**\n * Matches export modifiers on declarations for removal while preserving the declarations themselves.\n *\n * @remarks\n * Matches the `export` keyword (and optional `default`) at the start of lines\n * in declaration files. Used to strip export modifiers while preserving the\n * declaration itself when consolidating exports.\n *\n * Pattern breakdown:\n * - `^export` - Export keyword at line start (multiline mode)\n * - `\\s+` - Required whitespace after export\n * - `(?:default\\s+)?` - Optional default keyword with whitespace\n *\n * The multiline flag (`m`) ensures `^` matches line starts throughout the content.\n *\n * @example\n * ```ts\n * const content = 'export interface Config { x: number; }';\n * content.replace(EXPORT_MODIFIER_REGEX, ''); // 'interface Config { x: number; }'\n * ```\n *\n * @see {@link removeExportModifiers}\n *\n * @since 2.0.0\n */\n\nexport const EXPORT_MODIFIER_REGEX = /^export\\s+(?:default\\s+)?/gm;\n\n/**\n * Matches single-line trailing JSDoc comment blocks at the end of lines for removal.\n *\n * @remarks\n * Matches JSDoc comment blocks that appear at the end of lines, including\n * surrounding whitespace. Used to clean up documentation comments that are\n * misplaced or unnecessary in bundled output.\n *\n * Pattern breakdown:\n * - `\\s*` - Leading whitespace\n * - `\\/\\*\\*[^\\\\r\\\\n]*?\\*\\/` - Single-line JSDoc comment block (no line breaks)\n * - `\\s*$` - Trailing whitespace and end of line\n *\n * @example\n * ```ts\n * const content = 'const x = 1; /** Documentation *\\/';\n * TRAILING_COMMENT_REGEX.test(content); // true\n * ```\n *\n * @see {@link removeOrphanComments}\n *\n * @since 2.0.0\n */\n\nexport const TRAILING_COMMENT_REGEX = /(?<=[:;,{}\\[\\]()\\w\"'`])[ \\t]*\\/\\*\\*[^\\r\\n]*?\\*\\/[ \\t]*$/gm;\n\n/**\n * Removes shebang line from the beginning of file content.\n *\n * @param content - The file content to process\n *\n * @returns Content with shebang line removed, or unchanged if no shebang present\n *\n * @remarks\n * Removes Unix shebang lines (e.g., `#!/usr/bin/env node`) from the start of files.\n * Uses character code checks for performance (35 = '#', 33 = '!'), avoiding regex\n * execution for files that don't have shebangs.\n *\n * Shebang lines are typically only present in executable scripts and are not valid\n * in declaration files or bundled TypeScript code.\n *\n * @example\n * ```ts\n * const withShebang = '#!/usr/bin/env node\\nconsole.log(\"hello\");';\n * const cleaned = removeShebang(withShebang);\n * // 'console.log(\"hello\");'\n * ```\n *\n * @see {@link cleanContent}\n * @see {@link SHEBANG_REGEX}\n *\n * @since 2.0.0\n */\n\nexport function removeShebang(content: string): string {\n // 35 = '#', 33 = '!'\n return (content.charCodeAt(0) === 35 && content.charCodeAt(1) === 33)\n ? content.replace(SHEBANG_REGEX, '')\n : content;\n}\n\n/**\n * Removes empty export statements from file content.\n *\n * @param content - The file content to process\n *\n * @returns Content with all empty export statements removed\n *\n * @remarks\n * Removes `export {};` statements which TypeScript often generates to mark\n * a file as an ES module without exporting anything. These statements are invalid\n * in declaration files and should be removed during compilation.\n *\n * Performs a quick string check before applying the regex for performance optimization.\n *\n * @example\n * ```ts\n * const content = 'export {};\\nexport const x = 1;';\n * const cleaned = removeEmptyExports(content);\n * // 'export const x = 1;'\n * ```\n *\n * @see {@link cleanContent}\n * @see {@link EMPTY_EXPORT_REGEX}\n *\n * @since 2.0.0\n */\n\nexport function removeEmptyExports(content: string): string {\n return content.includes('export {}')\n ? content.replace(EMPTY_EXPORT_REGEX, '')\n : content;\n}\n\n/**\n * Removes orphaned and trailing JSDoc comment blocks from file content.\n *\n * @param content - The file content to process\n *\n * @returns Content with orphaned and trailing comments removed\n *\n * @remarks\n * Performs two sequential cleaning operations:\n * 1. Removes trailing JSDoc comments at the end of lines\n * 2. Removes orphaned JSDoc blocks (comments not associated with declarations)\n *\n * Orphaned comments commonly appear in bundled files where comments are preserved\n * during bundling but lose their associated declarations due to tree shaking or\n * module consolidation.\n *\n * The replacement pattern `'$1'` preserves the last comment in a sequence of orphaned\n * comments if it might still be associated with a declaration.\n *\n * @example\n * ```ts\n * const content = '/** Orphan *\\/\\n/** Doc *\\/\\nexport const x = 1;';\n * const cleaned = removeOrphanComments(content);\n * // Removes orphaned comments while preserving declaration-associated ones\n * ```\n *\n * @see {@link cleanContent}\n * @see {@link ORPHAN_COMMENT_REGEX}\n * @see {@link TRAILING_COMMENT_REGEX}\n *\n * @since 2.0.0\n */\n\nexport function removeOrphanComments(content: string): string {\n content = content.replace(TRAILING_COMMENT_REGEX, '');\n\n return content.replace(ORPHAN_COMMENT_REGEX, '$1');\n}\n\n/**\n * Removes export modifiers from all declarations while preserving the declarations themselves.\n *\n * @param content - The file content to process\n *\n * @returns Content with export modifiers removed from all declarations\n *\n * @remarks\n * Strips `export` and `export default` keywords from declarations, transforming:\n * - `export const x = 1;` → `const x = 1;`\n * - `export default interface Config {}` → `interface Config {}`\n * - `export function foo() {}` → `function foo() {}`\n *\n * This transformation is used when bundling declarations to remove export modifiers\n * from internal declarations that will be consolidated into a single export list or\n * re-exported through a barrel file.\n *\n * @example\n * ```ts\n * const content = 'export const x = 1;\\nexport function foo() {}';\n * const cleaned = removeExportModifiers(content);\n * // 'const x = 1;\\nfunction foo() {}'\n * ```\n *\n * @see {@link cleanContent}\n * @see {@link EXPORT_MODIFIER_REGEX}\n *\n * @since 2.0.0\n */\n\nexport function removeExportModifiers(content: string): string {\n return content.replace(EXPORT_MODIFIER_REGEX, '');\n}\n\n/**\n * Checks whether file content contains elements that require cleaning.\n *\n * @param content - The file content to check\n *\n * @returns `true` if content requires cleaning operations, `false` otherwise\n *\n * @remarks\n * Performs quick checks to determine if cleaning operations are necessary:\n * - Checks for shebang (character code 35 = '#')\n * - Checks for empty export statements\n * - Checks for JSDoc comments\n *\n * Used to short-circuit expensive cleaning operations when content doesn't need\n * processing, improving performance on already-clean files.\n *\n * @example\n * ```ts\n * needsCleaning('export const x = 1;'); // false\n * needsCleaning('#!/bin/bash\\nexport const x = 1;'); // true\n * needsCleaning('export {};\\nexport const x = 1;'); // true\n * needsCleaning('/** Doc *\\/\\nexport const x = 1;'); // true\n * ```\n *\n * @see {@link cleanContent}\n *\n * @since 2.0.0\n */\n\nexport function needsCleaning(content: string): boolean {\n return content.charCodeAt(0) === 35 || // '#' for shebang\n content.includes('export {}') ||\n content.includes('/**');\n}\n\n/**\n * Applies all cleaning transformations to file content in sequence.\n *\n * @param content - The file content to clean\n *\n * @returns Cleaned content with all transformations applied\n *\n * @remarks\n * Applies cleaning operations in the following order:\n * 1. Short-circuit check using {@link needsCleaning} for performance\n * 2. Removes shebang lines\n * 3. Removes empty export statements\n * 4. Removes orphaned JSDoc comments\n *\n * Typically applied to declaration files during emission or bundling to remove\n * artifacts that are not valid in `.d.ts` files or that clutter bundled output.\n * The sequential application ensures all unwanted elements are removed while\n * preserving valid TypeScript declarations.\n *\n * @example\n * ```ts\n * const raw = `#!/usr/bin/env node\n * /**\n * * Orphaned comment\n * *\\/\n * export {};\n * export const x = 1;`;\n *\n * const cleaned = cleanContent(raw);\n * // 'export const x = 1;'\n * ```\n *\n * @see {@link needsCleaning}\n * @see {@link removeShebang}\n * @see {@link removeEmptyExports}\n * @see {@link removeOrphanComments}\n *\n * @since 2.0.0\n */\n\nexport function cleanContent(content: string): string {\n if (!needsCleaning(content)) return content;\n\n content = removeShebang(content);\n content = removeEmptyExports(content);\n content = removeOrphanComments(content);\n\n return content;\n}\n\n\n/**\n * Calculates the output file path for a compiled TypeScript declaration file.\n *\n * @param sourcePath - The source TypeScript file path\n * @param options - TypeScript compiler options containing output directory settings\n *\n * @returns The normalized output path for the declaration file with forward slashes\n *\n * @remarks\n * Determines an output path using the following logic:\n * 1. Selects output base: `declarationDir` `>` `outDir` `>` source directory\n * 2. Selects root directory: `rootDir` `>` source directory\n * 3. Computes a relative path from root to a source file\n * 4. Changes file extension from `.ts`/`.tsx` to `.d.ts`\n * 5. Combines an output base path with the output file name\n * 6. Resolves a full path and normalizes to forward slashes\n *\n * Path resolution example:\n * - Source: `/project/src/components/Button.tsx`\n * - Root: `/project/src`\n * - Relative: `components/Button.tsx`\n * - Output file: `components/Button.d.ts`\n * - Final: `/project/dist/components/Button.d.ts`\n *\n * @example\n * ```ts\n * const sourcePath = '/project/src/index.ts';\n * const options: CompilerOptions = {\n * outDir: 'dist',\n * rootDir: 'src'\n * };\n *\n * const outputPath = calculateOutputPath(sourcePath, options);\n * // '/project/dist/index.d.ts'\n * ```\n *\n * @example\n * ```ts\n * // With declarationDir override\n * const options: CompilerOptions = {\n * outDir: 'dist',\n * declarationDir: 'types',\n * rootDir: 'src'\n * };\n *\n * const outputPath = calculateOutputPath(sourcePath, options);\n * // '/project/types/index.d.ts'\n * ```\n *\n * @see {@link EmitterService}\n * @see {@link BundlerService}\n *\n * @since 2.0.0\n */\n\nexport function calculateOutputPath(sourcePath: string, options: CompilerOptions): string {\n const { outDir, rootDir, declarationDir } = options;\n\n const outputBase = declarationDir || outDir || dirname(sourcePath);\n const root = rootDir || dirname(sourcePath);\n\n const relativePath = relative(root, sourcePath);\n const outputFileName = relativePath.replace(/\\.tsx?$/, '.d.ts');\n const fullPath = ts.sys.resolvePath(`${ outputBase }/${ outputFileName }`);\n\n return toPosix(fullPath);\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { ParsedCommandLine, LanguageService, Diagnostic } from 'typescript';\nimport type { CachedServiceInterface, DiagnosticInterface } from './interfaces/typescript-service.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { matchesGlob } from 'path';\nimport { relative } from '@remotex-labs/xmap';\nimport { Injectable } from '@symlinks/symlinks.module';\nimport { BundlerService } from '@typescript/services/bundler.service';\nimport { EmitterService } from '@typescript/services/emitter.service';\nimport { LanguageHostService } from '@typescript/services/hosts.service';\n\n/**\n * Manages TypeScript language services with caching and reference counting for shared compiler instances.\n * Provides type checking, code emission, and bundling capabilities through a unified interface that coordinates\n * multiple internal services while maintaining efficient resource usage across multiple consumers.\n *\n * @remarks\n * This service implements a caching strategy to share language service instances across multiple consumers\n * that reference the same `tsconfig.json` file. The lifecycle is managed through reference counting:\n * - Each instantiation increments the reference count for the config path\n * - Calling {@link dispose} decrements the count\n * - When the count reaches zero, the language service is cleaned up automatically\n *\n * The service coordinates three key subsystems:\n * - Language service and host for type checking and analysis\n * - Emitter service for standard TypeScript compilation output\n * - Bundler service for creating bundled outputs from entry points\n *\n * @example\n * ```ts\n * const service = new TypescriptService('tsconfig.json');\n *\n * // Type check all files\n * const diagnostics = service.check();\n * if (diagnostics.length > 0) {\n * console.error('Type errors found:', diagnostics);\n * }\n *\n * // Emit compiled output\n * await service.emit('./dist');\n *\n * // Clean up when done\n * service.dispose('tsconfig.json');\n * ```\n *\n * @see {@link EmitterService}\n * @see {@link BundlerService}\n * @see {@link LanguageHostService}\n *\n * @since 2.0.0\n */\n\n@Injectable({\n providers: [{ useValue: 'tsconfig.json' }]\n})\nexport class TypescriptService {\n /**\n * Parsed TypeScript compiler configuration including options, file names, and project references.\n * @since 2.0.0\n */\n\n readonly config: ParsedCommandLine;\n\n /**\n * TypeScript language service instance providing type checking, intellisense, and compilation capabilities.\n * @since 2.0.0\n */\n\n readonly languageService: LanguageService;\n\n /**\n * Custom language service host managing file system interactions and compiler options.\n * @since 2.0.0\n */\n\n readonly languageHostService: LanguageHostService;\n\n /**\n * Shared cache mapping config paths to language service instances with reference counting.\n *\n * @remarks\n * This static cache enables multiple service instances to share the same underlying language service\n * when they reference the same `tsconfig.json` file, reducing memory usage and compilation overhead.\n * Entries are automatically cleaned up when reference counts reach zero.\n *\n * @since 2.0.0\n */\n\n private static readonly serviceCache = new Map<string, CachedServiceInterface>();\n\n /**\n * Service responsible for emitting compiled TypeScript output files.\n * @since 2.0.0\n */\n\n private readonly emitterService: EmitterService;\n\n /**\n * Service responsible for creating bundled outputs from entry points.\n * @since 2.0.0\n */\n\n private readonly bundlerService: BundlerService;\n\n /**\n * Creates a new TypeScript service instance or retrieves a cached one for the specified configuration.\n *\n * @param configPath - Path to the `tsconfig.json` file, defaults to `'tsconfig.json'` in the current directory\n *\n * @remarks\n * The constructor performs the following initialization steps:\n * - Acquires or creates a cached language service for the config path\n * - Increments the reference count for the shared service instance\n * - Touches all files listed in the parsed configuration to ensure they're loaded\n * - Initializes emitter and bundler services with the language service\n *\n * If a language service already exists for the given config path, it will be reused rather than\n * creating a new instance, improving performance and reducing memory usage.\n *\n * @example\n * ```ts\n * // Use default tsconfig.json\n * const service = new TypescriptService();\n *\n * // Use custom config path\n * const customService = new TypescriptService('./custom-tsconfig.json');\n * ```\n *\n * @see {@link acquireLanguageService}\n * @see {@link LanguageHostService.touchFiles}\n *\n * @since 2.0.0\n */\n\n constructor(private configPath: string = 'tsconfig.json') {\n const { config, host, service } = this.acquireLanguageService();\n\n this.config = config;\n this.languageService = service;\n this.languageHostService = host;\n this.languageHostService.touchFiles(this.config.fileNames);\n\n this.emitterService = new EmitterService(service, host);\n this.bundlerService = new BundlerService(service, host);\n }\n\n /**\n * Performs type checking on all source files in the project and returns collected diagnostics.\n *\n * @returns Array of formatted diagnostic information including errors, warnings, and suggestions\n *\n * @remarks\n * This method filters out files that should not be checked (such as `node_modules` and declaration files)\n * and collects three types of diagnostics for each remaining file:\n * - Semantic diagnostics (type errors, type mismatches)\n * - Syntactic diagnostics (parse errors, invalid syntax)\n * - Suggestion diagnostics (optional improvements can be slow)\n *\n * If the language service has no program available, an empty array is returned.\n *\n * @example\n * ```ts\n * const service = new TypescriptService();\n * const diagnostics = service.check();\n *\n * for (const diagnostic of diagnostics) {\n * console.log(`${diagnostic.file}:${diagnostic.line}:${diagnostic.column}`);\n * console.log(`${diagnostic.message}`);\n * }\n * ```\n *\n * @see {@link shouldCheckFile}\n * @see {@link collectDiagnostics}\n *\n * @since 2.0.0\n */\n\n check(filesList?: Array<string>): Array<DiagnosticInterface> {\n const program = this.languageService.getProgram();\n if (!program) return [];\n\n const files = (filesList && filesList.length > 0) ?\n filesList.map(file => program.getSourceFile(file)!) :\n this.languageService.getProgram()?.getSourceFiles();\n\n if (!files) return [];\n\n return files\n .filter(file => this.shouldCheckFile(file))\n .flatMap(file => this.collectDiagnostics(file));\n }\n\n /**\n * Marks files as modified to trigger recompilation and updates configuration if the config file changed.\n *\n * @param files - Array of file paths that have been modified or created\n *\n * @remarks\n * This method performs two key operations:\n * - For files that exist in the script snapshot cache, marks them as touched to invalidate cached data\n * - If the modified files include the `tsconfig.json` file, reloads the configuration and updates the host options\n *\n * This is essential for watch mode scenarios where files change during development and the service\n * needs to stay synchronized with the file system state.\n *\n * @example\n * ```ts\n * const service = new TypescriptService();\n *\n * // Notify service of file changes\n * service.touchFiles(['src/index.ts', 'src/utils.ts']);\n *\n * // Config change triggers reload\n * service.touchFiles(['tsconfig.json']);\n * ```\n *\n * @see {@link LanguageHostService.touchFile}\n * @see {@link LanguageHostService.hasScriptSnapshot}\n *\n * @since 2.0.0\n */\n\n touchFiles(files: Array<string>): void {\n for (const file of files) {\n if (this.languageHostService.hasScriptSnapshot(file)) {\n this.languageHostService.touchFile(file);\n }\n\n if (file.includes(this.configPath)) {\n const cached = TypescriptService.serviceCache.get(this.configPath)!;\n cached.config = this.parseConfig();\n cached.host.options = cached.config.options;\n }\n }\n }\n\n /**\n * Emits a bundled output by processing specified entry points through the bundler service.\n *\n * @param entryPoints - Record mapping bundle names to their entry point file paths\n * @param outdir - Optional output directory path, uses compiler options default if not specified\n *\n * @returns Promise that resolves when bundling and emission completes\n *\n * @remarks\n * This method delegates to the bundler service which handles dependency resolution, tree shaking,\n * and output generation. Unlike standard emission, bundling combines multiple modules into\n * optimized output files.\n *\n * @example\n * ```ts\n * const service = new TypescriptService();\n *\n * await service.emitBundle(\n * { 'main': './src/index.ts', 'worker': './src/worker.ts' },\n * './dist/bundles'\n * );\n * ```\n *\n * @see {@link BundlerService.emit}\n *\n * @since 2.0.0\n */\n\n async emitBundle(entryPoints: Record<string, string>, outdir?: string): Promise<void> {\n await this.bundlerService.emit(entryPoints, outdir);\n }\n\n /**\n * Emits compiled TypeScript output files to the specified directory.\n *\n * @param outdir - Optional output directory path, uses compiler options default if not specified\n *\n * @returns Promise that resolves when emission completes\n *\n * @remarks\n * This method performs standard TypeScript compilation, emitting JavaScript files, declaration files,\n * and source maps according to the compiler options. The emission includes all files in the program\n * that are not excluded by configuration.\n *\n * @example\n * ```ts\n * const service = new TypescriptService();\n *\n * // Emit to default outDir from tsconfig\n * await service.emit();\n *\n * // Emit to custom directory\n * await service.emit('./build');\n * ```\n *\n * @see {@link EmitterService.emit}\n *\n * @since 2.0.0\n */\n\n async emit(outdir?: string): Promise<void> {\n await this.emitterService.emit(outdir);\n }\n\n /**\n * Decrements the reference count for a cached service and cleans up if no longer in use.\n *\n * @param tsconfigPath - Path to the TypeScript configuration file identifying which cached service to dispose\n *\n * @remarks\n * This method implements the cleanup phase of the reference counting lifecycle. When the reference count\n * reaches zero, the language service is disposed of and removed from the cache. This should be called\n * when a consumer no longer needs the TypeScript service to prevent resource leaks.\n *\n * If no cached service exists for the given path, this method does nothing.\n *\n * @example\n * ```ts\n * const service = new TypescriptService('tsconfig.json');\n *\n * // Use the service...\n * const diagnostics = service.check();\n *\n * // Clean up when done\n * service.dispose('tsconfig.json');\n * ```\n *\n * @see {@link cleanupUnusedServices}\n *\n * @since 2.0.0\n */\n\n dispose(tsconfigPath: string): void {\n const cached = TypescriptService.serviceCache.get(tsconfigPath);\n if (!cached) return;\n\n cached.refCount--;\n TypescriptService.cleanupUnusedServices();\n }\n\n /**\n * Removes cached language services with zero references and disposes of their resources.\n *\n * @remarks\n * This static method iterates through the service cache and removes entries where the reference\n * count has dropped below one. For each removed entry, the language service's `dispose()` method\n * is called to clean up internal resources before deletion from the cache.\n *\n * This method is called automatically by {@link dispose} and should not typically be invoked directly.\n *\n * @see {@link dispose}\n *\n * @since 2.0.0\n */\n\n private static cleanupUnusedServices(): void {\n for (const [ path, cached ] of this.serviceCache) {\n if (cached.refCount < 1) {\n cached.service.dispose();\n this.serviceCache.delete(path);\n }\n }\n }\n\n /**\n * Determines whether a source file should be included in type checking.\n *\n * @param file - TypeScript source file to evaluate\n *\n * @returns `true` if the file should be checked, `false` if it should be excluded\n *\n * @remarks\n * Files are excluded from checking if they meet either condition:\n * - Located in the ` node_modules ` directory (third-party dependencies)\n * - Are TypeScript declaration files (`.d.ts` files)\n *\n * @since 2.0.0\n */\n\n private shouldCheckFile(file: ts.SourceFile): boolean {\n if(!file || file.fileName.includes('node_modules')) return false;\n if(this.config.raw?.exclude) {\n for (const pattern of this.config.raw.exclude) {\n if (matchesGlob(relative(this.config.options.rootDir!, file.fileName), pattern))\n return false;\n }\n }\n\n return !file.isDeclarationFile;\n }\n\n /**\n * Collects all diagnostic information for a source file, including errors, warnings, and suggestions.\n *\n * @param file - TypeScript source file to collect diagnostics from\n *\n * @returns Array of formatted diagnostic objects with file location and message details\n *\n * @remarks\n * This method gathers three types of diagnostics:\n * - Semantic diagnostics: type errors, undefined variables, type mismatches\n * - Syntactic diagnostics: parse errors, invalid syntax, malformed code\n * - Suggestion diagnostics: optional code improvements (can impact performance)\n *\n * Each diagnostic is formatted using {@link formatDiagnostic} to provide consistent output.\n *\n * @see {@link formatDiagnostic}\n *\n * @since 2.0.0\n */\n\n private collectDiagnostics(file: ts.SourceFile): DiagnosticInterface[] {\n return [\n ...this.languageService.getSemanticDiagnostics(file.fileName),\n ...this.languageService.getSyntacticDiagnostics(file.fileName),\n ...this.languageService.getSuggestionDiagnostics(file.fileName) // optional: slow\n ].map(d => this.formatDiagnostic(d));\n }\n\n /**\n * Retrieves an existing cached language service or creates a new one if none exists.\n *\n * @returns Cached service interface containing config, host, service, and reference count\n *\n * @remarks\n * This method checks the static service cache for an existing language service matching the\n * current `configPath`. If found, it increments the reference count and returns the cached instance.\n * If not found, it delegates to {@link createLanguageService} to create and cache a new instance.\n *\n * @see {@link createLanguageService}\n *\n * @since 2.0.0\n */\n\n private acquireLanguageService(): CachedServiceInterface {\n const cached = TypescriptService.serviceCache.get(this.configPath);\n if (cached) {\n cached.refCount++;\n\n return cached;\n }\n\n return this.createLanguageService();\n }\n\n /**\n * Creates a new language service instance with host and caches it for future reuse.\n *\n * @returns Newly created cached service interface with reference count initialized to 1\n *\n * @remarks\n * This method performs the following steps:\n * - Parses the TypeScript configuration using {@link parseConfig}\n * - Creates a new language service host with the parsed options\n * - Initializes a TypeScript language service with the host and document registry\n * - Wraps everything in a cache entry with `refCount` set to 1\n * - Stores the entry in the static service cache\n *\n * @see {@link parseConfig}\n * @see {@link LanguageHostService}\n *\n * @since 2.0.0\n */\n\n private createLanguageService(): CachedServiceInterface {\n const config = this.parseConfig();\n const host = new LanguageHostService(config.options);\n const service = ts.createLanguageService(host, ts.createDocumentRegistry());\n\n const cached: CachedServiceInterface = { config, host, service, refCount: 1 };\n TypescriptService.serviceCache.set(this.configPath, cached);\n\n return cached;\n }\n\n /**\n * Creates a new language service instance with host and caches it for future reuse.\n *\n * @returns Newly created cached service interface with reference count initialized to 1\n *\n * @remarks\n * This method performs the following steps:\n * - Parses the TypeScript configuration using {@link parseConfig}\n * - Creates a new language service host with the parsed options\n * - Initializes a TypeScript language service with the host and document registry\n * - Wraps everything in a cache entry with `refCount` set to 1\n * - Stores the entry in the static service cache\n *\n * @see {@link parseConfig}\n * @see {@link LanguageHostService}\n *\n * @since 2.0.0\n */\n\n private parseConfig(): ParsedCommandLine {\n let config = ts.getParsedCommandLineOfConfigFile(\n this.configPath,\n {\n sourceMap: false,\n skipLibCheck: true,\n stripInternal: true,\n declarationMap: false,\n emitDeclarationOnly: true\n },\n {\n ...ts.sys,\n onUnRecoverableConfigFileDiagnostic: () => {}\n }\n );\n\n if (!config) {\n config = {\n options: {\n strict: true,\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.NodeNext,\n sourceMap: false,\n skipLibCheck: true,\n stripInternal: true,\n declarationMap: false,\n emitDeclarationOnly: true,\n moduleResolution: ts.ModuleResolutionKind.NodeNext\n },\n errors: [],\n fileNames: [],\n projectReferences: undefined\n };\n }\n\n config.options = {\n ...config.options,\n rootDir: config.options?.rootDir ?? process.cwd()\n };\n\n return config;\n }\n\n /**\n * Converts a TypeScript diagnostic into a standardized diagnostic interface with a formatted message and location.\n *\n * @param diagnostic - Raw TypeScript diagnostic from the compiler\n *\n * @returns Formatted diagnostic object with message, file path, line, column, and error code\n *\n * @remarks\n * This method flattens multi-line diagnostic messages into a single string using newline separators.\n * If the diagnostic includes file and position information, it calculates the human-readable line and\n * column numbers (1-indexed) and includes the diagnostic code.\n *\n * If no file or position information is available, only the message is included in the result.\n *\n * @since 2.0.0\n */\n\n private formatDiagnostic(diagnostic: Diagnostic): DiagnosticInterface {\n const result: DiagnosticInterface = {\n message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n'),\n category: diagnostic.category\n };\n\n if (diagnostic.file && diagnostic.start !== undefined) {\n const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n result.file = diagnostic.file.fileName;\n result.line = line + 1;\n result.column = character + 1;\n result.code = diagnostic.code;\n }\n\n return result;\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { LanguageService, Program, SourceFile } from 'typescript';\nimport type { LanguageHostService } from '@typescript/services/hosts.service';\nimport type { FileNodeInterface } from '@typescript/models/interfaces/graph-model.interface';\nimport type { BundleExportsInterface } from '@typescript/services/interfaces/bundler-serrvice.interface';\nimport type { ModuleImportsInterface } from '@typescript/services/interfaces/bundler-serrvice.interface';\nimport type { NamespaceExportsInterface } from '@typescript/services/interfaces/bundler-serrvice.interface';\n\n/**\n * Imports\n */\n\nimport { mkdir, writeFile } from 'fs/promises';\nimport { join, dirname } from '@remotex-labs/xmap';\nimport { inject } from '@symlinks/symlinks.module';\nimport { GraphModel } from '@typescript/models/graph.model';\nimport { HeaderDeclarationBundle } from '@typescript/constants/typescript.constant';\n\n/**\n * Bundles multiple internal TypeScript files into consolidated, cleaned declaration files (.d.ts bundles).\n *\n * Starting from one or more entry points, traverses the internal dependency graph, collects all\n * relevant declarations, flattens namespaces, deduplicates exports, gathers external imports,\n * and writes a single portable declaration file per entry point.\n *\n * Primarily used for module federation, library publishing, public API bundling, or\n * creating type-only entry points that hide implementation details.\n *\n * @since 2.0.0\n */\n\nexport class BundlerService {\n /**\n * Injected singleton instance of the dependency graph builder.\n *\n * Provides scanned file nodes with cleaned content, internal dependencies,\n * and detailed import/export information.\n *\n * @remarks\n * Resolved via the framework's `inject()` helper — always returns the shared singleton.\n *\n * @see {@link GraphModel}\n * @since 2.0.0\n */\n\n private readonly graphModel = inject(GraphModel);\n\n /**\n * Creates bundler bound to a specific language service and host.\n *\n * @param languageService - active TS language service\n * @param languageHostService - host with compiler options and resolution\n *\n * @since 2.0.0\n */\n\n constructor(private languageService: LanguageService, private languageHostService: LanguageHostService) {\n }\n\n /**\n * Bundles declarations for each entry point and writes consolidated .d.ts files.\n *\n * @param entryPoints - map of output filename (without extension) → entry file path\n * @param outdir - optional override for output directory\n * @returns promise that resolves when all bundles are written\n *\n * @throws Error when language service program is unavailable\n *\n * @example\n * ```ts\n * await bundler.emit({\n * index: './src/index.ts',\n * components: './src/components/index.ts',\n * utils: './src/utils/index.ts'\n * }, './dist/types');\n *\n * // Results in:\n * // dist/types/index.d.ts\n * // dist/types/components.d.ts\n * // dist/types/utils.d.ts\n * ```\n *\n * @see {@link bundleCollectDeclarations}\n * @since 2.0.0\n */\n\n async emit(entryPoints: Record<string, string>, outdir?: string): Promise<void> {\n const program = this.languageService?.getProgram();\n if (!program) throw new Error('Language service program not available');\n\n let config = this.languageHostService.getCompilationSettings();\n if (outdir) config = { ...config, outDir: outdir };\n\n await Promise.all(\n Object.entries(entryPoints).map(async ([ outputPath, entryFile ]) => {\n const sourceFile = program.getSourceFile(entryFile);\n if (!sourceFile) return;\n\n const outputFile = join(config.outDir!, `${ outputPath }.d.ts`);\n await this.bundleCollectDeclarations(sourceFile, program, outputFile);\n })\n );\n }\n\n /**\n * Scans entry point, collects transitive declarations, and writes a bundled file.\n *\n * @param source - entry source file\n * @param program - current program (for source file lookup)\n * @param output - target output file path\n * @returns promise that resolves when write completes\n *\n * @since 2.0.0\n */\n\n private async bundleCollectDeclarations(source: SourceFile, program: Program, output: string): Promise<void> {\n const entryDeclaration = this.graphModel.scan(\n source, this.languageService, this.languageHostService\n );\n\n const content = await this.getBundleContent(entryDeclaration, program);\n await mkdir(dirname(output), { recursive: true });\n await writeFile(output, content, 'utf-8');\n }\n\n /**\n * Performs DFS traversal of internal dependencies, collects all relevant content,\n * and prepares it for final bundling.\n *\n * @param entryPoint - scanned entry file node\n * @param program - program for source file lookup\n * @returns concatenated and processed bundle content\n *\n * @remarks\n * Handles transitive star exports by propagating them during traversal.\n *\n * @since 2.0.0\n */\n\n private async getBundleContent(entryPoint: FileNodeInterface, program: Program): Promise<string> {\n const visited = new Set<string>();\n const exportList = new Set([ entryPoint ]);\n const dependencyList = new Set([ entryPoint ]);\n const dependencyQueue = [ ...entryPoint.internalDeps ];\n const starExportModules = new Set(entryPoint.internalExports.star);\n\n let content = '';\n while (dependencyQueue.length > 0) {\n const currentFile = dependencyQueue.pop()!;\n if (visited.has(currentFile)) continue;\n visited.add(currentFile);\n\n const sourceFile = program.getSourceFile(currentFile);\n if (!sourceFile) continue;\n\n const declaration = this.graphModel.scan(sourceFile, this.languageService, this.languageHostService);\n dependencyList.add(declaration);\n\n if (starExportModules.has(currentFile)) {\n exportList.add(declaration);\n for (const starModule of declaration.internalExports.star) starExportModules.add(starModule);\n }\n\n for (const dep of declaration.internalDeps) {\n if (!visited.has(dep)) dependencyQueue.push(dep);\n }\n\n content += declaration.content;\n }\n\n content += entryPoint.content;\n\n return this.parseContent(content, dependencyList, exportList);\n }\n\n /**\n * Aggregates all external imports across the bundle into a deduplicated map.\n *\n * @param declarations - set of scanned file nodes in the bundle\n * @returns map of module → consolidated imports (default, named, namespace)\n *\n * @since 2.0.0\n */\n\n private collectExternalImports(declarations: Set<FileNodeInterface>): Map<string, ModuleImportsInterface> {\n const imports = new Map<string, ModuleImportsInterface>();\n for (const declaration of declarations) {\n // Default imports: import Foo from 'module'\n for (const [ module, name ] of Object.entries(declaration.externalImports.default)) {\n if (!imports.has(module)) {\n imports.set(module, { named: new Set(), namespace: new Map() });\n }\n const moduleImports = imports.get(module)!;\n if (!moduleImports.default) {\n moduleImports.default = name;\n }\n }\n\n // Named imports: import { a, b } from 'module'\n for (const [ module, names ] of Object.entries(declaration.externalImports.named)) {\n if (!imports.has(module)) {\n imports.set(module, { named: new Set(), namespace: new Map() });\n }\n for (const name of names) {\n imports.get(module)!.named.add(name);\n }\n }\n\n // Namespace imports: import * as Foo from 'module'\n for (const [ name, module ] of Object.entries(declaration.externalImports.namespace)) {\n if (!imports.has(module)) {\n imports.set(module, { named: new Set(), namespace: new Map() });\n }\n imports.get(module)!.namespace.set(name, module);\n }\n }\n\n return imports;\n }\n\n /**\n * Converts collected external imports into sorted import statements.\n *\n * @param imports - deduplicated imports map\n * @returns array of `import … from …` statements\n *\n * @remarks\n * Namespace imports are emitted separately to preserve `* as` semantics.\n *\n * @since 2.0.0\n */\n\n private generateImportStatements(imports: Map<string, ModuleImportsInterface>): Array<string> {\n const statements: Array<string> = [];\n for (const [ module, { default: defaultImport, named, namespace }] of imports) {\n const parts: Array<string> = [];\n\n if (defaultImport) {\n parts.push(defaultImport);\n }\n\n if (named.size > 0) {\n parts.push(`{ ${ Array.from(named).sort().join(', ') } }`);\n }\n\n if (namespace.size > 0) {\n for (const [ name ] of namespace) {\n statements.push(`import * as ${ name } from '${ module }';`);\n }\n }\n\n if (parts.length > 0) {\n statements.push(`import ${ parts.join(', ') } from '${ module }';`);\n }\n }\n\n return statements;\n }\n\n /**\n * Recursively collects exports from a namespace-exported module.\n *\n * @param fileName - file to start recursion from\n * @param visited - prevents cycles\n * @returns collected exports and supporting declarations\n *\n * @since 2.0.0\n */\n\n private collectNamespaceExports(fileName: string, visited = new Set<string>()): NamespaceExportsInterface {\n if (visited.has(fileName)) {\n return { exports: [], declarations: [] };\n }\n visited.add(fileName);\n\n const declaration = this.graphModel.get(fileName);\n if (!declaration) {\n return { exports: [], declarations: [] };\n }\n\n const exports: Array<string> = [ ...declaration.internalExports.exports ];\n const declarations: Array<string> = [];\n\n // Handle namespace exports: export * as Foo from './module'\n for (const [ namespaceName, targetModule ] of Object.entries(declaration.internalExports.namespace)) {\n const nested = this.collectNamespaceExports(targetModule, visited);\n\n if (nested.exports.length > 0) {\n declarations.push(...nested.declarations);\n declarations.push(`const ${ namespaceName } = { ${ nested.exports.join(', ') } };`);\n exports.push(namespaceName);\n }\n }\n\n // Handle star exports: export * from './module'\n for (const starModule of declaration.externalExports.star) {\n const nested = this.collectNamespaceExports(starModule, visited);\n exports.push(...nested.exports);\n declarations.push(...nested.declarations);\n }\n\n return { exports, declarations };\n }\n\n /**\n * Gathers all exports and supporting declarations for the bundle entry points.\n *\n * @param exportList - set of files that should be re-exported\n * @returns structured bundle exports\n *\n * @since 2.0.0\n */\n\n private collectBundleExports(exportList: Set<FileNodeInterface>): BundleExportsInterface {\n const exports: Array<string> = [];\n const declarations: Array<string> = [];\n const externalExports: Array<string> = [];\n\n for (const declaration of exportList) {\n exports.push(...declaration.internalExports.exports);\n\n // Namespace exports: export * as Foo from './module'\n for (const [ namespaceName, targetModule ] of Object.entries(declaration.internalExports.namespace)) {\n const nested = this.collectNamespaceExports(targetModule);\n\n if (nested.exports.length > 0) {\n declarations.push(...nested.declarations);\n declarations.push(`const ${ namespaceName } = { ${ nested.exports.join(', ') } };`);\n exports.push(namespaceName);\n }\n }\n\n // External star exports: export * from 'external-module'\n for (const module of declaration.externalExports.star) {\n declarations.push(`export * from '${ module }';`);\n }\n\n // External namespace exports: export * as Foo from 'external-module'\n for (const [ namespaceName, module ] of Object.entries(declaration.externalExports.namespace)) {\n externalExports.push(`export * as ${ namespaceName } from '${ module }';`);\n }\n\n // External named exports: export { a, b } from 'external-module'\n for (const [ module, names ] of Object.entries(declaration.externalExports.exports)) {\n externalExports.push(`export { ${ names.join(',\\n') } } from '${ module }';`);\n }\n }\n\n return { exports, declarations, externalExports };\n }\n\n /**\n * Combines all parts into final bundle content with header, imports, declarations, content, and exports.\n *\n * @param content - concatenated cleaned declaration text\n * @param dependencyList - all files in dependency closure\n * @param exportList - files whose exports should be re-exported\n * @returns final bundled declaration text\n *\n * @since 2.0.0\n */\n\n private parseContent(content: string, dependencyList: Set<FileNodeInterface>, exportList: Set<FileNodeInterface>): string {\n const parts: Array<string> = [ HeaderDeclarationBundle ];\n const imports = this.collectExternalImports(dependencyList);\n const importStatements = this.generateImportStatements(imports);\n parts.push(...importStatements);\n\n if (importStatements.length > 0) parts.push(''); // Empty line after imports\n const { exports, declarations, externalExports } = this.collectBundleExports(exportList);\n if (declarations.length > 0) {\n parts.push(...declarations);\n parts.push('');\n }\n\n parts.push(content);\n if (exports.length > 0) {\n const uniqueExports = Array.from(new Set(exports)).sort();\n parts.push(`export {\\n\\t${ uniqueExports.join(',\\n\\t') }\\n};`);\n }\n\n if (externalExports.length > 0) {\n parts.push(...externalExports);\n }\n\n return parts.join('\\n');\n }\n}\n","/**\n * Header text included at the top of generated declaration bundle files.\n *\n * @remarks\n * This constant provides a standardized header comment prepended to all\n * declaration bundle files generated by the TypeScript module. The header clearly\n * indicates that the file was automatically generated and should not be edited manually.\n *\n * The header serves as:\n * - A warning to developers not to manually modify generated files\n * - Documentation indicating the source of the file\n * - A consistent marker for identifying generated declaration files\n *\n * @example\n * ```ts\n * import { HeaderDeclarationBundle } from './typescript.constant';\n * import { writeFileSync } from 'fs';\n *\n * const bundledContent = `${HeaderDeclarationBundle}\\n${actualDeclarations}`;\n * writeFileSync('dist/index.d.ts', bundledContent);\n * ```\n *\n * @since 1.5.9\n */\n\nexport const HeaderDeclarationBundle = `/**\n * This file was automatically generated by xBuild.\n * DO NOT EDIT MANUALLY.\n */\n`;\n","/**\n * Import will remove at compile time\n */\n\nimport type { LanguageHostService } from '@typescript/services/hosts.service';\nimport type { CompilerOptions, Program, SourceFile, LanguageService } from 'typescript';\n\n/**\n * Imports\n */\n\nimport { dirname } from '@remotex-labs/xmap';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { calculateOutputPath, cleanContent } from '@typescript/components/transformer.component';\n\n/**\n * Incremental declaration emitter that writes cleaned `.d.ts` files to disk.\n *\n * Uses the TypeScript language service to emit declaration files only for changed\n * project files (skipping external libraries and unchanged versions), applies alias\n * path resolution, cleans unnecessary content, and writes files to the configured `outDir`.\n *\n * Designed for build tools, watch-mode compilers, module federation setups, or\n * public API packaging workflows that need fresh, minimal type declarations.\n *\n * @since 2.0.0\n */\n\nexport class EmitterService {\n /**\n * Maps output declaration path → last emitted version string.\n *\n * Used to skip redundant emits when file content/version has not changed.\n *\n * @remarks\n * Static, so the cache survives across service instances (useful in long-running processes).\n *\n * @since 2.0.0\n */\n\n private static emittedVersions: Map<string, string> = new Map();\n\n /**\n * Creates emitter bound to a specific language service and host.\n *\n * @param languageService - active TS language service instance\n * @param languageHostService - host with compiler options and resolution capabilities\n *\n * @since 2.0.0\n */\n\n constructor(private languageService: LanguageService, private languageHostService: LanguageHostService) {\n }\n\n /**\n * Clears the static version cache used for incremental emit decisions.\n * @since 2.0.0\n */\n\n static clearCache(): void {\n this.emittedVersions.clear();\n }\n\n /**\n * Emits cleaned declaration files for all changed project source files.\n *\n * @param outdir - optional override for output directory (overrides `outDir` in config)\n * @returns promise that resolves when all writes are complete\n *\n * @throws Error when language service program is unavailable\n *\n * @example\n * ```ts\n * // One-time full emit to custom directory\n * await emitter.emit('./dist/types');\n *\n * // Incremental emit on watch change\n * emitter.emit(); // uses original compilerOptions.outDir\n * ```\n *\n * @see {@link shouldEmitFile}\n * @see {@link emitSingleDeclaration}\n *\n * @since 2.0.0\n */\n\n async emit(outdir?: string): Promise<void> {\n const program = this.languageService.getProgram();\n if (!program) {\n throw new Error(`${ xterm.deepOrange('[TS]') } Language service program is not available`);\n }\n\n let config = this.languageHostService.getCompilationSettings();\n if (outdir) config = { ...config, outDir: outdir };\n\n const filesToEmit: Array<SourceFile> = [];\n const sourceFiles = program.getSourceFiles();\n for (let i = 0; i < sourceFiles.length; i++) {\n const file = sourceFiles[i];\n if (this.shouldEmitFile(file, program, config)) {\n filesToEmit.push(file);\n }\n }\n\n if (filesToEmit.length === 0) return;\n await Promise.all(filesToEmit.map(\n source => this.emitSingleDeclaration(source, config)\n ));\n }\n\n /**\n * Determines whether a source file should be (re-)emitted based on version and type.\n *\n * @param file - candidate source file\n * @param program - current program (for external library check)\n * @param config - effective compiler options (with possible outDir override)\n * @returns `true` if a file needs emission\n *\n * @remarks\n * Skips:\n * - `.d.ts` files\n * - files from external libraries (node_modules)\n * - files whose version matches the last emitted version\n *\n * Updates cache when emission is needed.\n *\n * @since 2.0.0\n */\n\n private shouldEmitFile(file: SourceFile, program: Program, config: CompilerOptions): boolean {\n if (file.isDeclarationFile || program.isSourceFileFromExternalLibrary(file))\n return false;\n\n const outputPath = calculateOutputPath(file.fileName, config);\n const version = EmitterService.emittedVersions.get(outputPath);\n const currentVersion = this.languageHostService.getScriptVersion(file.fileName);\n\n if (!version) {\n EmitterService.emittedVersions.set(\n outputPath, currentVersion\n );\n\n return true;\n }\n\n if (version !== currentVersion) {\n EmitterService.emittedVersions.set(outputPath, currentVersion);\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Emits and writes a single cleaned declaration file to disk.\n *\n * @param sourceFile - file to emit\n * @param options - compiler options (including outDir)\n * @returns promise that resolves when write completes\n *\n * @remarks\n * - Uses `emitOnlyDtsFiles: true`\n * - Applies `cleanContent` and alias resolution (if aliases are configured)\n * - Creates directories recursively if needed\n *\n * @example\n * ```ts\n * // Internal usage pattern\n * const output = languageService.getEmitOutput(file.fileName, true);\n * let text = output.outputFiles[0].text;\n * text = cleanContent(text);\n * if (aliasRegex) text = this.resolveAliases(aliasRegex, text, sourceFile);\n * await writeFile(calculatedPath, text, 'utf8');\n * ```\n *\n * @since 2.0.0\n */\n\n private async emitSingleDeclaration(sourceFile: SourceFile, options: CompilerOptions): Promise<void> {\n const output = this.languageService.getEmitOutput(sourceFile.fileName, true);\n if (output.emitSkipped) return;\n\n let content = output.outputFiles[0].text;\n const fileName = calculateOutputPath(sourceFile.fileName, options);\n\n content = cleanContent(content);\n content = this.languageHostService.resolveAliases(content, sourceFile.fileName, '.d.ts');\n\n await mkdir(dirname(fileName), { recursive: true });\n await writeFile(fileName, content, 'utf8');\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { ResolvedModuleWithFailedLookupLocations } from 'typescript';\nimport type { CompilerOptions, IScriptSnapshot, ModuleResolutionCache } from 'typescript';\nimport type { FileSnapshotInterface } from '@typescript/models/interfaces/files-model.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { inject } from '@symlinks/symlinks.module';\nimport { relative, dirname } from '@remotex-labs/xmap';\nimport { FilesModel } from '@typescript/models/files.model';\n\n/**\n * Implements a TypeScript Language Service host with file snapshot caching and module resolution.\n *\n * @remarks\n * The `LanguageHostService` implements the {@link ts.LanguageServiceHost} interface to provide\n * TypeScript's language service with file system access, file snapshots, and compiler configuration.\n *\n * @example\n * ```ts\n * // Initialize with compiler options\n * const host = new LanguageHostService({\n * target: ts.ScriptTarget.ES2020,\n * module: ts.ModuleKind.ESNext,\n * paths: {\n * '@utils/*': ['src/utils/*'],\n * '@components/*': ['src/components/*']\n * }\n * });\n *\n * // Track files for analysis\n * host.touchFile('src/index.ts');\n * host.touchFiles(['src/utils.ts', 'src/types.ts']);\n *\n * // Get file snapshots for language service\n * const snapshot = host.getScriptSnapshot('src/index.ts');\n *\n * // Resolve module imports\n * const resolved = host.resolveModuleName('@utils/helpers', 'src/index.ts');\n *\n * // Check for path aliases\n * const hasAliases = host.aliasRegex !== undefined;\n *\n * // Update configuration\n * host.options = { target: ts.ScriptTarget.ES2022 };\n * ```\n *\n * @see {@link ts.LanguageServiceHost} for the implemented interface specification\n * @see {@link FilesModel} for file snapshot caching implementation\n *\n * @since 2.0.0\n */\n\nexport class LanguageHostService implements ts.LanguageServiceHost {\n /**\n * Reference to TypeScript's system interface for file operations.\n *\n * @remarks\n * Static reference to `ts.sys` that provides abstracted file system operations\n * (read, write, directory traversal) compatible with different environments (Node.js, browsers, etc.).\n * Used for all file I/O operations in this service to maintain platform independence.\n *\n * @see {@link ts.sys}\n *\n * @since 2.0.0\n */\n\n private static readonly sys = ts.sys;\n\n /**\n * Cached regular expression for matching import/export statements with path aliases.\n *\n * @remarks\n * Compiled from `compilerOptions.paths` to efficiently detect imports using path aliases.\n * Regenerated when compiler options change. Undefined if no path aliases are configured.\n *\n * Used by tools that need to identify which import statements use aliases for proper\n * handling during transformation or bundling.\n *\n * @see {@link generateAliasRegex} for pattern generation\n *\n * @since 2.0.0\n */\n\n private alias: RegExp | undefined;\n\n /**\n * Cache for resolved module specifiers.\n *\n * @remarks\n * Stores the absolute resolved file path for each module name so repeated lookups\n * do not trigger TypeScript module resolution again. A value of `undefined` means\n * the module could not be resolved and that result is cached too.\n *\n * This cache is keyed by the raw import specifier, so it is only safe when the\n * same specifier is resolved in a compatible context.\n *\n * @since 2.3.0\n */\n\n private aliasCache = new Map<string, string | undefined>();\n\n /**\n * Cache for TypeScript module resolution results.\n *\n * @remarks\n * TypeScript's internal module resolution cache that stores resolution results to avoid\n * redundant lookups. Improves performance significantly when resolving many imports,\n * especially in large projects with complex path mappings.\n *\n * Recreated when compiler options change (since different options may affect resolution).\n *\n * @see {@link ts.createModuleResolutionCache}\n *\n * @since 2.0.0\n */\n\n private moduleResolutionCache: ModuleResolutionCache;\n\n /**\n * A set containing the file paths of all actively tracked script files.\n *\n * @remarks\n * This set ensures that files are tracked for later operations, such as retrieving script versions\n * or snapshots. Files are added to this set when they are first processed or read by the service.\n *\n * @example\n * ```ts\n * trackFiles.add('/src/main.ts');\n * console.log(trackFiles.has('/src/main.ts')); // true\n * ```\n *\n * @see {@link getScriptFileNames} - Retrieves all tracked files.\n *\n * @since 2.0.0\n */\n\n private readonly trackFiles = new Set<string>();\n\n /**\n * Model for managing file snapshots and version tracking.\n *\n * @remarks\n * Delegates file snapshot management to {@link FilesModel} for centralized\n * caching and change detection. Snapshots are tracked by modification time\n * to detect file changes efficiently.\n *\n * @see {@link FilesModel}\n *\n * @since 2.0.0\n */\n\n private readonly filesCache = inject(FilesModel);\n\n /**\n * Initializes a new {@link LanguageHostService} instance.\n *\n * @param compilerOptions - Optional TypeScript compiler options (defaults to an empty object)\n *\n * @remarks\n * Performs initialization including:\n * 1. Stores compiler options for later use\n * 2. Generates path alias regex from options if configured\n * 3. Creates module resolution cache with appropriate settings\n *\n * The module resolution cache is necessary for efficient resolution of imports in large projects.\n * Path alias regex is generated up-front and cached for performance.\n *\n * @example\n * ```ts\n * // Create host with default options\n * const host = new LanguageHostService();\n *\n * // Create host with specific compiler options\n * const host = new LanguageHostService({\n * target: ts.ScriptTarget.ES2020,\n * module: ts.ModuleKind.ESNext,\n * paths: {\n * '@utils/*': ['src/utils/*']\n * }\n * });\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(private compilerOptions: CompilerOptions = {}) {\n this.alias = LanguageHostService.generateAliasRegex(compilerOptions);\n this.moduleResolutionCache = ts.createModuleResolutionCache(\n process.cwd(),\n s => s,\n this.compilerOptions\n );\n }\n\n /**\n * Regular expression that matches import/export statements using path aliases (if `paths` is configured).\n *\n * @remarks\n * Used mainly for advanced refactoring or rewrite tools that need to identify aliased imports.\n *\n * @since 2.0.0\n */\n\n get aliasRegex(): RegExp | undefined {\n return this.alias;\n }\n\n /**\n * Replaces current compiler options and regenerates derived state (alias regex, module cache).\n *\n * @param options - new compiler configuration\n *\n * @since 2.0.0\n */\n\n set options(options: CompilerOptions) {\n this.compilerOptions = options;\n this.alias = LanguageHostService.generateAliasRegex(options);\n this.moduleResolutionCache = ts.createModuleResolutionCache(\n process.cwd(),\n s => s,\n this.compilerOptions\n );\n }\n\n /**\n * Reloads all tracked file snapshots in the shared {@link FilesModel} cache.\n *\n * @remarks\n * This method iterates over every currently tracked file path and touches each file again so\n * the cache can refresh its stored modification time, version, and content snapshot when needed.\n * It is useful in watch-mode or manual refresh scenarios where the underlying files may have changed\n * and dependent services need to observe the updated state.\n *\n * @since 2.3.0\n */\n\n static reload(): void {\n const filesCache = inject(FilesModel);\n filesCache.getTrackedFilePaths().map(path => {\n filesCache.touchFile(path);\n });\n }\n\n /**\n * Updates file snapshot in the cache and returns the current state.\n *\n * @param path - file path (relative or absolute)\n * @returns current snapshot data (version, mtime, content snapshot)\n *\n * @see {@link FilesModel#touchFile}\n * @since 2.0.0\n */\n\n touchFile(path: string): FileSnapshotInterface {\n this.trackFiles.add(this.filesCache.resolve(path));\n\n return this.filesCache.touchFile(path);\n }\n\n /**\n * Ensures multiple files are tracked and their snapshots are up to date.\n *\n * @param filesPath - list of file paths to touch\n *\n * @since 2.0.0\n */\n\n touchFiles(filesPath: Array<string>): void {\n for (const file of filesPath) {\n this.touchFile(file);\n }\n }\n\n /**\n * Returns current compiler options used by this host.\n *\n * @returns active TypeScript compiler configuration\n *\n * @since 2.0.0\n */\n\n getCompilationSettings(): CompilerOptions {\n return this.compilerOptions;\n }\n\n /**\n * Checks whether a file exists on disk.\n *\n * @param path - absolute path\n * @returns `true` if file exists\n *\n * @since 2.0.0\n */\n\n fileExists(path: string): boolean {\n return LanguageHostService.sys.fileExists(path);\n }\n\n /**\n * Reads file content from disk.\n *\n * @param path - absolute path\n * @param encoding - optional encoding (defaults to UTF-8)\n * @returns file content or `undefined` if read fails\n *\n * @since 2.0.0\n */\n\n readFile(path: string, encoding?: string): string | undefined {\n return LanguageHostService.sys.readFile(path, encoding);\n }\n\n /**\n * Lists files and/or directories matching criteria.\n *\n * @param path - starting directory\n * @param extensions - allowed file extensions\n * @param exclude - glob exclude patterns\n * @param include - glob include patterns\n * @param depth - max recursion depth\n * @returns matching file paths\n *\n * @since 2.0.0\n */\n\n readDirectory(path: string, extensions?: Array<string>, exclude?: Array<string>, include?: Array<string>, depth?: number): Array<string> {\n return LanguageHostService.sys.readDirectory(path, extensions, exclude, include, depth);\n }\n\n /**\n * Returns immediate subdirectories of a given path.\n *\n * @param path - directory to list\n * @returns subdirectory names\n *\n * @since 2.0.0\n */\n\n getDirectories(path: string): Array<string> {\n return LanguageHostService.sys.getDirectories(path);\n }\n\n /**\n * Checks whether a directory exists.\n *\n * @param path - absolute path\n * @returns `true` if directory exists\n *\n * @since 2.0.0\n */\n\n directoryExists(path: string): boolean {\n return LanguageHostService.sys.directoryExists(path);\n }\n\n /**\n * Returns the current working directory used as resolution base.\n *\n * @returns absolute path of cwd\n *\n * @since 2.0.0\n */\n\n getCurrentDirectory(): string {\n return LanguageHostService.sys.getCurrentDirectory();\n }\n\n /**\n * Returns names of all known script files tracked by this host.\n *\n * @returns array of resolved absolute paths\n *\n * @remarks\n * Only includes files previously requested via `getScriptSnapshot` or explicitly `touchFile`/`touchFiles`.\n *\n * @since 2.0.0\n */\n\n getScriptFileNames(): Array<string> {\n return [ ...this.trackFiles ];\n }\n\n /**\n * Returns a path to a default lib `.d.ts` file matching the given target.\n *\n * @param options - compiler options (mainly `target`)\n * @returns absolute path to lib.d.ts / lib.esxxxx.d.ts\n *\n * @since 2.0.0\n */\n\n getDefaultLibFileName(options: CompilerOptions): string {\n return ts.getDefaultLibFilePath(options);\n }\n\n /**\n * Returns string version identifier for the given file.\n *\n * @param path - file path\n * @returns version as string (usually `\"0\"`, `\"1\"`, `\"2\"`, …)\n *\n * @remarks\n * Tracks file in `trackFiles` set as a side effect so it appears in `getScriptFileNames()`.\n *\n * @since 2.0.0\n */\n\n getScriptVersion(path: string): string {\n const state = this.filesCache.getSnapshot(path);\n this.trackFiles.add(this.filesCache.resolve(path));\n\n return state ? state.version.toString() : '0';\n }\n\n /**\n * Checks whether a file is actively tracked (has been requested before).\n *\n * @param path - file path\n * @returns `true` if the file is known to this host\n *\n * @since 2.0.0\n */\n\n hasScriptSnapshot(path: string): boolean {\n return this.trackFiles.has(this.filesCache.resolve(path));\n }\n\n /**\n * Returns an up-to-date script snapshot for the file.\n *\n * @param path - file path\n * @returns `IScriptSnapshot` or `undefined` if a file is missing/empty\n *\n * @remarks\n * Automatically touches the file (reads disk if needed) when no snapshot exists yet.\n *\n * @since 2.0.0\n */\n\n getScriptSnapshot(path: string): IScriptSnapshot | undefined {\n const state = this.filesCache.getSnapshot(path);\n this.trackFiles.add(this.filesCache.resolve(path));\n if (state) return state.contentSnapshot;\n\n return this.touchFile(path).contentSnapshot;\n }\n\n /**\n * Resolves module import using current compiler options and cache.\n *\n * @param moduleName - module specifier\n * @param containingFile - path of a file containing the import\n * @returns resolution result (success and failed lookups)\n *\n * @since 2.0.0\n */\n\n resolveModuleName(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations {\n return ts.resolveModuleName(\n moduleName, containingFile, this.compilerOptions, ts.sys, this.moduleResolutionCache\n );\n }\n\n /**\n * Resolves a module specifier to its absolute file path using the host.\n *\n * @param moduleName - import/export specifier (e.g. \"lodash\", \"./utils\")\n * @param containingFile - path of a file containing the import\n * @returns resolved absolute path or `undefined` if resolution fails\n *\n * @since 2.0.0\n */\n\n resolveModuleFileName(moduleName: string, containingFile: string): string | undefined {\n if (this.aliasCache.has(moduleName)) {\n return this.aliasCache.get(moduleName);\n }\n\n const resolved = this.resolveModuleName(moduleName, containingFile);\n const result = resolved.resolvedModule?.resolvedFileName;\n this.aliasCache.set(moduleName, result);\n\n return result;\n }\n\n /**\n * Rewrites path aliases in declaration content to relative paths.\n *\n * @param content - raw declaration text\n * @param fileName - source file name\n * @param type - file extension to append to resolved paths (e.g., `'.d.ts'`, `'.js'`), defaults to empty string\n * @returns content with aliases replaced by relative paths\n *\n * @remarks\n * Ensures emitted files use portable relative imports instead of aliases.\n * The `type` parameter allows flexible transformation of resolved TypeScript source file extensions\n * (`.ts`, `.tsx`) to any target extension.\n *\n * **Common use cases**:\n * - Pass `'.d.ts'` for declaration file generation\n * - Pass `'.js'` for JavaScript output paths\n * - Pass `''` (default) to preserve the resolved file extension\n *\n * @example\n * ```ts\n * // For regular source files (preserve extension)\n * const code = host.resolveAliases(content, 'src/index.ts');\n *\n * // For declaration files\n * const dts = host.resolveAliases(content, 'src/index.ts', '.d.ts');\n * // '@utils/helpers' -> './utils/helpers.d.ts'\n *\n * // For JavaScript output\n * const js = host.resolveAliases(content, 'src/index.ts', '.js');\n * // '@utils/helpers' -> './utils/helpers.js'\n * ```\n *\n * @since 2.0.0\n */\n\n resolveAliases(content: string, fileName: string, type: string = ''): string {\n if(!this.alias) return content;\n\n return content.replace(this.alias, (match, importPath) => {\n const resolve = this.resolveModuleFileName(importPath, fileName);\n if (!resolve) return match;\n\n const targetFile = resolve.replace(/\\.tsx?$/, type);\n const relativePath = relative(dirname(fileName), targetFile);\n\n return match.replace(importPath, relativePath.startsWith('.') ? relativePath : './' + relativePath);\n });\n }\n\n /**\n * Builds regex that matches import/export declarations using any configured path alias.\n *\n * @param config - compiler options containing `paths`\n * @returns regex or `undefined` if no `paths` configured\n *\n * @since 2.0.0\n */\n\n private static generateAliasRegex(config: CompilerOptions): RegExp | undefined {\n const paths = config.paths;\n if (!paths || Object.keys(paths).length < 1) return;\n\n const aliases = Object.keys(paths)\n .map(alias => alias.replace('/*', '').replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('|');\n\n return new RegExp(\n '(?:^|\\\\s)(?:import|export)\\\\s+' + // import or export keyword\n '(?:type\\\\s+)?' + // optional 'type' keyword\n '(?:[^\\'\"]*from\\\\s+)?' + // optional '... from' (non-greedy)\n `['\"]((${ aliases })[^'\"]*)['\"]` + // capture the quoted path with alias\n ';?', // optional semicolon\n 'gm'\n );\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { BuildOptions, BuildResult, Metafile } from 'esbuild';\n\n/**\n * Imports\n */\n\nimport { cwd } from 'process';\nimport { build } from 'esbuild';\nimport { isBuildResultError, processEsbuildMessages } from '@providers/esbuild-messages.provider';\n\n/**\n * Default ESBuild options used when building or transpiling files.\n *\n * @remarks\n * These defaults bundle, minify, preserve symlinks, and generate external sourcemaps\n * targeting modern browser environments.\n *\n * see BuildOptions\n * @since 2.0.0\n */\n\nexport const defaultBuildOptions: BuildOptions = {\n write: false,\n bundle: true,\n minify: true,\n outdir: `${ cwd() }`,\n format: 'esm',\n target: 'esnext',\n platform: 'browser',\n sourcemap: 'external',\n mangleQuoted: true,\n sourcesContent: true,\n preserveSymlinks: true\n};\n\n/**\n * Builds multiple files using ESBuild with specified options.\n *\n * @param entryPoints - Array of entry points to build\n * @param buildOptions - Optional override build options\n *\n * @returns A promise resolving to an ESBuild BuildResult including metafile information\n *\n * @throws AggregateError - Thrown if esBuild encounters errors during build\n *\n * @remarks\n * This function merges user-provided options with default options and ensures\n * that a metafile is generated. If any errors occur during the build, they are\n * wrapped in a {@link AggregateError} for consistent error reporting.\n *\n * @example\n * ```ts\n * const result = await buildFiles(['src/index.ts'], { minify: false });\n * console.log(result.outputFiles);\n * ```\n *\n * @see esBuildError\n * @see AggregateError\n *\n * @since 2.0.0\n */\n\nexport async function buildFiles(entryPoints: BuildOptions['entryPoints'], buildOptions: BuildOptions = {}): Promise<BuildResult<BuildOptions & Metafile>> {\n try {\n return await build({\n absWorkingDir: cwd(),\n ...defaultBuildOptions,\n ...buildOptions,\n metafile: true,\n entryPoints: entryPoints\n }) as BuildResult<BuildOptions & Metafile>;\n } catch (err) {\n if(isBuildResultError(err)) {\n const aggregateError = new AggregateError([], 'Failed to build entryPoints');\n processEsbuildMessages(err.errors, aggregateError.errors);\n\n throw aggregateError;\n }\n\n throw err;\n }\n}\n\n/**\n * Transpiles TypeScript source code from a string into bundled JavaScript output without writing to disk.\n *\n * @param source - TypeScript source code as a string to transpile\n * @param path - Source file path used for source map generation and error reporting\n * @param buildOptions - Optional esbuild configuration options to override defaults\n *\n * @returns Promise resolving to a {@link BuildResult} containing transpiled code, source maps, and metadata\n *\n * @remarks\n * This function performs in-memory transpilation of TypeScript code using esbuild's stdin feature.\n * It's particularly useful for:\n * - Runtime code evaluation and transformation\n * - Macro expansion and inline directives\n * - Dynamic code generation during builds\n * - Testing and validation without file system writes\n *\n * The function applies the following configuration:\n * - Uses {@link defaultBuildOptions} as the base configuration\n * - Overrides with provided `buildOptions` parameter\n * - Forces `write: false` to keep output in memory\n * - Enables `metafile: true` for dependency analysis\n * - Sets `logLevel: 'silent'` to suppress build output\n * - Generates external source maps for debugging\n *\n * The source code is treated as TypeScript (`loader: 'ts'`) and resolved relative to the current\n * working directory. The `path` parameter is used for source map generation and error messages\n * but does not need to reference an actual file on disk.\n *\n * @example\n * ```ts\n * // Basic transpilation\n * const result = await buildFromString(\n * 'const x: number = 42; export default x;',\n * 'virtual.ts'\n * );\n * console.log(result.outputFiles[0].text); // Transpiled JS\n * ```\n *\n * @example\n * ```ts\n * // With custom build options\n * const result = await buildFromString(\n * 'export const add = (a: number, b: number) => a + b;',\n * 'math.ts',\n * {\n * format: 'cjs',\n * target: 'node16',\n * minify: true\n * }\n * );\n * ```\n *\n * @example\n * ```ts\n * // Used in macro evaluation\n * const code = extractExecutableCode(node, state);\n * const transpiled = await buildFromString(\n * code.data,\n * state.sourceFile.fileName,\n * {\n * bundle: false,\n * format: 'cjs',\n * packages: 'external',\n * platform: 'node'\n * }\n * );\n * // Execute transpiled code in VM\n * ```\n *\n * @see {@link BuildResult} for output structure\n * @see {@link defaultBuildOptions} for base configuration\n * @see {@link BuildOptions} for available configuration options\n * @see {@link analyzeDependencies} for dependency analysis without transpilation\n *\n * @since 2.0.0\n */\n\nexport async function buildFromString(source: string, path: string, buildOptions: BuildOptions = {}): Promise<BuildResult> {\n return await build({\n absWorkingDir: cwd(),\n ...defaultBuildOptions,\n ...buildOptions,\n stdin: {\n loader: 'ts',\n contents: source,\n resolveDir: cwd(),\n sourcefile: path\n },\n write: false,\n metafile: true,\n logLevel: 'silent',\n sourcemap: 'external'\n });\n}\n\n/**\n * Analyzes dependencies of entry point files without writing output.\n *\n * @param entryPoint - Entry point file path(s) for dependency analysis.\n * @param buildOptions - Optional esbuild configuration options to customize the analysis.\n * @returns A promise that resolves to a {@link BuildResult} with metafile metadata containing dependency information.\n *\n * @remarks\n * This function performs a lightweight dependency analysis by:\n *\n * 1. Running esbuild in bundling mode to resolve all imports and dependencies\n * 2. Generating a metafile containing detailed dependency graph information\n * 3. Marking external packages to avoid bundling node_modules\n * 4. Disabling file output to keep the analysis fast and non-destructive\n * 5. Suppressing log output for cleaner execution\n *\n * The resulting metafile contains:\n * - All resolved imports and their relationships\n * - Module dependencies and their sizes\n * - Entry point analysis\n * - Import/export structure information\n *\n * This is useful for:\n * - Understanding project dependency graphs\n * - Identifying circular dependencies\n * - Analyzing import chains\n * - Profiling bundle composition\n * - Validating module resolution\n *\n * @example\n * ```ts\n * // Basic dependency analysis\n * const result = await analyzeDependencies('src/index.ts');\n * console.log('Dependencies:', Object.keys(result.metafile.inputs));\n *\n * // With custom build options\n * const result = await analyzeDependencies('src/main.ts', {\n * external: ['lodash', 'react'],\n * alias: { '@utils': './src/utils' }\n * });\n *\n * // Analyze multiple entry points\n * const result = await analyzeDependencies(\n * ['src/index.ts', 'src/cli.ts']\n * );\n *\n * for (const [input, data] of Object.entries(result.metafile.inputs)) {\n * console.log(`File: ${input}`);\n * console.log(`Imports: ${data.imports.map(i => i.path).join(', ')}`);\n * }\n * ```\n *\n * @see Metafile\n * @see BuildResult\n * @see BuildOptions\n *\n * @since 1.0.0\n */\n\nexport async function analyzeDependencies(entryPoint: BuildOptions['entryPoints'], buildOptions: BuildOptions = {}): Promise<\n BuildResult & { metafile: Metafile }\n> {\n try {\n return await build({\n ...buildOptions,\n outdir: 'tmp',\n write: false, // Prevent writing output files\n bundle: true, // Bundle to analyze imports\n outfile: undefined,\n metafile: true, // Generate a metafile to analyze dependencies\n packages: 'external',\n logLevel: 'silent',\n entryPoints: entryPoint\n });\n } catch(err) {\n if(isBuildResultError(err)) {\n const aggregateError = new AggregateError([], 'Failed to analyze entryPoint');\n processEsbuildMessages(err.errors, aggregateError.errors);\n\n throw aggregateError;\n }\n\n throw err;\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { BuildOptions } from 'esbuild';\n\n/**\n * Imports\n */\n\nimport { xBuildError } from '@errors/xbuild.error';\nimport { collectFilesFromGlob } from '@components/glob.component';\n\n/**\n * Extracts and normalizes entry points from various esbuild entry point formats.\n *\n * @param baseDir - Base directory to resolve glob patterns from\n * @param entryPoints - Entry points in any esbuild-supported format\n * @returns Normalized object mapping output names to input file paths\n *\n * @remarks\n * Supports three esbuild entry point formats:\n *\n * **Array of strings (glob patterns):**\n * - Treats entries as glob patterns to match files\n * - Keys are filenames without extensions\n *\n * **Array of objects with `in` and `out` properties:**\n * - `in`: Input file path\n * - `out`: Output file path\n * - Keys are the `out` values\n *\n * **Record object:**\n * - Keys are output names\n * - Values are input file paths\n * - Returned as-is without modification\n *\n * @throws {@link xBuildError}\n * Thrown when entry points format is unsupported or invalid\n *\n * @example\n * Array of glob patterns:\n * ```ts\n * const entries = extractEntryPoints('./src', ['**\\/*.ts', '!**\\/*.test.ts']);\n * // Returns: { 'index': 'index.ts', 'utils/helper': 'utils/helper.ts' }\n * ```\n *\n * @example\n * Array of in/out objects:\n * ```ts\n * const entries = extractEntryPoints('./src', [\n * { in: 'src/index.ts', out: 'bundle' },\n * { in: 'src/worker.ts', out: 'worker' }\n * ]);\n * // Returns: { 'bundle': 'src/index.ts', 'worker': 'src/worker.ts' }\n * ```\n *\n * @example\n * Record object:\n * ```ts\n * const entries = extractEntryPoints('./src', {\n * main: 'src/index.ts',\n * worker: 'src/worker.ts'\n * });\n * // Returns: { 'main': 'src/index.ts', 'worker': 'src/worker.ts' }\n * ```\n *\n * @see {@link https://esbuild.github.io/api/#entry-points|esbuild Entry Points}\n *\n * @since 2.0.0\n */\n\nexport function extractEntryPoints(baseDir: string, entryPoints: BuildOptions['entryPoints']): Record<string, string> | undefined {\n if (Array.isArray(entryPoints)) {\n let result: Record<string, string> = {};\n\n if (entryPoints.length > 0 && typeof entryPoints[0] === 'object') {\n (entryPoints as { in: string, out: string }[]).forEach(entry => {\n result[entry.out] = entry.in;\n });\n } else if (typeof entryPoints[0] === 'string') {\n result = collectFilesFromGlob(baseDir, <Array<string>> entryPoints);\n }\n\n return result;\n } else if (entryPoints && typeof entryPoints === 'object') {\n return entryPoints;\n } else if (entryPoints === undefined) {\n return undefined;\n }\n\n throw new xBuildError('Unsupported entry points format');\n}\n","/**\n * Type imports (removed at compile time)\n */\n\nimport type { OnEndType, OnLoadType, OnStartType } from './interfaces/lifecycle-provider.interface';\nimport type { PluginBuild, Plugin, OnStartResult, PartialMessage, Message, LogLevel } from 'esbuild';\nimport type { BuildResult, OnResolveResult, OnResolveArgs, OnLoadResult, OnLoadArgs } from 'esbuild';\nimport type { OnResolveType, LifecycleContextInterface } from './interfaces/lifecycle-provider.interface';\n\n/**\n * Imports\n */\n\nimport { readFile } from 'fs/promises';\nimport { resolve } from '@remotex-labs/xmap';\nimport { inject } from '@symlinks/symlinks.module';\nimport { FilesModel } from '@typescript/models/files.model';\n\n/**\n * Manages lifecycle hooks for esbuild plugins with support for build stages and hook execution coordination.\n * Provides a centralized system for registering and executing hooks during different phases of the build process,\n * including resolution, loading, start, end, and success stages.\n *\n * @remarks\n * This provider implements a hook-based architecture that allows multiple handlers to be registered\n * for each build lifecycle stage. Hooks are stored in maps keyed by name, allowing for organized\n * registration and execution of build-time logic.\n *\n * The lifecycle stages are executed in the following order:\n * 1. **onStart**: Executed when the build begins, before any file processing\n * 2. **onResolve**: Executed during module resolution for each import\n * 3. **onLoad**: Executed when loading file contents for each module\n * 4. **onEnd**: Executed when the build completes (success or failure)\n * 5. **onSuccess**: Executed only when the build completes without errors\n *\n * Hook execution strategy:\n * - Start and end hooks aggregate errors and warnings from all handlers\n * - Resolve hooks merge results from multiple handlers\n * - Load hooks apply transformations sequentially (pipeline pattern)\n * - All hooks receive a specialized context object appropriate for their lifecycle stage\n *\n * @example\n * ```ts\n * const provider = new LifecycleProvider('my-plugin', { debug: true });\n *\n * provider.onStart(async (context) => {\n * console.log('Build starting...');\n * return { warnings: [] };\n * });\n *\n * provider.onLoad(async (context) => {\n * // Transform TypeScript files\n * if (context.args.path.endsWith('.ts')) {\n * return { contents: transformCode(context.contents), loader: 'ts' };\n * }\n * });\n *\n * const plugin = provider.create();\n * ```\n *\n * @see {@link FilesModel}\n * @see {@link LoadContextInterface}\n * @see {@link BuildContextInterface}\n * @see {@link ResultContextInterface}\n * @see {@link ResolveContextInterface}\n * @see {@link LifecycleContextInterface}\n *\n * @since 2.0.0\n */\n\nexport class LifecycleProvider {\n /**\n * File model for accessing TypeScript language service snapshots and file content.\n * @since 2.0.0\n */\n\n private filesModel: FilesModel = inject(FilesModel);\n\n /**\n * Registered handlers to execute when the build completes, regardless of success or failure.\n * @since 2.0.0\n */\n\n private readonly endHooks = new Map<string, OnEndType>();\n\n /**\n * Registered handlers to execute when loading file contents during module processing.\n * @since 2.0.0\n */\n\n private readonly loadHooks = new Map<string, OnLoadType>();\n\n /**\n * Registered handlers to execute when the build process begins.\n * @since 2.0.0\n */\n\n private readonly startHooks = new Map<string, OnStartType>();\n\n /**\n * Registered handlers to execute when the build completes successfully without errors.\n * @since 2.0.0\n */\n\n private readonly successHooks = new Map<string, OnEndType>();\n\n /**\n * Registered handlers to execute during module path resolution.\n * @since 2.0.0\n */\n\n private readonly resolveHooks = new Map<string, OnResolveType>();\n\n /**\n * Creates a new lifecycle provider instance with the specified variant name and configuration.\n *\n * @param variantName - The variant name used for identification and included in hook contexts\n * @param argv - Command-line arguments and configuration options passed to hook handlers\n *\n * @remarks\n * The constructor initializes empty hook maps for each lifecycle stage. The `variantName` parameter\n * is used as the default identifier when registering hooks without explicit names and is\n * included in the context passed to all handlers as `variantName`.\n *\n * The `argv` configuration is stored and made available to all hooks through their context objects,\n * allowing build-time behavior to be customized based on command-line flags or configuration.\n *\n * @example\n * ```ts\n * const provider = new LifecycleProvider('production', {\n * watch: false,\n * sourcemap: true,\n * minify: true\n * });\n * ```\n *\n * @since 2.0.0\n */\n\n constructor(protected variantName: string, protected argv: Record<string, unknown>) {\n }\n\n /**\n * Registers a handler to execute when the build process begins.\n *\n * @param handler - Optional callback function to execute at build start\n * @param name - Optional identifier for this hook, defaults to the variant name\n *\n * @remarks\n * Start hooks are executed before any file processing occurs and receive a build context\n * containing the esbuild `PluginBuild` object, variant name, arguments, and stage state.\n * They can return errors and warnings that will be aggregated with results from other start hooks.\n *\n * If no handler is provided, this method does nothing (allowing conditional registration).\n * Multiple start hooks can be registered with different names and will all execute in\n * registration order.\n *\n * Common use cases:\n * - Initialization and setup tasks\n * - Validation of build configuration\n * - Cleaning output directories\n * - Logging build start time\n *\n * @example\n * ```ts\n * provider.onStart(async (context) => {\n * console.log(`${context.variantName} build started at ${context.stage.startTime}`);\n * return { warnings: [], errors: [] };\n * });\n * ```\n *\n * @see {@link executeStartHooks}\n * @see {@link BuildContextInterface}\n *\n * @since 2.0.0\n */\n\n onStart(handler?: OnStartType, name: string = this.variantName): void {\n if (handler) this.startHooks.set(name, handler);\n }\n\n /**\n * Registers a handler to execute when the build completes, regardless of success or failure.\n *\n * @param handler - Optional callback function to execute at build end\n * @param name - Optional identifier for this hook, defaults to the variant name\n *\n * @remarks\n * End hooks are executed after all build operations are complete and receive a result context\n * containing the final build result, calculated duration, variant name, arguments, and stage state.\n * They can return additional errors and warnings to append to the build output.\n *\n * If no handler is provided, this method does nothing. Multiple end hooks execute in registration\n * order, and all results are aggregated.\n *\n * Common use cases:\n * - Cleanup and resource disposal\n * - Logging build completion and duration\n * - Generating build reports or statistics\n * - Post-processing output files\n *\n * @example\n * ```ts\n * provider.onEnd(async (context) => {\n * console.log(`${context.variantName} build completed in ${context.duration}ms`);\n * return { warnings: [], errors: [] };\n * });\n * ```\n *\n * @see {@link onSuccess}\n * @see {@link executeEndHooks}\n * @see {@link ResultContextInterface}\n *\n * @since 2.0.0\n */\n\n onEnd(handler?: OnEndType, name: string = this.variantName): void {\n if (handler) this.endHooks.set(name, handler);\n }\n\n /**\n * Registers a handler to execute when the build completes successfully without errors.\n *\n * @param handler - Optional callback function to execute on successful build\n * @param name - Optional identifier for this hook, defaults to the variant name\n *\n * @remarks\n * Success hooks are a specialized subset of end hooks that only execute when the build\n * completes with zero errors. They receive a result context containing the build result,\n * duration, and stage state, and are guaranteed to run only after successful builds.\n *\n * If no handler is provided, this method does nothing. Success hooks execute after all\n * regular end hooks have completed. Any errors thrown by success hooks are captured and\n * appended to the aggregated end-hook error list.\n *\n * Common use cases:\n * - Deploying build artifacts\n * - Running post-build validation\n * - Updating deployment status\n * - Sending success notifications\n *\n * @example\n * ```ts\n * provider.onSuccess(async (context) => {\n * console.log('Build succeeded! Deploying...');\n * await deploy(context.buildResult.metafile);\n * });\n * ```\n *\n * @see {@link onEnd}\n * @see {@link executeEndHooks}\n * @see {@link ResultContextInterface}\n *\n * @since 2.0.0\n */\n\n onSuccess(handler?: OnEndType, name: string = this.variantName): void {\n if (handler) this.successHooks.set(name, handler);\n }\n\n /**\n * Registers a handler to execute during module path resolution.\n *\n * @param handler - Optional callback function to execute during resolution\n * @param name - Optional identifier for this hook, defaults to the variant name\n *\n * @remarks\n * Resolve hooks are executed when esbuild needs to resolve import paths to file system locations.\n * They receive a resolve context containing the resolution arguments, variant name, and stage state.\n * Hooks can return modified resolution results or redirect imports.\n *\n * If no handler is provided, this method does nothing. Multiple resolve hooks can execute, and\n * their results are merged, with later hooks potentially overriding earlier ones.\n *\n * Common use cases:\n * - Implementing custom module resolution algorithms\n * - Redirecting imports to alternative locations\n * - Handling path aliases and mappings\n * - Resolving virtual modules\n *\n * @example\n * ```ts\n * provider.onResolve(async (context) => {\n * if (context.args.path.startsWith('@/')) {\n * return { path: resolve('src', context.args.path.slice(2)) };\n * }\n * });\n * ```\n *\n * @see {@link executeResolveHooks}\n * @see {@link ResolveContextInterface}\n *\n * @since 2.0.0\n */\n\n onResolve(handler?: OnResolveType, name: string = this.variantName): void {\n if (handler) this.resolveHooks.set(name, handler);\n }\n\n /**\n * Registers a handler to execute when loading file contents during module processing.\n *\n * @param handler - Optional callback function to execute during file loading\n * @param name - Optional identifier for this hook, defaults to the variant name\n *\n * @remarks\n * Load hooks are executed when esbuild loads file contents and receive a load context containing\n * the current contents (potentially transformed by previous hooks), loader type, load arguments,\n * variant name, and stage state. Hooks can transform the contents and change the loader,\n * with transformations applied sequentially in a pipeline pattern.\n *\n * If no handler is provided, this method does nothing. Multiple load hooks execute in\n * registration order, with each hook receiving the transformed output of previous hooks\n * through the context.\n *\n * Common use cases:\n * - Transforming file contents (transpilation, minification)\n * - Injecting code or imports\n * - Applying preprocessors\n * - Changing file loader types\n *\n * @example\n * ```ts\n * provider.onLoad(async (context) => {\n * if (context.args.path.endsWith('.custom')) {\n * return {\n * contents: transformCustomSyntax(context.contents),\n * loader: 'ts'\n * };\n * }\n * });\n * ```\n *\n * @see {@link executeLoadHooks}\n * @see {@link LoadContextInterface}\n *\n * @since 2.0.0\n */\n\n onLoad(handler?: OnLoadType, name: string = this.variantName): void {\n if (handler) this.loadHooks.set(name, handler);\n }\n\n /**\n * Clears all registered hooks from all lifecycle stages.\n *\n * @remarks\n * This method removes all registered handlers for start, end, success, resolve, and load hooks.\n * It's typically used when resetting the provider state or preparing for a new build configuration.\n *\n * After calling this method, the provider has no registered hooks and will not execute any\n * handlers until new ones are registered.\n *\n * @example\n * ```ts\n * provider.onStart(startHandler);\n * provider.onEnd(endHandler);\n *\n * // Remove all hooks\n * provider.clearAll();\n *\n * // Provider now has no registered hooks\n * ```\n *\n * @since 2.0.0\n */\n\n clearAll(): void {\n this.endHooks.clear();\n this.loadHooks.clear();\n this.startHooks.clear();\n this.successHooks.clear();\n this.resolveHooks.clear();\n }\n\n /**\n * Creates an esbuild plugin instance with all registered hooks configured.\n *\n * @returns Configured esbuild plugin object ready for use in build configuration\n *\n * @remarks\n * This method generates an esbuild plugin that wires up all registered hooks to the\n * appropriate esbuild lifecycle events. The plugin setup function:\n * - Initializes a base lifecycle context with variant name, arguments, and start time\n * - Enables metafile generation for build metadata\n * - Registers onStart handler if any start hooks exist\n * - Registers onEnd handler if any end or success hooks exist\n * - Registers onResolve handler with catch-all filter if any resolve hooks exist\n * - Registers onLoad handler with catch-all filter if any load hooks exist\n *\n * Each hook receives a specialized context appropriate for its lifecycle stage:\n * - Start hooks receive `BuildContextInterface` with the build object\n * - End/Success hooks receive `ResultContextInterface` with build result and duration\n * - Resolve hooks receive `ResolveContextInterface` with resolution arguments\n * - Load hooks receive `LoadContextInterface` with contents, loader, and load arguments\n *\n * Handlers are bound at setup time using `Function.prototype.bind` with the shared\n * lifecycle context, avoiding repeated closure allocations on each invocation.\n *\n * @example\n * ```ts\n * const provider = new LifecycleProvider('production', {});\n * provider.onStart(startHandler);\n * provider.onLoad(loadHandler);\n *\n * const plugin = provider.create();\n *\n * await esbuild.build({\n * entryPoints: ['src/index.ts'],\n * plugins: [plugin]\n * });\n * ```\n *\n * @see {@link executeEndHooks}\n * @see {@link executeLoadHooks}\n * @see {@link executeStartHooks}\n * @see {@link executeResolveHooks}\n *\n * @since 2.0.0\n */\n\n create(): Plugin {\n return {\n name: this.variantName,\n setup: (build: PluginBuild): void => {\n const context: LifecycleContextInterface = {\n argv: this.argv,\n options: build.initialOptions,\n variantName: this.variantName,\n stage: { startTime: new Date() }\n };\n\n build.initialOptions.metafile = true;\n\n if (this.startHooks.size > 0)\n build.onStart(this.executeStartHooks.bind(this, context, build));\n\n if (this.endHooks.size > 0 || this.successHooks.size > 0)\n build.onEnd(this.executeEndHooks.bind(this, context));\n\n if (this.resolveHooks.size > 0)\n build.onResolve({ filter: /.*/ }, this.executeResolveHooks.bind(this, context));\n\n if (this.loadHooks.size > 0)\n build.onLoad({ filter: /.*/ }, this.executeLoadHooks.bind(this, context));\n }\n };\n }\n\n /**\n * Appends a caught error to the provided error list as a normalized `PartialMessage`.\n *\n * @param errors - The error array to append to\n * @param id - Logical source identifier for the failing hook phase (e.g. `startHook`, `endHook`)\n * @param err - The thrown value to wrap\n * @param names - The hook name to set as `pluginName`, defaults to the variant name\n *\n * @remarks\n * Captured errors are normalized with:\n * - `id` to identify which lifecycle phase produced the message\n * - `pluginName` to attribute the failure to the registered hook name\n * - `location: null` because these errors are runtime hook failures, not source-mapped diagnostics\n *\n * @since 2.0.0\n */\n\n private pushError(errors: Array<PartialMessage>, id: string, err: unknown, names: string = this.variantName): void {\n errors.push({\n id,\n detail: err,\n location: null,\n pluginName: names\n });\n }\n\n /**\n * Executes all registered start hooks and aggregates their results.\n *\n * @param context - Base lifecycle context containing variant name, arguments, and stage state\n * @param build - The esbuild plugin build object\n * @returns Aggregated result containing all errors and warnings from start hooks\n *\n * @remarks\n * This method resets the start time in the stage object, then executes all registered\n * start hooks in order. Each hook receives a build context that includes the esbuild\n * build object along with the base lifecycle context.\n *\n * Results from all hooks are aggregated:\n * - Errors from all hooks are combined into a single array\n * - Warnings from all hooks are combined into a single array\n *\n * Errors thrown by a hook are caught and appended to the error array rather than\n * propagating, so all hooks always execute regardless of individual failures.\n * Each captured error is attributed to its hook's registered name via `pluginName`\n * on the `PartialMessage`, making the source of the failure identifiable in esbuild output.\n *\n * The context object is passed through to later lifecycle stages for consistent\n * state management across the build.\n *\n * @see {@link onStart}\n * @see {@link BuildContextInterface}\n *\n * @since 2.0.0\n */\n\n private async executeStartHooks(context: LifecycleContextInterface, build: PluginBuild): Promise<OnStartResult> {\n context.stage.startTime = new Date();\n const errors: Array<PartialMessage> = [];\n const warnings: Array<PartialMessage> = [];\n const hookContext = { build, ...context };\n\n for (const [ name, hook ] of this.startHooks.entries()) {\n try {\n const result = await hook(hookContext);\n if (result?.errors) errors.push(...result.errors);\n if (result?.warnings) warnings.push(...result.warnings);\n } catch (err) {\n this.pushError(errors, 'startHook', err, name);\n }\n }\n\n return { errors, warnings };\n }\n\n /**\n * Executes all registered end hooks and success hooks, mutating the provided `buildResult`.\n *\n * @param context - Base lifecycle context containing variant name, arguments, and stage state\n * @param buildResult - The final build result from esbuild (mutated in place)\n *\n * @remarks\n * This method computes build duration and executes hooks in two phases:\n * 1. **End hooks**: Always run. Returned `errors`/`warnings` are appended to `buildResult`.\n * Thrown errors are captured and normalized through {@link pushError} using `id: \"endHook\"`.\n * 2. **Success hooks**: Run only when `buildResult.errors.length === 0` after end hooks.\n * Return values are ignored; thrown errors are captured as `endHook`-scoped messages.\n *\n * Hook handlers share a single result context object that includes `duration`, `buildResult`,\n * and the base lifecycle metadata.\n *\n * @see {@link onEnd}\n * @see {@link onSuccess}\n * @see {@link ResultContextInterface}\n *\n * @since 2.0.0\n */\n\n private async executeEndHooks(context: LifecycleContextInterface, buildResult: BuildResult): Promise<void> {\n const { errors, warnings } = buildResult;\n const duration = Date.now() - context.stage.startTime.getTime();\n const hookContext = { buildResult, duration, ...context };\n\n for (const [ name, hook ] of this.endHooks.entries()) {\n try {\n const result = await hook(hookContext);\n if (result?.errors) errors.push(...result.errors as Array<Message>);\n if (result?.warnings) warnings.push(...result.warnings as Array<Message>);\n } catch (err) {\n this.pushError(errors, 'endHook', err, name);\n }\n }\n\n if (buildResult.errors.length === 0) {\n for (const [ name, hook ] of this.successHooks.entries()) {\n try {\n await hook(hookContext);\n } catch (err) {\n this.pushError(errors, 'endHook', err, name);\n }\n }\n }\n }\n\n /**\n * Executes all registered resolve hooks and merges their results.\n *\n * @param context - Base lifecycle context containing variant name, arguments, and stage state\n * @param args - The resolution arguments from esbuild\n * @returns Merged resolution result from all hooks, always including an `errors` array\n *\n * @remarks\n * This method executes all resolve hooks in registration order, passing each hook a resolve\n * context that includes the resolution arguments along with the base lifecycle context.\n * Results are merged using object spreading, meaning later hooks can override properties\n * set by earlier hooks.\n *\n * The result is initialized as `{ errors: [] }` and used as the merge base. If all hooks\n * return `undefined`/`null`, the method still returns this base result.\n *\n * Unlike start/end/load hooks, resolve hook errors are not caught — esbuild will surface\n * them directly as build errors.\n *\n * @see {@link onResolve}\n * @see {@link ResolveContextInterface}\n *\n * @since 2.0.0\n */\n\n private async executeResolveHooks(context: LifecycleContextInterface, args: OnResolveArgs): Promise<OnResolveResult> {\n let result: OnResolveResult = { errors: [] };\n const hookContext = { args, ...context };\n\n for (const [ name, hook ] of this.resolveHooks.entries()) {\n try {\n const hookResult = await hook(hookContext);\n if (!hookResult) continue;\n result = { ...result, ...hookResult };\n } catch (err) {\n this.pushError(result.errors!, 'endResolve', err, name);\n }\n }\n\n return result;\n }\n\n /**\n * Executes all registered load hooks in sequence, applying content transformations as a pipeline.\n *\n * @param context - Base lifecycle context containing variant name, arguments, and stage state\n * @param args - The load arguments from esbuild containing file path and namespace\n * @returns Load result with final transformed contents and loader type\n *\n * @remarks\n * This method implements a transformation pipeline where:\n * 1. Initial contents are loaded from a TypeScript snapshot or file system\n * 2. Each load hook receives a load context with current contents, loader, and arguments\n * 3. Hooks can transform contents and change the loader\n * 4. Each hook's output becomes the input for the next hook's context\n *\n * Content loading priority:\n * - First attempts to load from TypeScript language service snapshot (if available),\n * accessed via optional chaining on `contentSnapshot`\n * - Falls back to reading the file from disk using `fs/promises`\n *\n * The loader starts as `'default'` and can be changed by any hook in the pipeline.\n * Errors thrown by individual hooks are caught and appended to the error list, attributed to\n * the hook's registered name via `pluginName` on the `PartialMessage`, so the pipeline continues\n * running for subsequent hooks and the failing hook is clearly identifiable in esbuild output.\n * The final contents, loader, errors, and warnings are returned to esbuild for processing.\n *\n * @see {@link onLoad}\n * @see {@link LoadContextInterface}\n * @see {@link FilesModel.getSnapshot}\n *\n * @since 2.0.0\n */\n\n private async executeLoadHooks(context: LifecycleContextInterface, args: OnLoadArgs): Promise<OnLoadResult | null> {\n const errors: Array<PartialMessage> = [];\n const warnings: Array<PartialMessage> = [];\n let loader: OnLoadResult['loader'] = 'default';\n\n const filePath = resolve(args.path);\n const snapshot = this.filesModel.getOrTouchFile(filePath);\n let contents: string | Uint8Array;\n\n try {\n contents = snapshot?.contentSnapshot\n ? snapshot.contentSnapshot.text\n : await readFile(filePath, 'utf8');\n } catch {\n // Todo add this as global way to ignore error & warning\n const logOverride = context.options.logOverride as Record<string, LogLevel> | undefined;\n if(logOverride?.['lifecycle-file-ignored'] !== 'silent') {\n warnings.push({\n id: '',\n text: `${ args.path } ignored`,\n pluginName: 'lifecycle'\n });\n }\n\n return { warnings, errors, loader };\n }\n\n for (const [ name, hook ] of this.loadHooks.entries()) {\n try {\n const result = await hook({ contents, loader, args, ...context });\n if (!result) continue;\n if (result.contents !== undefined) contents = result.contents;\n if (result.loader) loader = result.loader;\n if (result.errors) errors.push(...result.errors);\n if (result.warnings) warnings.push(...result.warnings);\n } catch (err) {\n this.pushError(errors, 'loadHook', err, name);\n }\n }\n\n return { contents, loader, errors, warnings };\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { OnLoadResult } from 'esbuild';\nimport type { VariantService } from '@services/variant.service';\nimport type { CallExpression, VariableStatement, ExpressionStatement } from 'typescript';\nimport type { MacrosStateInterface } from '@directives/interfaces/analyze-directive.interface';\nimport type { LoadContextInterface } from '@providers/interfaces/lifecycle-provider.interface';\nimport type { SubstInterface, StateInterface } from '@directives/interfaces/macros-directive.interface';\nimport ts from 'typescript';\n/**\n * Imports\n */\nimport { createSourceFile } from 'typescript';\nimport { esBuildError } from '@errors/esbuild.error';\nimport { highlightCode } from '@remotex-labs/xmap/highlighter.component';\nimport { astDefineVariable, astDefineCallExpression } from '@directives/define.directive';\nimport { astInlineCallExpression, astInlineVariable } from '@directives/inline.directive';\n\n/**\n * Array of recognized macro function names for conditional compilation and inline evaluation.\n *\n * @remarks\n * Defines the complete set of macro directives supported by xBuild:\n * - `$$ifdef`: Conditional inclusion when definition is truthy\n * - `$$ifndef`: Conditional inclusion when definition is falsy or undefined\n * - `$$inline`: Runtime code evaluation during build time\n *\n * Used for:\n * - Validating macro calls during AST traversal\n * - Determining argument count requirements\n * - Filtering disabled macro references\n *\n * @since 2.0.0\n */\n\nconst MACRO_FUNCTIONS = [ '$$ifdef', '$$ifndef', '$$inline' ];\n\n/**\n * Checks whether a given AST node’s source text contains any supported macro function name.\n *\n * @param node - AST node to inspect\n * @param sourceFile - Optional source file used by TypeScript to compute node text\n *\n * @returns `true` if the node text contains at least one macro identifier; otherwise `false`.\n *\n * @remarks\n * This is a fast, text-based pre-check used to avoid deeper macro parsing work when a node\n * clearly cannot contain macro calls.\n *\n * @since 2.0.0\n */\n\nexport function nodeContainsMacro(node: ts.Node, sourceFile?: ts.SourceFile): boolean {\n return (MACRO_FUNCTIONS as ReadonlyArray<string>).some(m => node.getText(sourceFile).includes(m));\n}\n\n/**\n * Returns the expected argument count for a supported macro function.\n *\n * @param fnName - Macro function name (e.g. `$$ifdef`, `$$ifndef`, `$$inline`)\n *\n * @returns The required number of arguments for the macro.\n *\n * @remarks\n * - `$$inline` expects 1 argument (a thunk/callback)\n * - `$$ifdef` / `$$ifndef` expect 2 arguments (name + callback/value)\n *\n * @since 2.0.0\n */\n\nfunction expectedArgCount(fnName: string): number {\n return fnName === MACRO_FUNCTIONS[2] ? 1 : 2;\n}\n\n/**\n * Processes variable statements containing macro calls and adds replacements to the replacement set.\n *\n * @param node - The variable statement node to process\n * @param replacements - Set of code replacements to populate\n * @param state - The macro transformation state containing definitions and source file\n *\n * @returns A promise that resolves when all variable declarations have been processed\n *\n * @remarks\n * This function handles macro variable declarations of the form:\n * ```ts\n * const $$myFunc = $$ifdef('DEFINITION', callback);\n * export const $$inline = $$inline(() => computeValue());\n * let $$feature = $$ifndef('PRODUCTION', devFeature);\n * ```\n *\n * The processing flow:\n * 1. Iterates through all variable declarations in the statement\n * 2. Validates that the initializer is a macro call expression\n * 3. Checks that the macro function name is recognized\n * 4. Validates argument count (2 for ifdef/ifndef, 1 for inline)\n * 5. Detects export modifiers to preserve in the output\n * 6. Delegates to the appropriate transformer based on macro type\n * 7. Adds successful transformations to the replacement set\n *\n * **Macro type routing**:\n * - `$$inline`: Delegates to {@link astInlineVariable} (async evaluation)\n * - `$$ifdef`/`$$ifndef`: Delegates to {@link astDefineVariable} (conditional inclusion)\n *\n * Replacements track the start and end positions of the original statement\n * for accurate text substitution during the final transformation pass.\n *\n * @example Processing conditional macro\n * ```ts\n * // Source: const $$debug = $$ifdef('DEBUG', () => console.log);\n * // With: { DEBUG: true }\n * await isVariableStatement(node, replacements, state);\n * // replacements contains: {\n * // start: 0,\n * // end: 52,\n * // replacement: 'function $$debug() { return console.log; }'\n * // }\n * ```\n *\n * @example Processing inline macro\n * ```ts\n * // Source: export const API_URL = $$inline(() => process.env.API);\n * await isVariableStatement(node, replacements, state);\n * // replacements contains: {\n * // start: 0,\n * // end: 59,\n * // replacement: 'export const API_URL = undefined;'\n * // }\n * ```\n *\n * @example Invalid macro (skipped)\n * ```ts\n * // Source: const $$bad = $$ifdef('DEV'); // Missing callback argument\n * await isVariableStatement(node, replacements, state);\n * // No replacement added (insufficient arguments)\n * ```\n *\n * @see {@link astProcess} for the calling context\n * @see {@link astInlineVariable} for inline macro transformation\n * @see {@link astDefineVariable} for conditional macro transformation\n *\n * @since 2.0.0\n */\n\nexport async function isVariableStatement(node: VariableStatement, replacements: Set<SubstInterface>, state: StateInterface): Promise<boolean> {\n let replacement: string | false = false;\n\n for (const decl of node.declarationList.declarations) {\n let suffix = '';\n let call: ts.CallExpression | undefined;\n const init = decl.initializer;\n if (!init) continue;\n\n if (ts.isCallExpression(init) && ts.isIdentifier(init.expression)) {\n // Plain: $$macro(...)\n call = init;\n } else if (\n ts.isCallExpression(init) &&\n ts.isCallExpression(init.expression) &&\n ts.isIdentifier(init.expression.expression)\n ) {\n // IIFE: $$macro(...)(...outerArgs)\n call = init.expression;\n const args = init.arguments.map(a => a.getText(state.sourceFile)).join(', ');\n suffix = `(${ args })`;\n } else if (\n ts.isAsExpression(init) &&\n ts.isCallExpression(init.expression) &&\n ts.isIdentifier(init.expression.expression)\n ) {\n call = init.expression;\n }\n\n if (!call) continue;\n\n const fnName = (call.expression as ts.Identifier).text;\n if (!MACRO_FUNCTIONS.includes(fnName)) continue;\n if (call.arguments.length !== expectedArgCount(fnName)) {\n const { line, character } = state.sourceFile.getLineAndCharacterOfPosition(call.getStart(state.sourceFile));\n throw new esBuildError({\n text: `Invalid macro call: ${ fnName } with ${ call.arguments.length } arguments`,\n location: {\n file: state.sourceFile.fileName,\n line: line + 1,\n column: character\n }\n });\n }\n\n const hasExport =\n node.modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;\n\n if (fnName === MACRO_FUNCTIONS[2]) replacement = await astInlineVariable(decl, node, call, hasExport, state);\n else if (suffix) replacement = astDefineCallExpression(call, state, decl, hasExport, suffix);\n else replacement = astDefineVariable(decl, call, hasExport, state);\n\n if (replacement !== false) {\n replacements.add({\n replacement,\n end: node.getEnd(),\n start: node.getStart(state.sourceFile)\n });\n }\n }\n\n return replacement !== false;\n}\n\n/**\n * Processes standalone macro call expressions and adds replacements to the replacement set.\n *\n * @param node - The expression statement containing the macro call\n * @param replacements - Set of code replacements to populate\n * @param state - The macro transformation state containing definitions and source file\n *\n * @returns A promise that resolves when the expression has been processed\n *\n * @remarks\n * This function handles standalone macro calls that appear as expression statements:\n * ```ts\n * $$ifdef('DEBUG', () => console.log('debug'));\n * $$inline(() => initialize());\n * ```\n *\n * The processing flow:\n * 1. Validates that the expression is a macro call with identifier\n * 2. Checks that the macro function name is recognized\n * 3. Validates argument count (2 for ifdef/ifndef, 1 for inline)\n * 4. Delegates to the appropriate transformer based on macro type\n * 5. Adds successful transformations to the replacement set\n *\n * **Macro type routing**:\n * - `$$inline`: Delegates to {@link astInlineCallExpression} (async evaluation)\n * - `$$ifdef`/`$$ifndef`: Delegates to {@link astDefineCallExpression} (conditional inclusion)\n *\n * **Note**: The define call expression handler currently doesn't return a replacement\n * (returns `false` implicitly), so only inline macros result in replacements at this level.\n *\n * @example Processing inline call\n * ```ts\n * // Source: $$inline(() => configureApp());\n * await isCallExpression(node, replacements, state);\n * // replacements contains: {\n * // start: 0,\n * // end: 35,\n * // replacement: 'undefined'\n * // }\n * ```\n *\n * @example Processing conditional call\n * ```ts\n * // Source: $$ifdef('DEBUG', () => enableDebugMode());\n * await isCallExpression(node, replacements, state);\n * // No replacement added (define expressions handle differently)\n * ```\n *\n * @see {@link astProcess} for the calling context\n * @see {@link astInlineCallExpression} for inline macro transformation\n * @see {@link astDefineCallExpression} for conditional macro transformation\n *\n * @since 2.0.0\n */\n\nexport async function isCallExpression(\n node: ExpressionStatement, replacements: Set<SubstInterface>, state: StateInterface\n): Promise<boolean> {\n const callExpr = <CallExpression>node.expression;\n if (!callExpr.expression || !ts.isIdentifier(callExpr.expression)) return false;\n\n const fnName = callExpr.expression.text;\n if (!MACRO_FUNCTIONS.includes(fnName)) return false;\n if (callExpr.arguments.length !== expectedArgCount(fnName)) {\n const { line, character } = state.sourceFile.getLineAndCharacterOfPosition(node.getStart(state.sourceFile));\n throw new esBuildError({\n text: `Invalid macro call: ${ fnName } with ${ callExpr.arguments.length } arguments`,\n location: {\n file: state.sourceFile.fileName,\n line: line + 1,\n column: character\n }\n });\n }\n\n let replacement: string | false = false;\n if (fnName == MACRO_FUNCTIONS[2]) {\n await astInlineCallExpression(callExpr.arguments, state);\n replacement = 'undefined';\n } else replacement = astDefineCallExpression(callExpr, state);\n\n if (replacement !== false) {\n replacements.add({\n replacement,\n end: callExpr.getEnd(),\n start: callExpr.getStart(state.sourceFile)\n });\n }\n\n return replacement !== false;\n}\n\n/**\n * Processes a `CallExpression` AST node that targets one of the supported macro functions and,\n * if possible, registers a text replacement.\n *\n * @param node - The AST node to process (must be a `CallExpression` to be meaningful)\n * @param replacements - Collection of replacements to apply later (sorted and spliced into the source)\n * @param state - Current macro processing state (includes `sourceFile`, `contents`, metadata, etc.)\n *\n * @returns `true` when a macro replacement was added; otherwise `false`.\n *\n * @remarks\n * This handler is used for *nested* macro call sites (i.e. `CallExpression` nodes that are not\n * expression statements or variable statements), for example:\n *\n * ```ts\n * const value = someFn($$inline(() => 123));\n * ```\n *\n * Routing:\n * - `$$inline(...)` → {@link astInlineCallExpression} (async)\n * - `$$ifdef(...)` / `$$ifndef(...)` → {@link astDefineCallExpression}\n *\n * The replacement range is based on the node’s `[start, end]` positions in {@link StateInterface.sourceFile}.\n *\n * @see {@link astInlineCallExpression}\n * @see {@link astDefineCallExpression}\n *\n * @since 2.0.0\n */\n\nasync function macroCallExpression(node: ts.Node, replacements: Set<SubstInterface>, state: StateInterface): Promise<boolean> {\n if (!ts.isCallExpression(node)) return false;\n if (!nodeContainsMacro(node, state.sourceFile)) return false;\n\n const callNode = node as ts.CallExpression;\n if (!ts.isIdentifier(callNode.expression)) return false;\n\n const fnName = callNode.expression.text;\n\n if (fnName === MACRO_FUNCTIONS[2]) {\n // $$inline macro\n const replacement = await astInlineCallExpression(callNode.arguments, state);\n if (replacement === false) return false;\n\n replacements.add({\n start: node.getStart(state.sourceFile),\n end: node.getEnd(),\n replacement\n });\n\n return true;\n }\n\n // $$ifdef / $$ifndef macro\n const replacement = astDefineCallExpression(callNode, state);\n if (replacement === false) return false;\n\n replacements.add({\n start: node.getStart(state.sourceFile),\n end: node.getEnd(),\n replacement\n });\n\n return true;\n}\n\n/**\n * Recursively traverses the AST to find and transform all macro occurrences in the source file.\n *\n * @param state - The macro transformation state containing source file, definitions, and content\n * @param variant - The build variant name for tracking replacements (defaults to 'unknow')\n *\n * @returns A promise resolving to the transformed source code with all macro replacements applied\n *\n * @remarks\n * This is the main transformation function that orchestrates macro processing across the entire\n * source file. It performs a recursive AST traversal to locate and transform different macro patterns:\n *\n * **Macro patterns handled**:\n * 1. **Variable statements**: `const $$x = $$ifdef(...)` or `const x = $$inline(...)`\n * 2. **Expression statements**: Standalone `$$ifdef(...)` or `$$inline(...)` calls\n * 3. **Nested inline calls**: `$$inline(...)` within other expressions (not variable/expression statements)\n * 4. **Disabled macro calls**: Calls to macros marked as disabled in metadata\n * 5. **Disabled macro identifiers**: References to disabled macro names (replaced with `undefined`)\n *\n * @example Complete transformation\n * ```ts\n * // Original source:\n * const $$debug = $$ifdef('DEBUG', () => console.log);\n * const value = $$inline(() => 42);\n * $$debug();\n *\n * // With definitions: { DEBUG: false }\n * const result = await astProcess(state, 'production');\n *\n * // Transformed result:\n * const value = undefined;\n * undefined();\n *\n * // Tracked in state.stage.replacementInfo['production']\n * ```\n *\n * @example Handling disabled macros\n * ```ts\n * // Original source (with DEBUG=false):\n * const $$debug = $$ifdef('DEBUG', log);\n * if ($$debug) $$debug();\n *\n * // After processing:\n * if (undefined) undefined();\n * ```\n *\n * @example No macros (short circuit)\n * ```ts\n * const state = {\n * contents: 'const x = 1;',\n * sourceFile,\n * stage: { defineMetadata: { filesWithMacros: new Set(), disabledMacroNames: new Set() } }\n * };\n * const result = await astProcess(state);\n * // Returns original content unchanged immediately\n * ```\n *\n * @see {@link macroCallExpression} for nested inline calls\n * @see {@link isCallExpression} for expression statement handling\n * @see {@link isVariableStatement} for variable declaration handling\n * @see {@link MacrosStateInterface.replacementInfo} for replacement tracking\n *\n * @since 2.0.0\n */\n\nexport async function astProcess(state: StateInterface, variant: string = 'unknow'): Promise<string> {\n const fnToRemove = state.stage.defineMetadata.disabledMacroNames;\n const hasMacro = state.stage.defineMetadata.filesWithMacros.has(state.sourceFile.fileName);\n if (!hasMacro && fnToRemove.size === 0) return state.contents;\n\n const stack: Array<ts.Node> = [ state.sourceFile ];\n const replacements: Set<SubstInterface> = new Set();\n\n while (stack.length > 0) {\n const node = stack.pop();\n const kind = node?.kind;\n if (!node || !kind) continue;\n if (hasMacro) {\n if (kind === ts.SyntaxKind.VariableStatement) {\n if (await isVariableStatement(node as VariableStatement, replacements, state)) continue;\n }\n\n if (kind === ts.SyntaxKind.ExpressionStatement && nodeContainsMacro(node, state.sourceFile)) {\n if (await isCallExpression(node as ExpressionStatement, replacements, state)) continue;\n }\n\n if (kind === ts.SyntaxKind.CallExpression && nodeContainsMacro(node, state.sourceFile)) {\n if (await macroCallExpression(node as ExpressionStatement, replacements, state)) continue;\n }\n }\n\n if (fnToRemove.size > 0) {\n if (kind === ts.SyntaxKind.CallExpression) {\n const callNode = node as ts.CallExpression;\n if (ts.isIdentifier(callNode.expression) && fnToRemove.has(callNode.expression.text)) {\n replacements.add({\n start: node.getStart(state.sourceFile),\n end: node.getEnd(),\n replacement: 'undefined'\n });\n }\n } else if (kind === ts.SyntaxKind.Identifier) {\n const identifier = node as ts.Identifier;\n if (fnToRemove.has(identifier.text)) {\n const parent = node.parent ?? node;\n\n if (parent && !ts.isImportSpecifier(parent) && !ts.isExportSpecifier(parent)) {\n const parentText = parent?.getText(state.sourceFile);\n\n if (!ts.isCallExpression(parent) || parent.expression !== node) {\n if (!parentText || MACRO_FUNCTIONS.every(key => !parentText.includes(key))) {\n replacements.add({\n start: node.getStart(state.sourceFile),\n end: node.getEnd(),\n replacement: 'undefined'\n });\n }\n }\n }\n }\n }\n }\n\n const children = node.getChildren(state.sourceFile);\n for (let i = children.length - 1; i >= 0; i--) {\n stack.push(children[i]);\n }\n }\n\n if (replacements.size === 0) return state.contents;\n const replacementsArray = Array.from(replacements);\n replacementsArray.sort((a, b) => b.start - a.start);\n\n state.stage.replacementInfo ??= {};\n state.stage.replacementInfo[variant] ??= [];\n const replacementInfo = state.stage.replacementInfo[variant];\n\n for (const { start, end, replacement } of replacementsArray) {\n replacementInfo.push({\n source: highlightCode(state.contents.slice(start, end)),\n replacement: highlightCode(replacement)\n });\n\n state.contents = state.contents.slice(0, start) + replacement + state.contents.slice(end);\n }\n\n return state.contents;\n}\n\n/**\n * Main transformer directive that processes macro transformations for a build variant.\n *\n * @param variant - The build variant service containing configuration and TypeScript services\n * @param context - The load context containing file information, loader type, and build stage\n *\n * @returns A promise resolving to the transformed file result with processed macros, warnings, and errors\n *\n * @remarks\n * This is the entry point for macro transformation during the build process, integrated as\n * an esbuild plugin loader. It orchestrates the complete transformation pipeline:\n *\n * **Transformation pipeline**:\n * 1. **File filtering**: Validates file extension and content length\n * 2. **Source file acquisition**: Retrieves or creates TypeScript source file\n * 3. **State initialization**: Prepares transformation state with definitions and metadata\n * 4. **Macro processing**: Applies AST transformations via {@link astProcess}\n * 5. **Alias resolution**: Resolves TypeScript path aliases for non-bundled builds\n * 6. **Result assembly**: Returns transformed content with diagnostics\n *\n * **Early exits**:\n * - Non-TypeScript/JavaScript files: Returns content unchanged\n * - Empty files: Returns content unchanged\n * - Files without macros: Processes but no transformations occur\n *\n * **Alias resolution**:\n * When not bundling (`variant.config.esbuild.bundle === false`), path aliases are\n * resolved to relative paths with `.js` extensions for proper module resolution.\n *\n * **Source file handling**:\n * If the source file isn't in the language service program, it's touched (loaded)\n * to ensure the TypeScript compiler has current file information.\n *\n * @example Basic transformation flow\n * ```ts\n * const context = {\n * args: { path: 'src/index.ts' },\n * loader: 'ts',\n * stage: { defineMetadata: { ... } },\n * contents: 'const $$debug = $$ifdef(\"DEBUG\", log);'\n * };\n *\n * const result = await transformerDirective(variant, context);\n * // result.contents: transformed code\n * // result.warnings: macro warnings\n * // result.errors: transformation errors\n * ```\n *\n * @example Non-TypeScript file (skipped)\n * ```ts\n * const context = {\n * args: { path: 'styles.css' },\n * loader: 'css',\n * contents: '.class { color: red; }'\n * };\n *\n * const result = await transformerDirective(variant, context);\n * // result.contents === original content (unchanged)\n * ```\n *\n * @example With alias resolution\n * ```ts\n * // Source contains: import { utils } from '@utils/helpers';\n * // Non-bundled build\n * const result = await transformerDirective(variant, context);\n * // Import resolved: import { utils } from './utils/helpers.js';\n * ```\n *\n * @see {@link astProcess} for macro transformation logic\n * @see {@link LanguageHostService.resolveAliases} for alias resolution\n * @see {@link LoadContextInterface} for context structure\n *\n * @since 2.0.0\n */\n\nexport async function transformerDirective(variant: VariantService, context: LoadContextInterface): Promise<OnLoadResult | undefined> {\n const { args, loader, stage, contents, variantName, options, argv } = context;\n if (args.path.includes('node_modules')) return;\n\n if (contents.length < 1) return;\n const ext = args.path.slice(args.path.lastIndexOf('.'));\n if (![ '.js', '.ts' ].includes(ext)) return;\n\n const tsOptions = variant.typescript.languageHostService.getCompilationSettings();\n const sourceFile = createSourceFile(\n args.path, contents.toString(), tsOptions.target ?? ts.ScriptTarget.Latest, true\n );\n\n const state: StateInterface = {\n stage: stage as MacrosStateInterface,\n errors: [],\n contents: contents.toString(),\n warnings: [],\n defines: variant.config.define ?? {},\n sourceFile: sourceFile!,\n context: {\n argv,\n options,\n variantName\n }\n };\n\n let content = await astProcess(state, variant.name);\n if (!variant.config.esbuild.bundle) {\n const alias = variant.typescript.languageHostService.aliasRegex;\n if (alias) {\n content = variant.typescript.languageHostService.resolveAliases(content, args.path, '.js');\n }\n }\n\n return { loader, contents: content, warnings: state.warnings, errors: state.errors };\n}\n","/**\n * Type imports (removed at compile time)\n */\n\nimport type { VariableDeclaration, CallExpression } from 'typescript';\nimport type { SourceFile, Node, ArrowFunction, FunctionExpression } from 'typescript';\nimport type { DefinesType, StateInterface } from './interfaces/macros-directive.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\n\n/**\n * The name of the conditional inclusion directive for checking if a definition is truthy.\n *\n * @remarks\n * Used to identify `$$ifdef` macro calls in the AST. Paired with `$$ifndef` (not-defined check),\n * this directive enables conditional compilation based on build-time definitions.\n *\n * @see {@link isDefinitionMet} for condition evaluation logic\n *\n * @since 2.0.0\n */\n\nconst IFDEF_DIRECTIVE = '$$ifdef';\n\n/**\n * Transforms an AST node into a function declaration or constant assignment.\n *\n * @param fnName - The name for the generated function or constant\n * @param node - The AST node to transform (typically a function or expression)\n * @param sourceFile - The source file containing the node (for text extraction)\n * @param hasExport - Whether to prepend `export` keyword; defaults to `false`\n *\n * @returns A string containing the transformed function declaration or constant assignment\n *\n * @remarks\n * This function handles transformation for conditional macro definitions by converting\n * the macro's callback argument into a named function or constant. The transformation\n * strategy depends on the node type:\n *\n * **For function-like nodes** (arrow functions and function expressions):\n * - Extracts parameters, return type, and body\n * - Generates a proper function declaration\n * - Preserves type annotations if present\n *\n * **For other node types** (expressions, literals, etc.):\n * - Generates a constant assignment\n * - Uses the node's text representation as the value\n *\n * The `hasExport` parameter controls whether the generated declaration is exported,\n * preserving the original export status of the macro variable.\n *\n * @example Arrow function transformation\n * ```ts\n * // Source: const $$debug = $$ifdef('DEBUG', () => console.log);\n * const node = arrowFunctionNode; // () => console.log\n * const result = transformToFunction('$$debug', node, sourceFile, false);\n * // 'function $$debug() { return console.log; }'\n * ```\n *\n * @example Function expression with types\n * ```ts\n * // Source: export const $$getConfig = $$ifdef('DEV', function(): Config { return devConfig; });\n * const result = transformToFunction('$$getConfig', node, sourceFile, true);\n * // 'export function $$getConfig(): Config { return devConfig; }'\n * ```\n *\n * @example Non-function transformation\n * ```ts\n * // Source: const $$apiUrl = $$ifdef('PROD', 'https://api.example.com');\n * const node = stringLiteralNode;\n * const result = transformToFunction('$$apiUrl', node, sourceFile, false);\n * // 'const $$apiUrl = \"https://api.example.com\";'\n * ```\n *\n * @see {@link astDefineVariable} for the calling context\n * @see {@link transformFunctionLikeNode} for function-specific transformation\n *\n * @since 2.0.0\n */\n\nexport function transformToFunction(fnName: string, node: Node, sourceFile: SourceFile, hasExport = false): string {\n const prefix = hasExport ? 'export function ' : 'function ';\n if (ts.isArrowFunction(node) || ts.isFunctionExpression(node))\n return transformFunctionLikeNode(fnName, node, sourceFile, prefix);\n\n // Fallback for other node types\n const constPrefix = hasExport ? 'export const ' : 'const ';\n\n return `${ constPrefix }${ fnName } = ${ node.getText(sourceFile) };`;\n}\n\n/**\n * Transforms arrow functions and function expressions into proper function declarations.\n *\n * @param fnName - The name for the generated function\n * @param node - The arrow function or function expression to transform\n * @param sourceFile - The source file containing the node\n * @param prefix - The declaration prefix (e.g., `'function '` or `'export function '`)\n *\n * @returns A string containing the function declaration, prefixed with `async` if the\n * original node carried the `async` modifier\n *\n * @remarks\n * This function extracts the components of a function-like node and reconstructs them\n * as a proper function declaration:\n * - **Async**: Detected from the node's `modifiers` array via `ts.SyntaxKind.AsyncKeyword`\n * and prepended before the declaration prefix, yielding `async function name()` form\n * - **Parameters**: Extracted with full type annotations\n * - **Return type**: Preserved if present in the original\n * - **Body**: Transformed using {@link getFunctionBody} to handle arrow function syntax\n *\n * The transformation preserves all type information, making it suitable for TypeScript\n * projects that rely on type safety in conditional compilation scenarios.\n *\n * @example Async arrow function\n * ```ts\n * const node = parseExpression('async (x: number): Promise<number> => x * 2');\n * const result = transformFunctionLikeNode('double', node, sourceFile, 'export function ');\n * // 'async export function double(x: number): Promise<number> { return x * 2; }'\n * ```\n *\n * @example Arrow function with return type\n * ```ts\n * const node = parseExpression('(x: number): number => x * 2');\n * const result = transformFunctionLikeNode('double', node, sourceFile, 'export function ');\n * // 'export function double(x: number): number { return x * 2; }'\n * ```\n *\n * @example Function expression without types\n * ```ts\n * const node = parseExpression('function(a, b) { return a + b; }');\n * const result = transformFunctionLikeNode('add', node, sourceFile, 'function ');\n * // 'function add(a, b) { return a + b; }'\n * ```\n *\n * @see {@link getFunctionBody} for body extraction\n * @see {@link transformToFunction} for the calling context\n *\n * @since 2.0.0\n */\n\nfunction transformFunctionLikeNode(\n fnName: string, node: ArrowFunction | FunctionExpression, sourceFile: SourceFile, prefix: string\n): string {\n const isAsync = node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false;\n const asyncPrefix = isAsync ? 'async ' : '';\n const params = node.parameters.map(p => p.getText(sourceFile)).join(', ');\n const returnType = node.type ? `: ${ node.type.getText(sourceFile) }` : '';\n const body = getFunctionBody(node, sourceFile);\n\n return `${ asyncPrefix }${ prefix }${ fnName }(${ params })${ returnType } ${ body }`;\n}\n\n/**\n * Extracts and formats the function body, handling arrow function shorthand syntax.\n *\n * @param node - The arrow function or function expression to extract from\n * @param sourceFile - The source file containing the node\n *\n * @returns The formatted function body as a string\n *\n * @remarks\n * This function handles two body formats:\n * - **Block body**: Returns as-is (already wrapped in `{}`)\n * - **Expression body**: Wraps in block with `return` statement\n *\n * This ensures that all transformed functions have proper block bodies,\n * which is necessary for function declarations (they cannot have expression bodies).\n *\n * @example Arrow function with expression body\n * ```ts\n * const node = parseExpression('() => 42');\n * const body = getFunctionBody(node, sourceFile);\n * // '{ return 42; }'\n * ```\n *\n * @example Arrow function with block body\n * ```ts\n * const node = parseExpression('() => { console.log(\"test\"); return 42; }');\n * const body = getFunctionBody(node, sourceFile);\n * // '{ console.log(\"test\"); return 42; }'\n * ```\n *\n * @example Function expression (always has block body)\n * ```ts\n * const node = parseExpression('function() { return true; }');\n * const body = getFunctionBody(node, sourceFile);\n * // '{ return true; }'\n * ```\n *\n * @see {@link transformFunctionLikeNode} for the calling context\n *\n * @since 2.0.0\n */\n\nfunction getFunctionBody(node: ArrowFunction | FunctionExpression, sourceFile: SourceFile): string {\n const bodyText = node.body.getText(sourceFile);\n if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {\n return `{ return ${ bodyText }; }`;\n }\n\n return bodyText;\n}\n\n/**\n * Transforms an AST node into an Immediately Invoked Function Expression (IIFE).\n *\n * @param node - The AST node to transform\n * @param sourceFile - The source file containing the node\n * @param prefix - The prefix to prepend before the IIFE; defaults to `''`\n * @param suffix - The suffix to append after the IIFE; defaults to `'();'`\n *\n * @returns A string containing the IIFE expression, prefixed with `async` when the\n * original function-like node carried the `async` modifier\n *\n * @remarks\n * This function wraps code in IIFE syntax for immediate execution in expression contexts.\n * The transformation strategy depends on the node type:\n *\n * **For function-like nodes** (arrow functions and function expressions):\n * - Detects the `async` modifier via `ts.SyntaxKind.AsyncKeyword` and prepends `async`\n * before `prefix` when present\n * - Wraps directly: `(function)()` or `(() => value)()`\n * - Preserves the function body as-is\n *\n * **For other node types** (expressions, statements):\n * - Wraps in a synchronous arrow function IIFE with explicit return\n * - Ensures the value is returned for use in expressions\n * - Applies `prefix` before and `suffix` after the IIFE\n *\n * The `prefix` and `suffix` parameters allow customization of the IIFE syntax, useful when\n * the IIFE needs additional context, chaining, or specific wrapping.\n *\n * Used when conditional macros appear in expression contexts where a function\n * declaration is not valid syntax.\n *\n * @example Async arrow function to IIFE\n * ```ts\n * const node = parseExpression('async () => await fetchData()');\n * const result = transformToIIFE(node, sourceFile);\n * // 'async (() => await fetchData())()'\n * ```\n *\n * @example Arrow function to IIFE\n * ```ts\n * const node = parseExpression('() => 42');\n * const result = transformToIIFE(node, sourceFile);\n * // '(() => 42)()'\n * ```\n *\n * @example Function expression to IIFE\n * ```ts\n * const node = parseExpression('function() { return \"hello\"; }');\n * const result = transformToIIFE(node, sourceFile);\n * // '(function() { return \"hello\"; })()'\n * ```\n *\n * @example Expression to IIFE\n * ```ts\n * const node = parseExpression('1 + 1');\n * const result = transformToIIFE(node, sourceFile);\n * // '(() => { return 1 + 1; })()'\n * ```\n *\n * @example Custom prefix and suffix\n * ```ts\n * const node = parseExpression('getValue()');\n * const result = transformToIIFE(node, sourceFile, 'await ', '.catch(handleError)');\n * // 'await (() => { return getValue(); })().catch(handleError)'\n * ```\n *\n * @see {@link astDefineCallExpression} for the calling context\n *\n * @since 2.0.0\n */\n\nexport function transformToIIFE(node: Node, sourceFile: SourceFile, prefix: string = '', suffix: string = '();'): string {\n if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {\n const isAsync = node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false;\n const asyncPrefix = isAsync ? 'async ' : '';\n\n return `${ asyncPrefix }${ prefix }(${ node.getText(sourceFile) })${ suffix }`;\n }\n\n if (prefix) return `${ prefix }${ node.getText(sourceFile) }`;\n\n return `(() => { return ${ node.getText(sourceFile) }; })${ suffix }`;\n}\n\n/**\n * Determines whether a conditional macro definition should be included based on build definitions.\n *\n * @param defineName - The definition name to check (e.g., `'DEBUG'`, `'PRODUCTION'`)\n * @param directiveName - The directive name (`'$$ifdef'` or `'$$ifndef'`)\n * @param defines - The build definitions object mapping names to boolean values\n *\n * @returns `true` if the definition condition is met, `false` otherwise\n *\n * @remarks\n * This function implements the core conditional logic for `$$ifdef` and `$$ifndef` macros:\n *\n * **For `$$ifdef`** (if defined):\n * - Returns `true` when the definition exists and is truthy\n * - Returns `false` when the definition is missing, `false`, `0`, `''`, etc.\n *\n * **For `$$ifndef`** (if not defined):\n * - Returns `true` when the definition is missing or falsy\n * - Returns `false` when the definition exists and is truthy\n *\n * The check uses JavaScript's truthiness rules via `!!defines[defineName]`.\n *\n * @example `$$ifdef` with true definition\n * ```ts\n * const defines = { DEBUG: true, PRODUCTION: false };\n * isDefinitionMet('DEBUG', '$$ifdef', defines); // true\n * isDefinitionMet('PRODUCTION', '$$ifdef', defines); // false\n * ```\n *\n * @example `$$ifndef` with false definition\n * ```ts\n * const defines = { DEBUG: true, PRODUCTION: false };\n * isDefinitionMet('DEBUG', '$$ifndef', defines); // false\n * isDefinitionMet('PRODUCTION', '$$ifndef', defines); // true\n * ```\n *\n * @example Missing definition\n * ```ts\n * const defines = { DEBUG: true };\n * isDefinitionMet('MISSING', '$$ifdef', defines); // false\n * isDefinitionMet('MISSING', '$$ifndef', defines); // true\n * ```\n *\n * @see {@link astDefineVariable} for usage context\n * @see {@link astDefineCallExpression} for usage context\n *\n * @since 2.0.0\n */\n\nfunction isDefinitionMet(defineName: string, directiveName: string, defines: DefinesType): boolean {\n const isDefined = defineName in defines && !!defines[defineName];\n\n return (directiveName === IFDEF_DIRECTIVE) === isDefined;\n}\n\n/**\n * Transforms a conditional macro variable declaration into a function or returns an empty string if excluded.\n *\n * @param decl - The variable declaration node containing the macro\n * @param init - The call expression node representing the macro call\n * @param hasExport - Whether the variable declaration has an `export` modifier\n * @param state - The macro transformation state containing definitions and source file\n *\n * @returns The transformed function/constant string, empty string if excluded, or `false` if invalid\n *\n * @remarks\n * This function processes conditional macro variable declarations of the form:\n * ```ts\n * const $$myFunc = $$ifdef('DEFINITION', callback);\n * const $$myFunc = $$ifndef('DEFINITION', callback);\n * ```\n *\n * The transformation process:\n * 1. Validates that the first argument is a string literal (the definition name)\n * 2. Checks if the definition condition is met using {@link isDefinitionMet}\n * 3. If included: transforms the callback into a function using {@link transformToFunction}\n * 4. If excluded: returns an empty string (macro is stripped from output)\n * 5. If invalid: returns `false` (non-string definition argument)\n *\n * The variable name from the declaration becomes the function name in the output.\n *\n * @example Included macro (DEBUG=true)\n * ```ts\n * // Source: const $$debug = $$ifdef('DEBUG', () => console.log);\n * // With: { DEBUG: true }\n * const result = astDefineVariable(decl, init, false, state);\n * // 'function $$debug() { return console.log; }'\n * ```\n *\n * @example Excluded macro (DEBUG=false)\n * ```ts\n * // Source: const $$debug = $$ifdef('DEBUG', () => console.log);\n * // With: { DEBUG: false }\n * const result = astDefineVariable(decl, init, false, state);\n * // ''\n * ```\n *\n * @example Exported macro\n * ```ts\n * // Source: export const $$feature = $$ifdef('FEATURE_X', () => true);\n * // With: { FEATURE_X: true }\n * const result = astDefineVariable(decl, init, true, state);\n * // 'export function $$feature() { return true; }'\n * ```\n *\n * @example Invalid macro (non-string definition)\n * ```ts\n * // Source: const $$bad = $$ifdef(DEBUG, () => {});\n * const result = astDefineVariable(decl, init, false, state);\n * // false\n * ```\n *\n * @see {@link isDefinitionMet} for condition evaluation\n * @see {@link transformToFunction} for transformation logic\n *\n * @since 2.0.0\n */\n\nexport function astDefineVariable(\n decl: VariableDeclaration, init: CallExpression, hasExport: boolean, state: StateInterface\n): string | false {\n const [ defineArg, callbackArg ] = init.arguments;\n\n if (!ts.isStringLiteral(defineArg)) return false;\n\n const fnName = (init.expression as ts.Identifier).text;\n const defineName = defineArg.text;\n\n if (!isDefinitionMet(defineName, fnName, state.defines)) {\n return 'undefined';\n }\n\n const varName = decl.name.getText(state.sourceFile);\n\n return transformToFunction(varName, callbackArg, state.sourceFile, hasExport);\n}\n\n/**\n * Transforms a conditional macro call expression into a constant assignment with an IIFE or returns empty string if excluded.\n *\n * @param decl - The variable declaration node containing the macro\n * @param init - The call expression node representing the macro call\n * @param hasExport - Whether the variable declaration has an `export` modifier\n * @param state - The macro transformation state containing definitions and source file\n * @param outerSuffix - Optional suffix to append after the IIFE invocation\n *\n * @returns The transformed constant assignment string, empty string if excluded, or `false` if invalid\n *\n * @remarks\n * This function processes conditional macro call expressions that are assigned to constants:\n * ```ts\n * const $$value = $$ifdef('DEBUG', () => \"debug mode\");\n * export const $$config = $$ifndef('PRODUCTION', () => devConfig);\n * ```\n *\n * Unlike {@link astDefineVariable}, which transforms macros into function declarations,\n * this handles macros that should remain as constant assignments with IIFE values.\n *\n * The transformation process:\n * 1. Validates that the first argument is a string literal (the definition name)\n * 2. Extracts the macro function name (`$$ifdef` or `$$ifndef`)\n * 3. Checks if the definition condition is met using {@link isDefinitionMet}\n * 4. If included: transforms the callback into a constant assignment with IIFE using {@link transformToIIFE}\n * 5. If excluded: returns an empty string (macro is stripped from output)\n * 6. If invalid: returns `false` (non-string definition argument)\n *\n * The variable name from the declaration becomes the constant name in the output,\n * and the `hasExport` parameter controls whether the constant is exported.\n *\n * @example Included expression (DEBUG=true)\n * ```ts\n * // Source: const $$debugMsg = $$ifdef('DEBUG', () => \"debugging\");\n * // With: { DEBUG: true }\n * const result = astDefineCallExpression(decl, init, false, state);\n * // 'const $$debugMsg = (() => { return \"debugging\"; })();'\n * ```\n *\n * @example Excluded expression (DEBUG=false)\n * ```ts\n * // Source: const $$debugMsg = $$ifdef('DEBUG', () => \"debugging\");\n * // With: { DEBUG: false }\n * const result = astDefineCallExpression(decl, init, false, state);\n * // ''\n * ```\n *\n * @example Exported constant\n * ```ts\n * // Source: export const $$apiUrl = $$ifndef('PRODUCTION', () => 'http://localhost');\n * // With: { PRODUCTION: false }\n * const result = astDefineCallExpression(decl, init, true, state);\n * // 'export const $$apiUrl = (() => { return \"http://localhost\"; })();'\n * ```\n *\n * @example With custom suffix\n * ```ts\n * // Source: const $$data = $$ifdef('FEATURE', () => fetchData());\n * // With: { FEATURE: true }\n * const result = astDefineCallExpression(decl, init, false, state, '.then(process)');\n * // 'const $$data = (() => { return fetchData(); })().then(process)'\n * ```\n *\n * @see {@link isDefinitionMet} for condition evaluation\n * @see {@link transformToIIFE} for transformation logic\n * @see {@link astDefineVariable} for function declaration handling\n *\n * @since 2.0.0\n */\n\nexport function astDefineCallExpression(\n init: CallExpression, state: StateInterface, decl?: VariableDeclaration, hasExport: boolean = false, outerSuffix?: string\n): string | false {\n const [ defineArg, callbackArg ] = init.arguments;\n\n if (!ts.isStringLiteral(defineArg)) return false;\n\n const defineName = defineArg.text;\n const fnName = (init.expression as ts.Identifier).text;\n if (!isDefinitionMet(defineName, fnName, state.defines)) return '';\n\n let constPrefix = '';\n const varName = decl?.name.getText(state.sourceFile);\n if(varName) {\n constPrefix = hasExport ? `export const ${ varName } = ` : `const ${ varName } = `;\n }\n\n return transformToIIFE(callbackArg, state.sourceFile, constPrefix, outerSuffix);\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { CallExpression, VariableDeclaration, Node } from 'typescript';\nimport type { SourceFile, NodeArray, Expression, VariableStatement } from 'typescript';\nimport type { StateInterface } from '@directives/interfaces/macros-directive.interface';\nimport type { FunctionNodeType, ModuleInterface } from '@directives/interfaces/inline-directive.interface';\nimport type { ExecutableInterface, VariableKeywordType } from '@directives/interfaces/inline-directive.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { createRequire } from 'module';\nimport { InlineError } from '@errors/inline.error';\nimport { inject } from '@symlinks/symlinks.module';\nimport { sandboxExecute } from '@services/vm.service';\nimport { dirname, relative } from '@remotex-labs/xmap';\nimport { FrameworkService } from '@services/framework.service';\nimport { buildFromString } from '@services/transpiler.service';\n\n/**\n * Evaluates inline macro code in a sandboxed environment and returns the result as a string.\n *\n * @param code - The JavaScript code to execute (typically an IIFE wrapping a function or expression)\n * @param state - The current macro transformation state containing source file and error tracking\n * @param node - The AST node representing the inline macro call (used for error location tracking)\n *\n * @returns A promise resolving to the stringified result of the code execution, or `'undefined'` on error\n *\n * @remarks\n * This function performs the following steps:\n * 1. Transpiles and bundles the code using {@link buildFromString} in CommonJS format\n * 2. Creates a sandboxed execution context with access to Node.js globals and the file system\n * 3. Executes the code using {@link sandboxExecute} in an isolated VM context\n * 4. Captures and formats any errors using {@link InlineError} with source mapping\n * 5. Returns `'undefined'` on failure (errors are tracked in `state.errors`)\n *\n * The sandbox has access to:\n * - Global Node.js APIs (`Buffer`, `process`, `console`)\n * - Module system (`require`, `module`, `__dirname`, `__filename`)\n * - Timers (`setTimeout`, `setInterval`, and their clear counterparts)\n * - Standard JavaScript globals from `globalThis`\n *\n * Errors that occur during execution are enhanced with source maps to point back to the\n * original source code location, accounting for line offsets where the inline macro appears.\n *\n * @example Basic inline evaluation\n * ```ts\n * const code = '(() => { return 42; })()';\n * const result = await evaluateCode(code, state, node);\n * // result === 'undefined' (function executed but returns undefined as string)\n * ```\n *\n * @example Inline computation with imports\n * ```ts\n * const code = `(() => {\n * const fs = require('fs');\n * return fs.existsSync('./package.json') ? 'found' : 'missing';\n * })()`;\n *\n * const result = await evaluateCode(code, state, node);\n * // Executes in sandbox with require() support\n * ```\n *\n * @example Error handling with source mapping\n * ```ts\n * const code = '(() => { throw new Error(\"Test error\"); })()';\n * const result = await evaluateCode(code, state, node);\n * // Returns 'undefined'\n * // state.errors contains InlineError with mapped stack trace\n * ```\n *\n * @see {@link sandboxExecute} for VM execution\n * @see {@link InlineError} for error formatting\n * @see {@link createSandboxContext} for context creation\n * @see {@link handleExecutionError} for error processing\n * @see {@link buildFromString} for transpilation and bundling\n *\n * @since 2.0.0\n */\n\nexport async function evaluateCode(code: string, state: StateInterface, node: Node): Promise<string> {\n const [ map, data ] = (await buildFromString(code, state.sourceFile.fileName, {\n bundle: true,\n format: 'cjs',\n platform: 'node',\n packages: 'external'\n })).outputFiles!;\n\n try {\n const module = { exports: {} };\n const require = createRequire(state.sourceFile.fileName);\n const context = createSandboxContext(state.sourceFile.fileName, module, require);\n context.context = state.context;\n\n const result = await sandboxExecute(data.text, context, {\n filename: state.sourceFile.fileName\n });\n\n if (result === null) return 'undefined';\n if (typeof result === 'number' || typeof result === 'boolean') return String(result);\n\n return JSON.stringify(result);\n } catch (err) {\n handleExecutionError(err, state, map.text, node);\n }\n\n return 'undefined';\n}\n\n/**\n * Creates a sandboxed execution context with Node.js globals and module system access.\n *\n * @param fileName - The absolute path to the source file (used for `__filename` and module resolution)\n * @param module - The CommonJS module object with `exports` property\n * @param require - The require function scoped to the source file's location\n *\n * @returns A context object containing all globals available during inline macro execution\n *\n * @remarks\n * The sandbox context provides a controlled environment for executing inline macros with:\n * - **Standard globals**: All properties from `globalThis` (including `RegExp` explicitly)\n * - **Node.js APIs**: `Buffer`, `process`, `console`\n * - **Module system**: `module`, `require`, `__dirname`, `__filename`\n * - **Timers**: `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`\n *\n * The context is designed to mimic a normal Node.js execution environment while maintaining\n * isolation from the build process. The `require` function is scoped to the source file's\n * directory, allowing relative imports to resolve correctly.\n *\n * @example Context structure\n * ```ts\n * const module = { exports: {} };\n * const require = createRequire('/project/src/config.ts');\n *\n * const context = createSandboxContext('/project/src/config.ts', module, require);\n *\n * // context contains:\n * // - process, Buffer, console\n * // - require (scoped to /project/src/)\n * // - __dirname === '/project/src'\n * // - __filename === '/project/src/config.ts'\n * // - setTimeout, setInterval, etc.\n * ```\n *\n * @example Usage in inline evaluation\n * ```ts\n * const context = createSandboxContext(state.sourceFile.fileName, module, require);\n *\n * await sandboxExecute(compiledCode, context, {\n * filename: state.sourceFile.fileName\n * });\n * ```\n *\n * @see {@link sandboxExecute} for execution\n * @see {@link evaluateCode} for usage context\n *\n * @since 2.0.0\n */\n\nexport function createSandboxContext(fileName: string, module: ModuleInterface, require: NodeJS.Require): Record<string, unknown> {\n return {\n ...globalThis,\n Error,\n RegExp,\n process,\n Buffer,\n module,\n require,\n console,\n setTimeout,\n setInterval,\n clearTimeout,\n clearInterval,\n ReferenceError,\n __dirname: dirname(fileName),\n __filename: fileName\n };\n}\n\n/**\n * Handles execution errors during inline macro evaluation and adds them to the transformation state.\n *\n * @param err - The error that occurred during execution\n * @param state - The macro transformation state to store the error in\n * @param mapText - The source map text for mapping error locations back to original source\n * @param node - The AST node representing the inline macro (used for calculating line offset)\n *\n * @remarks\n * This function processes errors that occur during {@link evaluateCode} by:\n * 1. Filtering out non-Error objects (ignores thrown primitives or undefined)\n * 2. Calculating the line offset where the inline macro appears in the source file\n * 3. Creating an {@link InlineError} with source map support and line offset adjustment\n * 4. Adding the formatted error to `state.errors` for build reporting\n *\n * The line offset is crucial for accurate error reporting because inline macros are extracted\n * from their original location, compiled separately, and executed in isolation. The offset\n * ensures that error locations point to the correct line in the original source file.\n *\n * @example Error handling flow\n * ```ts\n * try {\n * await sandboxExecute(code, context);\n * } catch (err) {\n * // err is a runtime error from the executed code\n * handleExecutionError(err, state, sourceMapText, node);\n * // state.errors now contains formatted error with correct source location\n * }\n * ```\n *\n * @example Error output\n * ```ts\n * // Original source at line 42: const x = $$inline(() => undefined.toString());\n * // After handling:\n * // state.errors === [{\n * // text: \"Cannot read property 'toString' of undefined\",\n * // detail: InlineError (with formatted stack pointing to line 42)\n * // }]\n * ```\n *\n * @see {@link evaluateCode} for execution context\n * @see {@link InlineError} for error formatting and source mapping\n *\n * @since 2.0.0\n */\n\nfunction handleExecutionError(err: unknown, state: StateInterface, mapText: string, node: Node): void {\n if (!err || (typeof err !== 'object') || !('stack' in err)) {\n err = new Error(String(err));\n }\n\n const start = node.getStart(state.sourceFile);\n const { line } = state.sourceFile.getLineAndCharacterOfPosition(start);\n\n inject(FrameworkService).setSource(mapText, state.sourceFile.fileName);\n const error = new InlineError(<Error> err, line);\n\n state.errors.push({\n text: error.message,\n detail: error\n });\n}\n\n/**\n * Searches for a function declaration or function variable by name in the source file.\n *\n * @param functionName - The name of the function to find\n * @param sourceFile - The TypeScript source file to search\n *\n * @returns The found function node (declaration, arrow function, or function expression), or `null` if not found\n *\n * @remarks\n * This function recursively traverses the AST to locate functions that match the given name.\n * It handles three types of function definitions:\n * - `function myFunction() {}` (function declarations)\n * - `const myFunction = () => {}` (arrow functions in variable declarations)\n * - `const myFunction = function() {}` (function expressions in variable declarations)\n *\n * The search stops at the first match found. This is used when an inline macro references\n * a function by name rather than providing an inline function expression.\n *\n * @example Finding a function declaration\n * ```ts\n * const sourceFile = ts.createSourceFile(\n * 'test.ts',\n * 'function myFunc() { return 42; }',\n * ts.ScriptTarget.Latest\n * );\n *\n * const func = findFunctionByName('myFunc', sourceFile);\n * // func is a FunctionDeclaration node\n * ```\n *\n * @example Finding an arrow function variable\n * ```ts\n * const sourceFile = ts.createSourceFile(\n * 'test.ts',\n * 'const myFunc = () => 42;',\n * ts.ScriptTarget.Latest\n * );\n *\n * const func = findFunctionByName('myFunc', sourceFile);\n * // func is an ArrowFunction node\n * ```\n *\n * @example Function not found\n * ```ts\n * const func = findFunctionByName('nonExistent', sourceFile);\n * // func === null\n * ```\n *\n * @see {@link extractFromIdentifier} for usage context\n * @see {@link findFunctionInVariableStatement} for variable extraction logic\n *\n * @since 2.0.0\n */\n\nfunction findFunctionByName(functionName: string, sourceFile: SourceFile): FunctionNodeType | null {\n let foundFunction: FunctionNodeType | null = null;\n\n const visit = (node: Node): void => {\n if (foundFunction) return;\n if (ts.isFunctionDeclaration(node) && node.name?.text === functionName) {\n foundFunction = node;\n\n return;\n }\n\n if (ts.isVariableStatement(node)) {\n foundFunction = findFunctionInVariableStatement(node, functionName);\n if (foundFunction) return;\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return foundFunction;\n}\n\n/**\n * Extracts a function initializer from a variable statement if it matches the given name.\n *\n * @param node - The variable statement to search\n * @param functionName - The variable name to match\n *\n * @returns The arrow function or function expression initializer, or `null` if not found\n *\n * @remarks\n * This helper function is used by {@link findFunctionByName} to extract functions defined\n * as variables with arrow functions or function expressions as initializers.\n *\n * Only matches variables declared with simple identifiers (not destructured patterns)\n * that have arrow functions or function expressions as their initializer.\n *\n * @example Matching arrow function\n * ```ts\n * const statement = parseStatement('const myFunc = () => 42;');\n * const func = findFunctionInVariableStatement(statement, 'myFunc');\n * // func is the ArrowFunction node\n * ```\n *\n * @example Matching function expression\n * ```ts\n * const statement = parseStatement('const myFunc = function() { return 42; };');\n * const func = findFunctionInVariableStatement(statement, 'myFunc');\n * // func is the FunctionExpression node\n * ```\n *\n * @example No match\n * ```ts\n * const statement = parseStatement('const myFunc = 42;');\n * const func = findFunctionInVariableStatement(statement, 'myFunc');\n * // func === null (initializer is not a function)\n * ```\n *\n * @see {@link findFunctionByName} for the calling context\n *\n * @since 2.0.0\n */\n\nfunction findFunctionInVariableStatement(node: VariableStatement, functionName: string): FunctionNodeType | null {\n for (const decl of node.declarationList.declarations) {\n if (\n ts.isIdentifier(decl.name) &&\n decl.name.text === functionName &&\n decl.initializer &&\n (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))\n ) {\n return decl.initializer;\n }\n }\n\n return null;\n}\n\n/**\n * Wraps JavaScript code in an Immediately Invoked Function Expression (IIFE).\n *\n * @param code - The code to wrap\n *\n * @returns The code wrapped in IIFE syntax: `module.exports = (code)();`\n *\n * @remarks\n * Converts function definitions or expressions into immediately executed forms for\n * inline evaluation. This is necessary when the inline macro contains a function\n * that should be executed and its return value used, rather than the function itself.\n *\n * The wrapping ensures that:\n * - Function declarations become function expressions (valid in expression context)\n * - Arrow functions and function expressions are immediately invoked\n * - The result of execution is captured rather than the function object\n *\n * @example Wrapping an arrow function\n * ```ts\n * const code = '() => 42';\n * const wrapped = wrapInIIFE(code);\n * // 'module.exports = (() => 42)();'\n * ```\n *\n * @example Wrapping a function expression\n * ```ts\n * const code = 'function() { return \"hello\"; }';\n * const wrapped = wrapInIIFE(code);\n * // 'module.exports = (function() { return \"hello\"; })();'\n * ```\n *\n * @example Wrapping a function declaration\n * ```ts\n * const code = 'function myFunc() { return 123; }';\n * const wrapped = wrapInIIFE(code);\n * // 'module.exports = (function myFunc() { return 123; })();'\n * ```\n *\n * @see {@link evaluateCode} for execution\n * @see {@link extractExecutableCode} for usage context\n *\n * @since 2.0.0\n */\n\nexport function wrapInIIFE(code: string): string {\n return `module.exports = (${ code })();`;\n}\n\n/**\n * Determines the variable keyword (`const`, `let`, or `var`) from TypeScript node flags.\n *\n * @param flags - TypeScript node flags from a variable declaration list\n *\n * @returns The appropriate variable keyword\n *\n * @remarks\n * Extracts the variable declaration keyword by checking TypeScript's node flags:\n * - Returns `'const'` if `NodeFlags.Const` is set\n * - Returns `'let'` if `NodeFlags.Let` is set\n * - Returns `'var'` as the default fallback\n *\n * This is used when transforming inline macro variable declarations to preserve\n * the original variable declaration style in the output.\n *\n * @example\n * ```ts\n * const flags = ts.NodeFlags.Const;\n * const keyword = getVariableKeyword(flags);\n * // 'const'\n * ```\n *\n * @example\n * ```ts\n * const flags = ts.NodeFlags.Let;\n * const keyword = getVariableKeyword(flags);\n * // 'let'\n * ```\n *\n * @example\n * ```ts\n * const flags = ts.NodeFlags.None;\n * const keyword = getVariableKeyword(flags);\n * // 'var'\n * ```\n *\n * @see {@link astInlineVariable} for usage context\n *\n * @since 2.0.0\n */\n\nfunction getVariableKeyword(flags: ts.NodeFlags): VariableKeywordType {\n if (flags & ts.NodeFlags.Const) return 'const';\n if (flags & ts.NodeFlags.Let) return 'let';\n\n return 'var';\n}\n\n/**\n * Extracts executable code from various AST node types for inline macro evaluation.\n *\n * @param node - The AST node to extract code from\n * @param state - The macro transformation state for error reporting and source file access\n *\n * @returns An object containing the extracted code and the source node, or `null` if extraction fails\n *\n * @remarks\n * This function handles multiple node types:\n * - **Identifiers**: Looks up function declarations by name and wraps them in IIFEs\n * - **Arrow functions**: Wraps them in IIFEs for immediate execution\n * - **Function expressions**: Wraps them in IIFEs for immediate execution\n * - **Other expressions**: Returns the code as-is for direct evaluation\n *\n * When a function is referenced by name (identifier), the function must be defined\n * in the same source file. If not found, a warning is added to the transformation state.\n *\n * The returned `ExecutableInterface` contains both the formatted executable code and\n * the original AST node for error location tracking during execution.\n *\n * @example Extracting from an identifier reference\n * ```ts\n * // Source contains: function myFunc() { return 42; }\n * const node = ts.factory.createIdentifier('myFunc');\n * const result = extractExecutableCode(node, state);\n * // result.data === '(function myFunc() { return 42; })()'\n * ```\n *\n * @example Extracting from an arrow function\n * ```ts\n * const node = parseExpression('() => 42');\n * const result = extractExecutableCode(node, state);\n * // result.data === '(() => 42)()'\n * ```\n *\n * @example Extracting from an expression\n * ```ts\n * const node = parseExpression('1 + 2');\n * const result = extractExecutableCode(node, state);\n * // result.data === '1 + 2'\n * ```\n *\n * @example Function not found (generates warning)\n * ```ts\n * const node = ts.factory.createIdentifier('nonExistent');\n * const result = extractExecutableCode(node, state);\n * // result.data === ''\n * // state.warnings contains: \"Function $$inline(nonExistent); not found in ...\"\n * ```\n *\n * @see {@link evaluateCode} for execution\n * @see {@link wrapInIIFE} for IIFE wrapping\n * @see {@link extractFromIdentifier} for identifier handling\n *\n * @since 2.0.0\n */\n\nexport function extractExecutableCode(node: Node, state: StateInterface): ExecutableInterface | null {\n if (!node) return null;\n\n // Handle identifier (function name reference)\n if (ts.isIdentifier(node)) {\n return extractFromIdentifier(node, state);\n }\n\n // Handle arrow functions and function expressions\n if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {\n return {\n node,\n data: wrapInIIFE(node.getText(state.sourceFile))\n };\n }\n\n // Handle other expressions\n return {\n node,\n data: node.getText(state.sourceFile)\n };\n}\n\n/**\n * Extracts executable code from a function identifier reference.\n *\n * @param node - The identifier node referencing a function name\n * @param state - The macro transformation state for function lookup and warnings\n *\n * @returns An object containing the wrapped function code and source node, or empty code with warning if not found\n *\n * @remarks\n * This function handles inline macros that reference functions by name rather than\n * defining them inline. It:\n * 1. Searches for the function declaration in the source file using {@link findFunctionByName}\n * 2. If found, wraps the function in an IIFE for immediate execution\n * 3. If not found, adds a warning to the transformation state and returns empty code\n *\n * The warning includes the relative path to help developers locate the issue quickly.\n *\n * @example Successful extraction\n * ```ts\n * // Source contains: function myFunc() { return 42; }\n * const identifier = ts.factory.createIdentifier('myFunc');\n * const result = extractFromIdentifier(identifier, state);\n * // result.data === '(function myFunc() { return 42; })()'\n * // result.node === FunctionDeclaration node\n * ```\n *\n * @example Function not found\n * ```ts\n * const identifier = ts.factory.createIdentifier('missing');\n * const result = extractFromIdentifier(identifier, state);\n * // result.data === ''\n * // result.node === identifier\n * // state.warnings contains a warning message\n * ```\n *\n * @see {@link findFunctionByName} for function lookup\n * @see {@link extractExecutableCode} for the calling context\n * @see {@link addFunctionNotFoundWarning} for warning generation\n *\n * @since 2.0.0\n */\n\nfunction extractFromIdentifier(node: ts.Identifier, state: StateInterface): ExecutableInterface {\n const functionDeclaration = findFunctionByName(node.text, state.sourceFile);\n\n if (!functionDeclaration) {\n addFunctionNotFoundWarning(node.text, state, node);\n\n return { data: '', node };\n }\n\n return {\n node: functionDeclaration,\n data: wrapInIIFE(functionDeclaration.getText(state.sourceFile))\n };\n}\n\n/**\n * Adds a warning to the transformation state when a referenced function is not found.\n *\n * @param functionName - The name of the function that was not found\n * @param state - The macro transformation state to add the warning to\n * @param node - The AST node representing the function reference (used for location tracking)\n *\n * @remarks\n * Generates a user-friendly warning message with the relative file path and precise location\n * information to help developers quickly identify and fix missing function references in inline macros.\n *\n * The warning includes:\n * - A descriptive message with the function name and file path\n * - Precise location information (line, column, file path)\n * - The source line text containing the reference\n *\n * The warning message format is:\n * ```\n * Function $$inline(functionName); not found in path/to/file.ts\n * ```\n *\n * @example\n * ```ts\n * // In file: /project/src/config.ts at line 42, column 15\n * // Code contains: const x = $$inline(missingFunc);\n *\n * const identifier = ts.factory.createIdentifier('missingFunc');\n * addFunctionNotFoundWarning('missingFunc', state, identifier);\n * // state.warnings === [{\n * // text: \"Function $$inline(missingFunc); not found in src/config.ts\",\n * // location: {\n * // line: 43, // 1-indexed\n * // column: 15,\n * // file: '/project/src/config.ts',\n * // lineText: 'asd'\n * // }\n * // }]\n * ```\n *\n * @see {@link extractFromIdentifier} for the calling context\n *\n * @since 2.0.0\n */\n\nfunction addFunctionNotFoundWarning(functionName: string, state: StateInterface, node: Node): void {\n const start = node.getStart(state.sourceFile);\n const { line, character } = state.sourceFile.getLineAndCharacterOfPosition(start);\n const relativePath = relative('.', state.sourceFile.fileName);\n\n state.warnings.push({\n text: `Function $$inline(${ functionName }); not found in ${ relativePath }`,\n location: {\n line: line + 1,\n column: character,\n file: state.sourceFile.fileName,\n lineText: 'asd'\n }\n });\n}\n\n/**\n * Transforms an inline macro variable declaration into executable code with the evaluated result.\n *\n * @param decl - The variable declaration node containing the inline macro\n * @param node - The complete variable statement (needed for flags and export status)\n * @param init - The call expression node representing the `$$inline()` macro call\n * @param hasExport - Whether the variable declaration has an `export` modifier\n * @param state - The macro transformation state for code extraction and evaluation\n *\n * @returns A promise resolving to the transformed variable declaration string, or `false` if transformation fails\n *\n * @remarks\n * This function processes inline macro variable declarations of the form:\n * ```ts\n * const myVar = $$inline(...);\n * export const myVar = $$inline(...);\n * ```\n *\n * The transformation process:\n * 1. Extracts the executable code from the macro argument using {@link extractExecutableCode}\n * 2. Evaluates the code in a sandboxed environment using {@link evaluateCode}\n * 3. Replaces the macro call with the evaluated result\n * 4. Preserves the variable keyword (`const`, `let`, or `var`) and export status\n *\n * @example Basic inline variable\n * ```ts\n * // Input AST for: a const result = $$inline(() => 1 + 1);\n * const transformed = await astInlineVariable(decl, node, init, false, state);\n * // transformed === 'const result = undefined;'\n * // (actual evaluation would return the computed value)\n * ```\n *\n * @example Exported inline variable\n * ```ts\n * // Input AST for: export const API_URL = $$inline(() => process.env.API_URL);\n * const transformed = await astInlineVariable(decl, node, init, true, state);\n * // transformed === 'export const API_URL = undefined;'\n * ```\n *\n * @example With function reference\n * ```ts\n * // Input AST for: let config = $$inline(getConfig);\n * const transformed = await astInlineVariable(decl, node, init, false, state);\n * // transformed === 'let config = undefined;'\n * ```\n *\n * @see {@link evaluateCode} for code evaluation\n * @see {@link extractExecutableCode} for code extraction\n * @see {@link getVariableKeyword} for variable keyword detection\n *\n * @since 2.0.0\n */\n\nexport async function astInlineVariable(\n decl: VariableDeclaration, node: VariableStatement, init: CallExpression, hasExport: boolean, state: StateInterface\n): Promise<string | false> {\n const arg = init.arguments[0];\n const code = extractExecutableCode(arg, state);\n if (!code) return false;\n\n const result = await evaluateCode(code.data, state, code.node);\n const varKeyword = getVariableKeyword(node.declarationList.flags);\n const exportPrefix = hasExport ? 'export ' : '';\n const varName = decl.name.getText(state.sourceFile);\n\n return `${ exportPrefix }${ varKeyword } ${ varName } = ${ result };`;\n}\n\n/**\n * Transforms an inline macro call expression into its evaluated result.\n *\n * @param args - The arguments passed to the `$$inline()` call\n * @param state - The macro transformation state for code extraction and evaluation\n *\n * @returns A promise resolving to the evaluated result string, or `false` if transformation fails\n *\n * @remarks\n * This function processes standalone inline macro calls that appear in expression contexts:\n * ```ts\n * console.log($$inline(() => \"hello\"));\n * const x = someFunction($$inline(getValue));\n * ```\n *\n * Unlike {@link astInlineVariable}, this handles inline macros that are not part of\n * variable declarations but are used directly as expressions.\n *\n * The transformation process:\n * 1. Extracts the executable code from the first argument using {@link extractExecutableCode}\n * 2. Evaluates the code using {@link evaluateCode}\n * 3. Returns the stringified result to replace the macro call\n *\n * @example Inline function call\n * ```ts\n * // Input AST for: console.log($$inline(() => 42));\n * const transformed = await astInlineCallExpression(args, state);\n * // transformed === 'undefined'\n * // Original: console.log($$inline(() => 42));\n * // Result: console.log(undefined);\n * ```\n *\n * @example Inline with function reference\n * ```ts\n * // Input AST for: const result = compute($$inline(getValue));\n * const transformed = await astInlineCallExpression(args, state);\n * // transformed === 'undefined'\n * ```\n *\n * @example Extraction failure\n * ```ts\n * const transformed = await astInlineCallExpression([], state);\n * // transformed === false\n * ```\n *\n * @see {@link evaluateCode} for code evaluation\n * @see {@link extractExecutableCode} for code extraction\n * @see {@link astInlineVariable} for variable declaration handling\n *\n * @since 2.0.0\n */\n\nexport async function astInlineCallExpression(args: NodeArray<Expression>, state: StateInterface): Promise<string | false> {\n const arg = args[0];\n const code = extractExecutableCode(arg, state);\n\n if (!code) return false;\n\n return evaluateCode(code.data, state, code.node);\n}\n","/**\n * Imports\n */\n\nimport { xBuildBaseError } from '@errors/base.error';\nimport { getErrorMetadata, formatStack } from '@providers/stack.provider';\n\n/**\n * Custom error class for inline errors with enhanced formatting and source code context.\n *\n * @remarks\n * The `InlineError` class extends {@link xBuildBaseError} to provide specialized handling for\n * JavaScript/TypeScript errors with optional line offset adjustment. It automatically:\n * - Extracts and formats error metadata using {@link getErrorMetadata}\n * - Applies syntax highlighting to code context\n * - Generates enhanced stack traces with file locations\n * - Supports line offset adjustment for accurate error positioning\n * - Stores structured metadata in {@link ResolveMetadataInterface} format\n *\n * This class is designed to transform standard Error objects into human-readable, visually enhanced\n * output suitable for terminal display, making it easier to identify and fix errors in source code.\n *\n * **Key features:**\n * - Automatic error metadata extraction and formatting\n * - Contextual code display with configurable line offset\n * - Syntax highlighting with color-coded error indicators\n * - Enhanced stack trace generation\n * - Structured error metadata for programmatic access\n *\n * @example\n * ```ts\n * import { InlineError } from './inline.error';\n *\n * try {\n * // Some code that might throw an error\n * throw new Error('Unexpected token');\n * } catch (err) {\n * throw new InlineError(err as Error);\n * }\n * ```\n *\n * @example\n * ```ts\n * // Error with line offset adjustment\n * try {\n * // Code execution\n * } catch (err) {\n * // Adjust error line number by 2 lines\n * const error = new InlineError(err as Error, 2);\n * console.error(error); // Displays formatted error with adjusted line context\n * }\n * ```\n *\n * @see {@link ResolveMetadataInterface} for metadata structure\n * @see {@link xBuildBaseError} for base error functionality\n * @see {@link getErrorMetadata} for metadata extraction logic\n * @see {@link formatStack} for stack formatting logic\n *\n * @since 2.0.0\n */\n\nexport class InlineError extends xBuildBaseError {\n /**\n * Creates a new inline error with formatted output and metadata.\n *\n * @param error - The base Error object containing error details\n * @param lineOffset - Optional line number offset for adjusting error position (default: 0)\n *\n * @remarks\n * The constructor processes the error to:\n * 1. Extract the error message for the base Error\n * 2. Generate error metadata using {@link getErrorMetadata} with optional line offset\n * 3. Format the stack trace using {@link formatStack}\n * 4. Store structured metadata in {@link errorMetadata}\n *\n * The `lineOffset` parameter allows you to adjust the reported line number in the error output.\n * This is useful when the actual error location differs from the reported location due to\n * transpilation, code generation, or other transformations:\n * - Positive values shift the line number down\n * - Negative values shift the line number up\n * - Zero (default) uses the original line number\n *\n * The error name is always set to `'InlineError'` and the stack is replaced\n * with a custom formatted version that includes:\n * - Error name and message with color coding\n * - Highlighted code snippet showing the error location\n * - Enhanced stack trace with file path and position\n *\n * @example\n * ```ts\n * const error = new Error('Syntax error in file');\n * const inlineError = new InlineError(error);\n * // inlineError.stack contains formatted output with code context\n * // inlineError.metadata contains structured location data\n * ```\n *\n * @example\n * ```ts\n * // Adjust error line by -3 to account for wrapper code\n * const error = new Error('Type mismatch');\n * const inlineError = new InlineError(error, -3);\n * // Error will be displayed 3 lines higher than originally reported\n * ```\n *\n * @see {@link getErrorMetadata} for metadata extraction and formatting\n * @see {@link formatStack} for stack trace formatting\n *\n * @since 2.0.0\n */\n\n constructor(error: Error, lineOffset: number = 0) {\n super(error.message, 'InlineError');\n\n this.errorMetadata = getErrorMetadata(error, { lineOffset });\n this.stack = formatStack(this.errorMetadata, this.name, this.message);\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { Context, ScriptOptions } from 'vm';\n\n/**\n * Imports\n */\n\nimport { Script, createContext } from 'vm';\n\n/**\n * Executes arbitrary code inside a Node.js VM sandbox.\n *\n * @param code - The JavaScript source code to execute\n * @param sandbox - Optional {@link Context} object to inject into the VM environment\n * @param options - Optional {@link ScriptOptions} used when compiling the script\n *\n * @returns A promise resolving to the result of the executed code\n *\n * @throws Error - If the provided code fails to compile or runtime execution throws\n *\n * @remarks\n * This function uses Node.js's {@link Script} and {@link createContext} APIs to safely run code in\n * an isolated environment. Execution is configured with `breakOnSigint` enabled and `displayErrors` disabled.\n *\n * @example\n * ```ts\n * const result = await sandboxExecute(\"2 + 2\");\n * console.log(result); // 4\n * ```\n *\n * @example\n * ```ts\n * const result = await sandboxExecute(\"user.name\", { user: { name: \"Alice\" } });\n * console.log(result); // \"Alice\"\n * ```\n *\n * @see Context\n * @see ScriptOptions\n *\n * @since 1.0.0\n */\n\nexport async function sandboxExecute(code: string, sandbox: Context = {}, options: ScriptOptions = {}): Promise<unknown> {\n const script = new Script(code, options);\n const context = createContext(sandbox);\n\n return await script.runInContext(context, { breakOnSigint: true, displayErrors: false });\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { VariantService } from '@services/variant.service';\nimport type { PartialMessage, Location, OnLoadResult } from 'esbuild';\nimport type { BuildContextInterface } from '@providers/interfaces/lifecycle-provider.interface';\nimport type { MacrosMetadataInterface } from '@directives/interfaces/analyze-directive.interface';\n\n/**\n * Imports\n */\n\nimport { inject } from '@symlinks/symlinks.module';\nimport { FilesModel } from '@typescript/models/files.model';\n\n/**\n * Constants\n */\n\nconst MACRO_PREFIX = '$$';\nconst IFDEF_REGEX = /(?:(?:export\\s+)?(?:const|let|var)\\s+([\\w$]+)\\s*=\\s*)?\\$\\$(ifdef|ifndef|inline)\\s*\\(\\s*(?:['\"]([^'\"]+)['\"])?/g;\n\n/**\n * Calculates the line and column position of a macro name within source text.\n *\n * @param text - The complete source file content\n * @param name - The macro name to locate\n * @param file - The file path for location reporting\n * @param index - The starting index in the text where the match was found\n * @returns A partial {@link Location} object containing file, line, and column information\n *\n * @since 2.0.0\n */\n\nexport function getLineAndColumn(text: string, name: string, file: string, index: number): Partial<Location> {\n let line = 1;\n for (let i = 0; i < index; i++) if (text[i] === '\\n') line++;\n const startLinePosition = text.lastIndexOf('\\n', index - 1) + 1;\n\n return {\n file,\n line,\n column: text.indexOf(name, startLinePosition) - startLinePosition\n };\n}\n\n/**\n * Determines whether a given position in source code is within a comment.\n *\n * @param content - The complete source file content\n * @param index - The position to check\n * @returns `true` if the position is within a single-line (`//`), multi-line (`\\/* *\\/`), or JSDoc comment, otherwise `false`\n *\n * @remarks\n * Scans backward from the given index to the start of the line, skipping whitespace.\n * Checks if the first non-whitespace characters form a comment start sequence.\n * This is used to avoid processing macros that appear in comments.\n *\n * @example Single-line comment detection\n * ```ts\n * const code = '// const $$debug = $$ifdef(\"DEBUG\");\\nconst $$prod = $$ifdef(\"PROD\");';\n *\n * const debugIndex = code.indexOf('$$debug');\n * console.log(isCommentLine(code, debugIndex)); // true\n *\n * const prodIndex = code.indexOf('$$prod');\n * console.log(isCommentLine(code, prodIndex)); // false\n * ```\n *\n * @example Multi-line comment detection\n * ```ts\n * const code = `/*\n * * const $$feature = $$ifdef(\"FEATURE\");\n * *\\/\n * const $$active = $$ifdef(\"ACTIVE\");`;\n *\n * const featureIndex = code.indexOf('$$feature');\n * console.log(isCommentLine(code, featureIndex)); // true\n *\n * const activeIndex = code.indexOf('$$active');\n * console.log(isCommentLine(code, activeIndex)); // false\n * ```\n *\n * @example Indented code\n * ```ts\n * const code = ' // Commented macro\\n const $$real = $$ifdef(\"REAL\");';\n * const index = code.indexOf('// Commented');\n * console.log(isCommentLine(code, index)); // true\n * ```\n *\n * @since 2.0.0\n */\n\nexport function isCommentLine(content: string, index: number): boolean {\n let lineStart = content.lastIndexOf('\\n', index - 1) + 1;\n\n while (lineStart < index && (content[lineStart] === ' ' || content[lineStart] === '\\t')) {\n lineStart++;\n }\n\n if (lineStart >= index) return false;\n\n const char1 = content[lineStart];\n const char2 = content[lineStart + 1];\n\n return (char1 === '/' && (char2 === '/' || char2 === '*')) || char1 === '*';\n}\n\n/**\n * Analyzes all project files for macro usage and generates metadata about disabled macros.\n *\n * @param variant - The current build variant containing define configurations\n * @param context - The build context to store metadata and configuration\n * @returns A promise resolving to an {@link AnalyzerMessageInterface} containing any warnings\n *\n * @remarks\n * Scans all entry point dependencies for `$$ifdef` and `$$ifndef` macro declarations.\n * Determines which macros should be disabled based on the variant's definition configuration.\n * Generates warnings for macros that don't follow the `$$` naming convention.\n * Stores results in `context.stage.defineMetadata` for use during the build process.\n *\n * @example Basic macro analysis with definitions\n * ```ts\n * const variant = {\n * config: {\n * define: {\n * DEBUG: true,\n * PRODUCTION: false\n * }\n * }\n * };\n *\n * const context = {\n * build: {\n * initialOptions: {\n * entryPoints: ['src/index.ts']\n * }\n * },\n * stage: {}\n * };\n *\n * const result = await analyzeMacroMetadata(variant, context);\n *\n * // context.stage.defineMetadata now contains:\n * // {\n * // disabledMacroNames: Set(['$$noProd']), // from $$ifndef('PRODUCTION')\n * // filesWithMacros: Set(['src/index.ts', 'src/config.ts'])\n * // }\n *\n * console.log(result.warnings); // Array of warnings for improperly named macros\n * ```\n *\n * @example Handling ifdef vs. ifndef\n * ```ts\n * // the Source file contains:\n * // const $$hasDebug = $$ifdef('DEBUG'); // enabled when DEBUG=true\n * // const $$noDebug = $$ifndef('DEBUG'); // enabled when DEBUG=false\n *\n * const variant = {\n * config: {\n * define: { DEBUG: true }\n * }\n * };\n *\n * await analyzeMacroMetadata(variant, context);\n * // disabledMacroNames will contain: Set(['$$noDebug'])\n * ```\n *\n * @example Warning generation for invalid macro names\n * ```ts\n * // Source contains: const myMacro = $$ifdef('FEATURE');\n * // (missing $$ prefix)\n *\n * const result = await analyzeMacroMetadata(variant, context);\n *\n * console.log(result.warnings);\n * // [{\n * // text: \"Macro function 'myMacro' not start with '$$' prefix to avoid conflicts\",\n * // location: { file: 'src/feature.ts', line: 10, column: 6 }\n * // }]\n * ```\n *\n * @see {@link MacrosMetadataInterface}\n *\n * @since 2.0.0\n */\n\nexport async function analyzeMacroMetadata(variant: VariantService, context: BuildContextInterface): Promise<OnLoadResult> {\n const metadata: MacrosMetadataInterface = {\n disabledMacroNames: new Set(),\n filesWithMacros: new Set()\n };\n\n context.stage.defineMetadata = metadata;\n\n const warnings: Array<PartialMessage> = [];\n const filesModel = inject(FilesModel);\n const defines = variant.config.define ?? {};\n const files = Object.values(variant.dependencies ?? {});\n\n for (const file of files) {\n const content = filesModel.getOrTouchFile(file)?.contentSnapshot?.text;\n if (!content) continue;\n\n const resolvedFile = filesModel.resolve(file);\n\n IFDEF_REGEX.lastIndex = 0;\n for (const match of content.matchAll(IFDEF_REGEX)) {\n const matchIndex = match.index!;\n if (isCommentLine(content, matchIndex)) continue;\n\n const [ , fn, directive, define ] = match;\n metadata.filesWithMacros.add(resolvedFile); // always register the file\n if (!fn) continue;\n\n if (!fn.startsWith(MACRO_PREFIX)) {\n warnings.push({\n text: `Macro function '${ fn }' not start with '${ MACRO_PREFIX }' prefix to avoid conflicts`,\n location: getLineAndColumn(content, fn, file, matchIndex)\n });\n }\n\n if(directive === 'inline') continue;\n const isDefined = !!defines[define];\n if ((directive === 'ifndef') === isDefined) {\n metadata.disabledMacroNames.add(fn);\n }\n }\n }\n\n return { warnings };\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { OnLoadResult, Message, PartialMessage } from 'esbuild';\nimport type { BuildConfigInterface } from '@interfaces/configuration.interface';\nimport type { BuildContextInterface } from '@providers/interfaces/lifecycle-provider.interface';\nimport type { OnEndType, OnStartType } from '@providers/interfaces/lifecycle-provider.interface';\nimport type { ResultContextInterface } from '@providers/interfaces/lifecycle-provider.interface';\nimport type { BuildResultInterface } from '@providers/interfaces/esbuild-messages-provider.interface';\nimport type { DiagnosticInterface } from '@typescript/services/interfaces/typescript-service.interface';\nimport type { ReloadOptionsInterface, BuildTreeInterface } from '@services/interfaces/build-service.interface';\n\n/**\n * Imports\n */\n\nimport { xBuildError } from '@errors/xbuild.error';\nimport { inject } from '@symlinks/symlinks.module';\nimport { VariantService } from '@services/variant.service';\nimport { LifecycleProvider } from '@providers/lifecycle.provider';\nimport { transformerDirective } from '@directives/macros.directive';\nimport { analyzeMacroMetadata } from '@directives/analyze.directive';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { LanguageHostService } from '@typescript/services/hosts.service';\nimport { enhancedBuildResult, isBuildResultError } from '@providers/esbuild-messages.provider';\n\n/**\n * Orchestrates the build process across multiple variants with lifecycle management and configuration.\n *\n * @remarks\n * The `BuildService` is the primary service for managing multi-variant builds in xBuild.\n * It handles configuration changes, variant lifecycle, type checking, and build execution\n * with support for hot reloading and file watching.\n *\n * **Key responsibilities**:\n * - Manages multiple build variants (e.g., production, development, testing)\n * - Provides reactive configuration updates through subscription system\n * - Coordinates lifecycle hooks (onStart, onEnd) across all variants\n * - Handles macro transformation and directive processing\n * - Supports incremental builds and file touch notifications\n * - Aggregates build results and type checking diagnostics\n *\n * **Architecture**:\n * Each variant is managed by a {@link VariantService} instance with its own:\n * - esbuild configuration and context\n * - TypeScript language service\n * - Lifecycle provider for hooks and plugins\n * - Build state and watch mode support\n *\n * The service uses a subscription pattern to react to configuration changes,\n * automatically creating new variants or disposing removed ones.\n *\n * @example Basic usage\n * ```ts\n * const buildService = new BuildService({\n * variants: {\n * production: {\n * esbuild: { minify: true, sourcemap: false }\n * },\n * development: {\n * esbuild: { minify: false, sourcemap: true }\n * }\n * }\n * });\n *\n * // Build all variants\n * const results = await buildService.build();\n * console.log(results.production.errors);\n * ```\n *\n * @example With lifecycle hooks\n * ```ts\n * const buildService = new BuildService(config);\n *\n * buildService.onStart = (context) => {\n * console.log(`Building variant: ${context.variantName}`);\n * };\n *\n * buildService.onEnd = (context) => {\n * console.log(`Completed ${context.variantName}: ${context.result.errors.length} errors`);\n * };\n *\n * await buildService.build();\n * ```\n *\n * @example Configuration reload\n * ```ts\n * const buildService = new BuildService(initialConfig);\n *\n * // Reload with new configuration\n * buildService.reload({\n * variants: {\n * production: { esbuild: { target: 'es2020' } },\n * staging: { esbuild: { minify: true } }\n * }\n * });\n * // Old variants disposed, new ones created\n * ```\n *\n * @example Type checking\n * ```ts\n * const buildService = new BuildService(config);\n * const diagnostics = await buildService.typeChack();\n *\n * for (const [variant, errors] of Object.entries(diagnostics)) {\n * console.log(`${variant}: ${errors.length} type errors`);\n * }\n * ```\n *\n * @see {@link VariantService} for individual variant management\n * @see {@link ConfigurationService} for configuration handling\n * @see {@link LifecycleProvider} for hook management\n *\n * @since 2.0.0\n */\n\nexport class BuildService {\n /**\n * Callback invoked when a build completes for any variant.\n *\n * @remarks\n * Set via the `onEnd` setter. Called after each variant's build finishes,\n * providing access to build results, errors, warnings, and metadata.\n *\n * @since 2.0.0\n */\n\n private onEndCallback?: OnEndType;\n\n /**\n * Callback invoked when a build starts for any variant.\n *\n * @remarks\n * Set via the `onStart` setter. Called before each variant's build begins,\n * after macro metadata analysis completes.\n *\n * @since 2.0.0\n */\n\n private onStartCallback?: OnStartType;\n\n /**\n * Map of variant names to their service instances.\n *\n * @remarks\n * Contains all active build variants. Variants are created during construction\n * and updated when configuration changes via {@link reload} or {@link setConfiguration}.\n *\n * @since 2.0.0\n */\n\n private variants: { [variant: string]: VariantService } = {};\n\n /**\n * Configuration service managing build settings and variant definitions.\n *\n * @remarks\n * Injected singleton that provides reactive configuration updates through\n * its subscription system. Changes trigger automatic variant recreation.\n *\n * @since 2.0.0\n */\n\n private readonly configuration: ConfigurationService<BuildConfigInterface> = inject(ConfigurationService);\n\n /**\n * Creates a new BuildService instance with optional configuration and command-line arguments.\n *\n * @param argv - Command-line arguments passed to variant services (default: empty object)\n *\n * @remarks\n * The constructor:\n * 1. Accepts optional initial configuration\n * 2. Stores command-line arguments for variant initialization\n * 3. Subscribes to configuration changes via {@link parseVariants}\n * 4. Automatically creates variants defined in the configuration\n *\n * Configuration can be provided later via {@link reload} or {@link setConfiguration}\n * if not supplied during construction.\n *\n * @since 2.0.0\n */\n\n constructor(private argv: Record<string, unknown> = {}) {\n this.configuration.subscribe(this.parseVariants.bind(this));\n }\n\n /**\n * Gets the current complete build configuration.\n *\n * @returns The active build configuration including all variants and common settings\n *\n * @remarks\n * Retrieves the immutable snapshot of the current configuration from the\n * configuration service. Changes to the returned object do not affect\n * the actual configuration - use {@link setConfiguration} or {@link reload} instead.\n *\n * @since 2.0.0\n */\n\n get config(): BuildConfigInterface {\n return this.configuration.getValue();\n }\n\n /**\n * Sets the callback to invoke when any variant build completes.\n *\n * @param callback - Function receiving the result context with build output and metadata\n *\n * @remarks\n * The callback receives a {@link ResultContextInterface} containing:\n * - Variant name\n * - Build result (errors, warnings, outputs)\n * - Metadata files and outputs\n * - Timestamp and duration\n *\n * Called after the build finishes but before promises resolve.\n *\n * @example\n * ```ts\n * buildService.onEnd = (context) => {\n * const { variantName, result } = context;\n * console.log(`✓ ${variantName}: ${result.errors.length} errors`);\n * };\n * ```\n *\n * @since 2.0.0\n */\n\n set onEnd(callback: OnEndType) {\n this.onEndCallback = callback;\n }\n\n /**\n * Sets the callback to invoke when any variant build starts.\n *\n * @param callback - Function receiving the build context with file and variant information\n *\n * @remarks\n * The callback receives a {@link BuildContextInterface} containing:\n * - Variant name\n * - File path being processed\n * - Build stage and metadata\n * - Loader type\n *\n * Called after macro analysis but before transformation begins.\n *\n * @example\n * ```ts\n * buildService.onStart = (context) => {\n * console.log(`Building ${context.args.path} for ${context.variantName}`);\n * };\n * ```\n *\n * @since 2.0.0\n */\n\n set onStart(callback: OnStartType) {\n this.onStartCallback = callback;\n }\n\n /**\n * Reloads the build configuration and updates variants accordingly.\n *\n * @param config - Optional new configuration to replace the current one\n * @param clearCache - Whether to clear cached files and TypeScript language service state before reloading\n *\n * @remarks\n * The reload process:\n * 1. Optionally clears cached file state and TypeScript language service data\n * 2. Replaces configuration if provided\n * 3. Compares new variant names with existing ones\n * 4. Disposes variants no longer in configuration\n * 5. Creates new variants from the updated configuration\n * 6. Existing variants with matching names continue unchanged\n *\n * This is useful for hot-reloading configuration files without restarting the build process.\n *\n * @example\n * ```ts\n * // Reload with a new staging variant\n * buildService.reload({\n * config: {\n * variants: {\n * ...buildService.config.variants,\n * staging: { esbuild: { minify: true } }\n * }\n * }\n * });\n * ```\n *\n * @example\n * ```ts\n * // Reload and clear cached file/type-checking state first\n * buildService.reload({\n * clearCache: true\n * });\n * ```\n *\n * @since 2.3.0\n */\n\n reload({ config, clearCache = false }: ReloadOptionsInterface = {}): void {\n if (clearCache) LanguageHostService.reload();\n if (config) this.configuration.reload(config);\n this.disposeVariants(this.compareKeys(this.config.variants, this.variants));\n this.parseVariants();\n }\n\n /**\n * Notifies all variants that specific files have been modified.\n *\n * @param files - Array of file paths that have changed\n *\n * @remarks\n * Propagates file change notifications to all variant services, triggering\n * incremental rebuilds in watch mode. Each variant's watch service handles\n * the actual rebuild logic.\n *\n * Typically used by file watchers or development servers to trigger hot reloads.\n *\n * @example\n * ```ts\n * // File watcher integration\n * watcher.on('change', (changedFiles) => {\n * buildService.touchFiles(changedFiles);\n * });\n * ```\n *\n * @see {@link VariantService.touchFiles}\n *\n * @since 2.0.0\n */\n\n touchFiles(files: Array<string>): void {\n for (const instance of Object.values(this.variants)) {\n instance.touchFiles(files);\n }\n }\n\n /**\n * Partially updates the build configuration without replacing it entirely.\n *\n * @param config - Partial configuration to merge with the current configuration\n *\n * @remarks\n * Performs a shallow merge of the provided configuration with the current one.\n * Use {@link reload} for deep configuration replacement or variant restructuring.\n *\n * Common use cases:\n * - Toggling minification\n * - Updating define constants\n * - Modifying common build options\n *\n * @example\n * ```ts\n * // Enable minification for all variants\n * buildService.setConfiguration({\n * common: { esbuild: { minify: true } }\n * });\n * ```\n *\n * @see {@link reload} for full configuration replacement\n *\n * @since 2.0.0\n */\n\n setConfiguration(config: Partial<BuildConfigInterface>): void {\n this.configuration.patch(config);\n }\n\n /**\n * Performs TypeScript type checking across all variants.\n *\n * @returns Promise resolving to a map of variant names to their diagnostic results\n *\n * @remarks\n * Runs the TypeScript compiler's diagnostic checker for each variant in parallel.\n * Returns all type errors, warnings, and suggestions without failing the build.\n *\n * **Note**: Method name has a typo - should be `typeCheck` but kept for backward compatibility.\n *\n * Useful for:\n * - Pre-build validation\n * - CI/CD type checking pipelines\n * - IDE integration and diagnostics display\n *\n * @example\n * ```ts\n * const diagnostics = await buildService.typeChack();\n *\n * for (const [variant, errors] of Object.entries(diagnostics)) {\n * if (errors.length > 0) {\n * console.error(`${variant} has ${errors.length} type errors`);\n * errors.forEach(err => console.error(err.messageText));\n * }\n * }\n * ```\n *\n * @see {@link DiagnosticInterface}\n * @see {@link VariantService.check}\n *\n * @since 2.0.0\n */\n\n async typeChack(): Promise<Record<string, DiagnosticInterface[]>> {\n const result: Record<string, Array<DiagnosticInterface>> = {};\n\n for (const variant of Object.values(this.variants)) {\n result[variant.name] = await variant.check();\n }\n\n return result;\n }\n\n /**\n * Executes the build process for all or specific variants,\n * respecting `dependOn` ordering and running independent variants in parallel.\n *\n * @param names - Optional array of variant names to build (builds all if omitted)\n *\n * @returns Promise resolving to a map of variant names to their enhanced build results\n *\n * @throws xBuildError - When a circular dependency is detected before any build starts\n * @throws AggregateError - When any variant build fails, containing all error details\n *\n * @remarks\n * The build process:\n * 1. Validates the dependency graph — throws immediately on circular deps\n * 2. Launches all requested variants concurrently\n * 3. Each variant awaits its `dependOn` dependencies before running\n * 4. Collects results and errors from each variant without stopping others\n * 5. Enhances build results with additional metadata\n * 6. Throws AggregateError if any builds failed\n *\n * **Dependency resolution**:\n * - `dependOn` variants always finish before the dependent variant starts\n * - A shared dependency (e.g. two variants both depending on `types`) builds\n * only once — subsequent dependents await the same running promise\n * - Independent variants run fully in parallel\n *\n * **Error handling**:\n * - Build failures don't stop other variants from building\n * - All errors are collected into {@link BuildTreeInterface.errors} and thrown\n * together after all builds complete\n * - Supports both esbuild-specific errors and generic JavaScript errors\n *\n * **Result enhancement**:\n * Build results are processed by {@link enhancedBuildResult} to provide\n * structured error and warning information.\n *\n * @example Build all variants\n * ```ts\n * try {\n * const results = await buildService.build();\n * console.log(`Built ${Object.keys(results).length} variants`);\n * } catch (error) {\n * if (error instanceof AggregateError) {\n * error.errors.forEach(err => console.error(err.message));\n * }\n * }\n * ```\n *\n * @example Build specific variants\n * ```ts\n * const results = await buildService.build(['production', 'staging']);\n * // Only production and staging variants are built\n * ```\n *\n * @example With dependency ordering\n * ```ts\n * // Given: main dependOn shared, shared dependOn types\n * // Build order: types → shared → main (dependencies first)\n * const results = await buildService.build();\n * ```\n *\n * @see {@link buildVariant} for per-variant execution and caching logic\n * @see {@link BuildTreeInterface}\n * @see {@link enhancedBuildResult}\n * @see {@link BuildResultInterface}\n * @see {@link VariantService.build}\n * @see {@link validateDependencies} for circular dependency detection\n *\n * @since 2.4.0\n */\n\n async build(names?: Array<string>): Promise<Record<string, BuildResultInterface>> {\n const ctx: BuildTreeInterface = {\n cache: new Map(),\n errors: [],\n results: {}\n };\n\n this.validateDependencies(names);\n\n const targets = names ?? Object.keys(this.variants);\n await Promise.all(targets.map(name => this.buildVariant(name, ctx)));\n\n if (ctx.errors.length) throw new AggregateError(ctx.errors, 'Build failed');\n\n return ctx.results;\n }\n\n /**\n * Triggers the onEnd callback when a variant build completes.\n *\n * @param context - The result context containing build output and metadata\n *\n * @remarks\n * Internal handler that safely invokes the user-provided onEnd callback if set.\n * Called by variant lifecycle providers after each build finishes.\n *\n * @since 2.0.0\n */\n\n private onEndTrigger(context: ResultContextInterface): void {\n if (this.onEndCallback) this.onEndCallback(context);\n }\n\n /**\n * Triggers the onStart callback and performs macro analysis before a variant build starts.\n *\n * @param context - The build context containing file and variant information\n *\n * @returns Promise resolving to the load result after macro metadata analysis\n *\n * @throws Error - Propagates errors from macro analysis that aren't AggregateErrors\n *\n * @remarks\n * Internal handler that:\n * 1. Analyzes macro metadata for the file being built\n * 2. Invokes the user-provided onStart callback if set\n * 3. Returns the analysis result to the build pipeline\n * 4. Converts AggregateErrors to esbuild-compatible error format\n *\n * The macro analysis prepares directive information ($$ifdef, $$inline, etc.)\n * that will be used during the transformation phase.\n *\n * @see {@link analyzeMacroMetadata}\n *\n * @since 2.0.0\n */\n\n private async onStartTrigger(context: BuildContextInterface): Promise<OnLoadResult> {\n try {\n const result = await analyzeMacroMetadata(this.variants[context.variantName], context);\n if (this.onStartCallback) this.onStartCallback(context);\n\n return result;\n } catch (error) {\n const errors: Array<PartialMessage> = [];\n if (error instanceof AggregateError) {\n for (const err of error.errors) {\n errors.push({\n detail: err,\n text: err.message\n });\n }\n\n return { errors };\n }\n\n throw error;\n }\n }\n\n /**\n * Disposes and removes variants by name.\n *\n * @param dispose - Array of variant names to dispose\n *\n * @remarks\n * Cleanly shuts down variant services and removes them from the internal map.\n * Called during configuration reload to remove variants no longer in config.\n *\n * Each variant's dispose method:\n * - Stops watch mode if active\n * - Cleans up esbuild contexts\n * - Releases TypeScript language service resources\n *\n * @since 2.0.0\n */\n\n private disposeVariants(dispose: Array<string>): void {\n if (dispose.length) {\n for (const variant of dispose) {\n this.variants[variant].dispose();\n delete this.variants[variant];\n }\n }\n }\n\n /**\n * Compares two objects and returns keys present in the second but not the first.\n *\n * @param obj1 - Reference object (usually new configuration)\n * @param obj2 - Comparison object (usually existing variants)\n *\n * @returns Array of keys present in obj2 but missing in obj1\n *\n * @remarks\n * Used to identify variants that should be disposed during configuration reload.\n * If a variant exists in the service but not in the new configuration, it's removed.\n *\n * @since 2.0.0\n */\n\n private compareKeys(obj1: object, obj2: object): Array<string> {\n const keys2 = Object.keys(obj2);\n const onlyInObj2 = keys2.filter(key => !(key in obj1));\n\n return [ ...onlyInObj2 ];\n }\n\n /**\n * Creates variant service instances from the current configuration.\n *\n * @throws xBuildError - When no variants are defined in the configuration\n *\n * @remarks\n * Invoked by the configuration subscription whenever configuration changes.\n * For each variant in the configuration:\n * 1. Skips if the variant already exists (prevents recreation)\n * 2. Creates a new LifecycleProvider with hooks\n * 3. Attaches onStart and onEnd listeners\n * 4. Creates VariantService with configuration\n * 5. Registers macro transformer directive\n *\n * The lifecycle hooks enable:\n * - Build start/end notifications\n * - Macro analysis and transformation\n * - Custom plugin integration\n *\n * @see {@link VariantService}\n * @see {@link LifecycleProvider}\n * @see {@link transformerDirective}\n *\n * @since 2.0.0\n */\n\n private parseVariants(): void {\n if (!this.config.variants)\n throw new xBuildError('Variants are not defined in the configuration');\n\n for (const name of Object.keys(this.config.variants)) {\n if (this.variants[name]) continue;\n const lifecycle = new LifecycleProvider(name, this.argv);\n lifecycle.onEnd(this.onEndTrigger.bind(this), 'build-service');\n lifecycle.onStart(this.onStartTrigger.bind(this), 'build-service');\n this.variants[name] = new VariantService(name, lifecycle, this.config.variants[name], this.argv);\n lifecycle.onLoad(transformerDirective.bind({}, this.variants[name]), 'build-service');\n }\n }\n\n /**\n * Returns the normalized `dependOn` list for a variant.\n *\n * @param variantName - The variant to look up\n *\n * @returns Array of dependency variant names, empty if none defined\n *\n * @remarks\n * Normalizes the `dependOn` field from the variant configuration into\n * a consistent array form, since the field accepts either a single\n * string or an array of strings.\n *\n * @see {@link buildVariant}\n * @see {@link validateDependencies}\n *\n * @since 2.4.0\n */\n\n private getDependOn(variantName: string): Array<string> {\n const { dependOn } = this.config.variants?.[variantName] ?? {};\n if (!dependOn) return [];\n\n return Array.isArray(dependOn) ? dependOn : [ dependOn ];\n }\n\n /**\n * Validates the dependency graph for all or specific variants before building starts.\n *\n * @param names - Optional subset of variant names to validate (validates all if omitted)\n *\n * @throws xBuildError - When a circular dependency is detected, with the full cycle\n * path included in the message (e.g. `Circular dependency detected: main → shared → main`)\n *\n * @remarks\n * Performs a depth-first traversal of the dependency graph using two sets:\n * - `visited` — variants fully processed, skipped on revisit\n * - `inStack` — variants in the current traversal path, used to detect cycles\n *\n * Dependencies that exist in `dependOn` but have no matching variant instance\n * in {@link variants} are silently skipped.\n *\n * Called by {@link build} before any variant starts, ensuring the entire\n * graph is valid before any work begins.\n *\n * @see {@link build}\n * @see {@link getDependOn}\n *\n * @since 2.4.0\n */\n\n private validateDependencies(names?: Array<string>): void {\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n const visit = (name: string, chain: Array<string>): void => {\n if (inStack.has(name))\n throw new xBuildError(`Circular dependency detected: ${ [ ...chain, name ].join(' → ') }`);\n if (visited.has(name)) return;\n\n inStack.add(name);\n for (const dep of this.getDependOn(name)) {\n if (this.variants[dep]) visit(dep, [ ...chain, name ]);\n }\n inStack.delete(name);\n visited.add(name);\n };\n\n for (const name of (names ?? Object.keys(this.variants))) visit(name, []);\n }\n\n /**\n * Executes the build for a single variant after all its dependencies resolve.\n *\n * @param name - Variant name to build\n * @param ctx - Isolated build context for this {@link build} invocation\n *\n * @remarks\n * Called exclusively by {@link buildVariant} after the promise is registered\n * in {@link BuildTreeInterface.cache}, preventing re-entry.\n *\n * Awaits all `dependOn` dependencies concurrently via `Promise.all` before\n * running the variant. Dependencies missing from {@link variants} are silently skipped.\n *\n * Errors are pushed into {@link BuildTreeInterface.errors} rather than thrown,\n * so all variants attempt to build even if a sibling fails. Handles both\n * esbuild-specific errors via {@link isBuildResultError} and generic JavaScript errors.\n *\n * @see {@link buildVariant}\n * @see {@link getDependOn}\n * @see {@link isBuildResultError}\n * @see {@link BuildTreeInterface}\n * @see {@link enhancedBuildResult}\n *\n * @since 2.4.0\n */\n\n private async executeBuild(name: string, ctx: BuildTreeInterface): Promise<void> {\n const deps = this.getDependOn(name).filter(dep => this.variants[dep]);\n await Promise.all(deps.map(dep => this.buildVariant(dep, ctx)));\n\n const instance = this.variants[name];\n if (!instance) return;\n\n try {\n const result = await instance.build();\n if (result) ctx.results[name] = enhancedBuildResult(result);\n } catch (error) {\n if (isBuildResultError(error) || error instanceof AggregateError) {\n ctx.errors.push(\n ...enhancedBuildResult({ errors: error.errors as Array<Message> }).errors\n );\n } else {\n ctx.errors.push(error instanceof Error ? error : new Error(String(error)));\n }\n }\n }\n\n /**\n * Builds a single variant, first awaiting any `dependOn` dependencies.\n *\n * @param name - Variant name to build\n * @param ctx - Isolated build context for this {@link build} invocation,\n * carrying the promise cache, error list, and results map\n *\n * @returns Promise that resolves when the variant and all its dependencies finish\n *\n * @remarks\n * Stores its promise in {@link BuildTreeInterface.cache} on first call so any\n * subsequent caller depending on the same variant awaits the already-running\n * promise rather than triggering a duplicate build.\n *\n * Delegates actual execution to {@link executeBuild} after registering the promise,\n * ensuring the cache is populated before any async work begins.\n *\n * @see {@link build}\n * @see {@link executeBuild}\n * @see {@link BuildTreeInterface}\n *\n * @since 2.4.0\n */\n\n private buildVariant(name: string, ctx: BuildTreeInterface): Promise<void> {\n const cached = ctx.cache.get(name);\n if (cached) return cached;\n\n const promise = this.executeBuild(name, ctx);\n ctx.cache.set(name, promise);\n\n return promise;\n }\n}\n","\n/**\n * Main entry point and public API for the xBuild build system.\n *\n * @remarks\n * This module serves as the primary interface for xBuild, providing:\n * - Type definitions for configuration and diagnostics\n * - Core services for building, watching, and serving\n * - Utility functions for configuration management\n * - Global macro function declarations for build-time transforms\n *\n * **Usage patterns**:\n * - **CLI usage**: Imported by {@link bash.ts} for command-line operations\n * - **Programmatic usage**: Imported by custom build scripts and tools\n * - **Configuration files**: Type exports used in `xbuild.config.ts`\n *\n * **Key exports**:\n * - `BuildService`: Main build orchestration service\n * - `WatchService`: File system monitoring for rebuilds\n * - `ServerModule`: Development HTTP server\n * - Configuration helper functions\n * - Global macro type declarations\n *\n * @example Programmatic build\n * ```ts\n * import { BuildService, overwriteConfig } from '@remotex-labs/xbuild';\n *\n * overwriteConfig({\n * variants: {\n * production: {\n * esbuild: { minify: true, outdir: 'dist' }\n * }\n * }\n * });\n *\n * const service = new BuildService();\n * await service.build('production');\n * ```\n *\n * @example Configuration file typing\n * ```ts\n * import type { xBuildConfig } from '@remotex-labs/xbuild';\n *\n * export default {\n * variants: {\n * dev: { esbuild: { minify: false } }\n * }\n * } satisfies xBuildConfig;\n * ```\n *\n * @packageDocumentation\n * @since 1.0.0\n */\n\n/**\n * Import will remove at compile time\n */\n\nimport type { PartialBuildConfigType } from '@interfaces/configuration.interface';\nimport type { xBuildConfigInterface } from '@providers/interfaces/config-file-provider.interface';\n\n/**\n * Imports\n */\n\nimport { inject } from '@symlinks/symlinks.module';\nimport { ConfigurationService } from '@services/configuration.service';\n\n/**\n * Export types\n */\n\nexport type * from '@providers/interfaces/lifecycle-provider.interface';\nexport type { ArgumentsInterface } from '@argv/interfaces/argv-module.interface';\nexport type { ServerConfigurationInterface } from '@server/interfaces/server.interface';\nexport type { MacroContextInterface } from '@directives/interfaces/macros-directive.interface';\nexport type { DiagnosticInterface } from '@typescript/services/interfaces/typescript-service.interface';\n\n/**\n * Export\n */\n\nexport * from '@components/glob.component';\nexport * from '@providers/esbuild-messages.provider';\nexport { ServerModule } from '@server/server.module';\nexport { WatchService } from '@services/watch.service';\n\n/**\n * Type alias for xBuild configuration objects.\n *\n * @remarks\n * Provides a shorter, more conventional name for the configuration interface.\n * Used primarily in configuration files to declare configuration object types\n * with TypeScript's `satisfies` operator or type annotations.\n *\n * **Properties include**:\n * - `variants`: Build variant configurations (dev, prod, etc.)\n * - `common`: Shared settings across all variants\n * - `serve`: Development server configuration\n * - `userArgv`: Custom CLI argument definitions\n * - `verbose`: Detailed logging flag\n *\n * @example Type annotation\n * ```ts\n * const config: xBuildConfig = {\n * variants: {\n * production: {\n * esbuild: { minify: true, outdir: 'dist' }\n * }\n * }\n * };\n * ```\n *\n * @example With satisfies operator (recommended)\n * ```ts\n * export default {\n * common: { esbuild: { platform: 'node' } },\n * variants: {\n * dev: { esbuild: { minify: false } },\n * prod: { esbuild: { minify: true } }\n * }\n * } satisfies xBuildConfig;\n * ```\n *\n * @see {@link xBuildConfigInterface} for detailed property documentation\n *\n * @since 2.0.0\n */\n\nexport type xBuildConfig = xBuildConfigInterface;\n\n/**\n * Global type declarations for xBuild's build-time macro system.\n *\n * @remarks\n * Declares globally available macro functions that are transformed at build time.\n * These functions provide conditional compilation and inline evaluation capabilities\n * without requiring explicit imports.\n *\n * **Macro functions**:\n * - `$$ifdef`: Include code when definition is truthy\n * - `$$ifndef`: Include code when definition is falsy/undefined\n * - `$$inline`: Evaluate expressions at build time\n *\n * All macro functions are:\n * - Prefixed with `$$` to avoid naming conflicts\n * - Transformed during the build process (not runtime functions)\n * - Available globally without imports\n * - Type-safe with TypeScript\n *\n * **DefineType**: String literal union representing common definition names,\n * extensible with custom strings via `| string`.\n *\n * @example Conditional compilation\n * ```ts\n * const logger = $$ifdef('DEBUG', () => console.log);\n * // In production (DEBUG=false), becomes: const logger = undefined;\n * // In development (DEBUG=true), becomes: function logger() { return console.log; }\n * ```\n *\n * @example Negated conditional\n * ```ts\n * const optimized = $$ifndef('DEBUG', () => fastImplementation());\n * // Included only when DEBUG is not defined or false\n * ```\n *\n * @example Inline evaluation\n * ```ts\n * const version = $$inline(() => process.env.VERSION);\n * // Evaluates at build time, replaces with actual value\n * ```\n *\n * @see {@link transformerDirective} for macro transformation implementation\n *\n * @since 2.0.0\n */\n\ndeclare global {\n /**\n * Type representing valid definition names for conditional macros.\n *\n * @remarks\n * Provides autocomplete for common definition names while allowing\n * custom strings. Definitions are typically set via:\n * - `config.variants[name].define` in configuration\n * - `--define` CLI flag\n * - Environment variables\n *\n * **Common definitions**:\n * - `DEBUG`: Development/debugging features\n * - `PRODUCTION`: Production-only optimizations\n * - `TEST`: Test environment features\n * - `DEV`: Development mode\n * - `CI`: Continuous integration environment\n * - `LOCAL`: Local development\n *\n * @example\n * ```ts\n * // With type checking\n * const fn = $$ifdef('DEBUG', log); // 'DEBUG' autocompletes\n * const custom = $$ifdef('MY_FEATURE', impl); // Custom string also allowed\n * ```\n *\n * @since 2.0.0\n */\n\n type DefineType = 'DEBUG' | 'PRODUCTION' | 'TEST' | 'DEV' | 'CI' | 'LOCAL' | string;\n\n /**\n * Conditional inclusion macro that includes code when a definition is truthy.\n *\n * @template T - The type of the callback return value\n * @param define - The definition name to check\n * @param callback - The code to include when definition is truthy\n *\n * @returns The callback value when condition is true, `undefined` when false\n *\n * @remarks\n * Transformed at build time based on the variant's `define` configuration.\n * When the specified definition is truthy, the callback is included in the\n * output; otherwise, the entire expression is replaced with `undefined`.\n *\n * **Transformation behavior**:\n * - Definition is truthy → Callback is included as-is\n * - Definition is falsy/undefined → Replaced with `undefined`\n * - Works with functions, objects, primitives, or any expression\n *\n * **Variable declarations**:\n * ```ts\n * const $$debug = $$ifdef('DEBUG', () => console.log);\n * // DEBUG=true → function $$debug() { return console.log; }\n * // DEBUG=false → undefined (entire declaration removed)\n * ```\n *\n * **Expression statements**:\n * ```ts\n * $$ifdef('DEBUG', () => initDebugTools());\n * // DEBUG=true → (() => initDebugTools())()\n * // DEBUG=false → (removed)\n * ```\n *\n * @example Function inclusion\n * ```ts\n * const logger = $$ifdef('DEBUG', () => console.log);\n *\n * // With DEBUG=true\n * logger('test'); // Works: logs 'test'\n *\n * // With DEBUG=false\n * logger('test'); // TypeError: logger is undefined\n * ```\n *\n * @example Object inclusion\n * ```ts\n * const config = {\n * apiUrl: 'https://api.example.com',\n * debug: $$ifdef('DEBUG', { verbose: true, logLevel: 'trace' })\n * };\n *\n * // With DEBUG=true\n * // config.debug = { verbose: true, logLevel: 'trace' }\n *\n * // With DEBUG=false\n * // config.debug = undefined\n * ```\n *\n * @example Guards in code\n * ```ts\n * if ($$ifdef('DEBUG', true)) {\n * console.log('Debug mode active');\n * }\n * // DEBUG=false → if (undefined) { ... } (block never executes)\n * ```\n *\n * @see {@link DefineType} for valid definition names\n * @since 2.0.0\n */\n\n function $$ifdef<T>(define: DefineType, callback: T):\n T extends (...args: infer A) => infer R ? (...args: A) => R | undefined : T | undefined;\n\n /**\n * Conditional inclusion macro that includes code when a definition is falsy or undefined.\n *\n * @template T - The type of the callback return value\n * @param define - The definition name to check\n * @param callback - The code to include when definition is falsy/undefined\n *\n * @returns The callback value when condition is false, `undefined` when true\n *\n * @remarks\n * The inverse of `$$ifdef`. Transformed at build time based on the\n * variant's `define` configuration. When the specified definition is falsy\n * or undefined, the callback is included; otherwise, replaced with `undefined`.\n *\n * **Transformation behavior**:\n * - Definition is falsy/undefined → Callback is included as-is\n * - Definition is truthy → Replaced with `undefined`\n * - Works with functions, objects, primitives, or any expression\n *\n * **Use cases**:\n * - Development-only features (disabled in production)\n * - Fallback implementations (when optimized version unavailable)\n * - Debugging tools (removed in release builds)\n *\n * @example Development-only features\n * ```ts\n * const devTools = $$ifndef('PRODUCTION', () => initDevTools());\n *\n * // With PRODUCTION=false (dev mode)\n * devTools(); // Works: initializes dev tools\n *\n * // With PRODUCTION=true (production)\n * devTools(); // TypeError: devTools is undefined\n * ```\n *\n * @example Fallback implementation\n * ```ts\n * const optimizer = $$ifndef('NATIVE_OPTIMIZER', () => jsOptimizer());\n *\n * // With NATIVE_OPTIMIZER undefined\n * // Uses JavaScript fallback implementation\n *\n * // With NATIVE_OPTIMIZER=true\n * // optimizer is undefined, use native implementation elsewhere\n * ```\n *\n * @example Conditional exports\n * ```ts\n * export const debug = $$ifndef('PRODUCTION', {\n * log: console.log,\n * trace: console.trace\n * });\n *\n * // In development: exports debug object\n * // In production: export const debug = undefined;\n * ```\n *\n * @see {@link DefineType} for valid definition names\n * @since 2.0.0\n */\n\n function $$ifndef<T>(define: DefineType, callback: T):\n T extends (...args: infer A) => infer R ? (...args: A) => R | undefined : T | undefined;\n\n /**\n * Inline evaluation macro that executes code at build time and replaces it with the result.\n *\n * @template T - The return type of the callback function\n * @param callback - Expression to evaluate at build time\n *\n * @returns The evaluated result with its original type, or `undefined` on evaluation failure\n *\n * @remarks\n * Executes the provided callback during the build process (not at runtime) and\n * replaces the macro call with the evaluated result. This enables:\n * - Injecting build-time environment variables\n * - Computing values during compilation\n * - Generating code from external sources\n * - Eliminating runtime overhead for static values\n *\n * **Execution context**:\n * - Runs in the Node.js build environment\n * - Has access to process.env and Node.js APIs\n * - Executes once per build, not per file or variant\n * - Errors during evaluation cause build failure\n *\n * **Return value handling**:\n * - The result preserves the original return type from the callback\n * - Primitives (string, number, boolean) are properly typed\n * - Objects and arrays maintain their structure and types\n * - Functions are toString()'d (use carefully)\n * - Returns `undefined` if evaluation fails or callback returns undefined\n *\n * **Common use cases**:\n * - Environment variable injection\n * - Build timestamp generation\n * - Package version embedding\n * - Configuration value computation\n *\n * @example Environment variable injection\n * ```ts\n * const apiUrl = $$inline(() => process.env.API_URL);\n * // Type: string | undefined\n * // Becomes: const apiUrl = \"https://api.example.com\";\n * ```\n *\n * @example Build metadata\n * ```ts\n * const buildInfo = {\n * version: $$inline(() => require('./package.json').version),\n * timestamp: $$inline(() => new Date().toISOString()),\n * commit: $$inline(() => process.env.GIT_COMMIT)\n * };\n * // Each value retains its type (string | undefined)\n * ```\n *\n * @example Computed configuration\n * ```ts\n * const maxWorkers = $$inline(() => {\n * const cpus = require('os').cpus().length;\n * return Math.max(1, cpus - 1);\n * });\n * // Type: number | undefined\n * // Computes optimal worker count during build\n * ```\n *\n * @example Feature flags from environment\n * ```ts\n * const features = {\n * betaFeatures: $$inline(() => process.env.ENABLE_BETA === 'true'),\n * debugMode: $$inline(() => process.env.NODE_ENV !== 'production')\n * };\n * // Boolean values computed at build time, typed as boolean | undefined\n * ```\n *\n * @see {@link astInlineCallExpression} for evaluation implementation\n *\n * @since 2.0.0\n */\n\n function $$inline<T>(callback: () => T): T | undefined;\n\n /**\n * Pre-configuration CLI arguments snapshot (bootstrap argv).\n *\n * @remarks\n * A globally accessible object used during early CLI bootstrap to store the result of\n * the *minimal* argument parse (typically just enough to locate the config file).\n *\n * This is useful when later stages need access to the initial argv values before the\n * full, enhanced parse (with user extensions) is performed.\n *\n * **Intended usage:**\n * - Set once at startup (e.g., right after parsing `--config`)\n * - Read later by services/modules that need bootstrap context\n *\n * **Shape:**\n * Uses `Record<string, unknown>` because the exact keys depend on the CLI parser and\n * configuration-defined options.\n *\n * @example\n * ```ts\n * // After minimal parsing\n * globalThis.$argv = { config: 'xbuild.config.ts', _: [], $0: 'xbuild' };\n *\n * // Later\n * const configPath = String($argv.config);\n * ```\n *\n * @since 2.0.0\n */\n\n var $argv: Record<string, unknown>;\n}\n\n/**\n * Core build orchestration service for managing multi-variant builds with lifecycle hooks.\n *\n * @remarks\n * The `BuildService` is the primary entry point for programmatic xBuild usage,\n * providing comprehensive build orchestration across multiple variants (e.g.,\n * production, development, staging) with reactive configuration management.\n *\n * **Key capabilities**:\n * - Multi-variant build execution with parallel processing\n * - Reactive configuration updates via subscription pattern\n * - TypeScript type checking across all variants\n * - Incremental builds with file touch notifications\n * - Lifecycle hooks (onStart, onEnd) for custom build logic\n * - Macro transformation and conditional compilation\n * - Hot-reloading configuration in watch mode\n *\n * **Variant management**:\n * Each variant is an isolated build configuration with its own:\n * - esbuild settings (minification, sourcemaps, platform, etc.)\n * - TypeScript compiler options and language service\n * - Output directory and entry points\n * - Define constants for conditional compilation\n * - Custom lifecycle hooks and plugins\n *\n * **Usage patterns**:\n * - **CLI mode**: Instantiated by {@link bash.ts} with command-line arguments\n * - **Programmatic mode**: Created in custom build scripts for automation\n * - **Watch mode**: Responds to file changes with incremental rebuilds\n * - **Testing**: Type-check only mode for CI/CD pipelines\n *\n * @example Programmatic build with single variant\n * ```ts\n * import { BuildService, overwriteConfig } from '@remotex-labs/xbuild';\n *\n * // Configure build\n * overwriteConfig({\n * variants: {\n * production: {\n * esbuild: {\n * minify: true,\n * sourcemap: false,\n * outdir: 'dist',\n * platform: 'node'\n * }\n * }\n * }\n * });\n *\n * // Execute build\n * const service = new BuildService();\n * await service.build('production');\n * console.log('Build complete!');\n * ```\n *\n * @example Multi-variant build with lifecycle hooks\n * ```ts\n * import { BuildService, overwriteConfig } from '@remotex-labs/xbuild';\n *\n * overwriteConfig({\n * variants: {\n * cjs: {\n * esbuild: { format: 'cjs', outdir: 'dist/cjs' }\n * },\n * esm: {\n * esbuild: { format: 'esm', outdir: 'dist/esm' }\n * }\n * }\n * });\n *\n * const service = new BuildService();\n *\n * // Track build progress\n * service.onStart = (context) => {\n * console.log(`Building ${context.variantName}...`);\n * };\n *\n * service.onEnd = (context) => {\n * const { variantName, buildResult, duration } = context;\n * if (buildResult.errors.length === 0) {\n * console.log(`✓ ${variantName} completed in ${duration}ms`);\n * } else {\n * console.error(`✗ ${variantName} failed with ${buildResult.errors.length} errors`);\n * }\n * };\n *\n * // Build all variants in parallel\n * await service.build();\n * ```\n *\n * @example Type checking without building\n * ```ts\n * import { BuildService, overwriteConfig } from '@remotex-labs/xbuild';\n *\n * overwriteConfig({\n * variants: {\n * main: {\n * esbuild: { entryPoints: ['src/**\\/*.ts'] },\n * types: { failOnError: true }\n * }\n * }\n * });\n *\n * const service = new BuildService();\n * const diagnostics = await service.typeChack();\n *\n * for (const [variant, errors] of Object.entries(diagnostics)) {\n * if (errors.length > 0) {\n * console.error(`${variant}: ${errors.length} type errors`);\n * process.exit(1);\n * }\n * }\n * ```\n *\n * @example Configuration hot-reloading in watch mode\n * ```ts\n * import { BuildService } from '@remotex-labs/xbuild';\n * import { watch } from 'chokidar';\n *\n * const service = new BuildService();\n *\n * // Watch for configuration changes\n * watch('xbuild.config.ts').on('change', async () => {\n * const newConfig = await import('./xbuild.config.ts');\n * service.reload(newConfig.default);\n * console.log('Configuration reloaded, rebuilding...');\n * });\n *\n * // Watch for source file changes\n * watch('src/**\\/*.ts').on('change', (paths) => {\n * service.touchFiles([paths]);\n * });\n * ```\n *\n * @example Conditional compilation with defines\n * ```ts\n * import { BuildService, overwriteConfig } from '@remotex-labs/xbuild';\n *\n * overwriteConfig({\n * variants: {\n * development: {\n * esbuild: { outdir: 'dev' },\n * define: {\n * DEBUG: true,\n * PRODUCTION: false\n * }\n * },\n * production: {\n * esbuild: { minify: true, outdir: 'dist' },\n * define: {\n * DEBUG: false,\n * PRODUCTION: true\n * }\n * }\n * }\n * });\n *\n * // Source code can use conditional macros:\n * // const logger = $$ifdef('DEBUG', () => console.log);\n * // logger?.('Debug message'); // Only included in development\n *\n * const service = new BuildService();\n * await service.build();\n * ```\n *\n * @example Custom arguments and metadata\n * ```ts\n * import { BuildService, overwriteConfig } from '@remotex-labs/xbuild';\n *\n * overwriteConfig({\n * userArgv: {\n * deploy: { type: 'boolean', description: 'Deploy after build' },\n * environment: { type: 'string', default: 'staging' }\n * },\n * variants: {\n * main: { esbuild: { outdir: 'dist' } }\n * }\n * });\n *\n * const service = new BuildService({\n * deploy: true,\n * environment: 'production'\n * });\n *\n * service.onEnd = async (context) => {\n * if (context.argv.deploy && context.buildResult.errors.length === 0) {\n * await deployToCDN(context.argv.environment);\n * }\n * };\n *\n * await service.build();\n * ```\n *\n * @see {@link OnEndType} for end hook signature\n * @see {@link OnStartType} for start hook signature\n * @see {@link WatchService} for file watching capabilities\n * @see {@link VariantService} for individual variant management\n * @see {@link patchConfig} for incremental configuration updates\n * @see {@link overwriteConfig} for full configuration replacement\n *\n * @since 2.0.0\n */\n\nexport { BuildService } from '@services/build.service';\n\n/**\n * Replaces the entire xBuild configuration with a new configuration.\n *\n * @param config - New configuration to apply\n *\n * @remarks\n * Completely overwrites the current configuration with the provided configuration.\n * This is a destructive operation that discards all existing settings, including:\n * - All variant configurations\n * - Common settings\n * - Server configuration\n * - User-defined CLI arguments\n *\n * **Use cases**:\n * - Programmatic build scripts that fully control configuration\n * - Testing scenarios requiring isolated configuration\n * - Dynamic configuration generation\n * - Configuration hot-reloading in watch mode\n *\n * **Timing considerations**:\n * - Must be called before creating `BuildService` instances\n * - In watch mode, triggers rebuild with new configuration\n * - Settings take effect immediately for subsequent builds\n *\n * **Difference from {@link patchConfig}**:\n * - `overwriteConfig`: Replaces entire configuration (destructive)\n * - `patchConfig`: Merges with existing configuration (additive)\n *\n * @example Programmatic configuration\n * ```ts\n * import { overwriteConfig, BuildService } from '@remotex-labs/xbuild';\n *\n * overwriteConfig({\n * variants: {\n * production: {\n * esbuild: {\n * minify: true,\n * outdir: 'dist',\n * platform: 'node'\n * }\n * }\n * }\n * });\n *\n * const service = new BuildService();\n * await service.build('production');\n * ```\n *\n * @example Dynamic configuration\n * ```ts\n * const isProd = process.env.NODE_ENV === 'production';\n *\n * overwriteConfig({\n * variants: {\n * main: {\n * esbuild: {\n * minify: isProd,\n * sourcemap: !isProd,\n * outdir: isProd ? 'dist' : 'dev'\n * }\n * }\n * }\n * });\n * ```\n *\n * @example Configuration reload in watch mode\n * ```ts\n * // In file change handler\n * if (changedFile === 'xbuild.config.ts') {\n * const newConfig = await loadConfig();\n * overwriteConfig(newConfig);\n * // Next build uses new configuration\n * }\n * ```\n *\n * @see {@link PartialBuildConfigType} for configuration structure\n * @see {@link patchConfig} for non-destructive configuration updates\n * @see {@link ConfigurationService.reload} for implementation details\n *\n * @since 2.0.0\n */\n\nexport function overwriteConfig(config: PartialBuildConfigType): void {\n inject(ConfigurationService).reload(config);\n}\n\n/**\n * Merges the provided configuration with the existing xBuild configuration.\n *\n * @param config - Partial configuration to merge\n *\n * @remarks\n * Performs a deep merge of the provided configuration with the current configuration,\n * preserving existing settings not specified in the patch. This is a non-destructive\n * operation that allows incremental configuration updates.\n *\n * **Merge behavior**:\n * - Object properties are deeply merged (not replaced)\n * - Array properties are replaced (not concatenated)\n * - Undefined values in patch are ignored (don't remove existing values)\n * - Null values in patch replace existing values\n *\n * **Use cases**:\n * - Adding new variants without affecting existing ones\n * - Updating specific settings while preserving others\n * - Applying conditional configuration overlays\n * - Plugin-based configuration extension\n *\n * **Timing considerations**:\n * - Can be called before or after creating `BuildService` instances\n * - Settings take effect immediately for subsequent builds\n * - Useful for progressive configuration in build scripts\n *\n * **Difference from {@link overwriteConfig}**:\n * - `patchConfig`: Merges with existing configuration (additive)\n * - `overwriteConfig`: Replaces entire configuration (destructive)\n *\n * @example Adding a new variant\n * ```ts\n * import { patchConfig } from '@remotex-labs/xbuild';\n *\n * // Existing config has 'dev' and 'prod' variants\n * patchConfig({\n * variants: {\n * staging: {\n * esbuild: {\n * minify: true,\n * outdir: 'staging'\n * }\n * }\n * }\n * });\n * // Now has 'dev', 'prod', and 'staging' variants\n * ```\n *\n * @example Updating specific settings\n * ```ts\n * // Update only output directory, preserve other settings\n * patchConfig({\n * variants: {\n * production: {\n * esbuild: {\n * outdir: 'build'\n * }\n * }\n * }\n * });\n * // Other production settings (minify, platform, etc.) unchanged\n * ```\n *\n * @example Conditional configuration\n * ```ts\n * if (process.env.ENABLE_SOURCE_MAPS === 'true') {\n * patchConfig({\n * common: {\n * esbuild: {\n * sourcemap: 'linked'\n * }\n * }\n * });\n * }\n * ```\n *\n * @example Plugin pattern\n * ```ts\n * function addTypeScriptPaths(paths: Record<string, string[]>) {\n * patchConfig({\n * common: {\n * esbuild: {\n * tsconfig: './tsconfig.json'\n * }\n * }\n * });\n * }\n *\n * addTypeScriptPaths({ '@/*': ['src/*'] });\n * ```\n *\n * @see {@link overwriteConfig} for full configuration replacement\n * @see {@link PartialBuildConfigType} for configuration structure\n * @see {@link ConfigurationService.patch} for implementation details\n *\n * @since 2.0.0\n */\n\nexport function patchConfig(config: PartialBuildConfigType): void {\n inject(ConfigurationService).patch(config);\n}\n","/**\n * Maps terminal control codes to exit signal identifiers.\n *\n * @remarks\n * This constant object defines the ANSI escape sequences for common\n * terminal interrupt signals. These are used to detect when users\n * attempt to terminate the application via keyboard shortcuts.\n *\n * The signals are:\n * - `\\x03` (Ctrl+C) - SIGINT signal for interrupting the process\n * - `\\x04` (Ctrl+D) - SIGQUIT signal for quitting the process\n *\n * @example\n * ```ts\n * if (code === EXIT_SIGNALS.SIGINT) {\n * console.log('Caught Ctrl+C, exiting...');\n * process.exit(1);\n * }\n * ```\n *\n * @see WatchModule\n * @since 2.0.0\n */\n\n\nexport const EXIT_SIGNALS = {\n SIGINT: '\\x03', // Ctrl+C\n SIGQUIT: '\\x04' // Ctrl+D\n} as const;\n\n/**\n * Maps keyboard shortcuts to their corresponding action identifiers.\n *\n * @remarks\n * This constant object defines the single-character keys used for interactive terminal commands.\n * Each key triggers a specific development action such as restarting the server or clearing the console.\n *\n * The mappings are:\n * - `h` - Display help/shortcuts\n * - `q` - Quit the application\n * - `c` - Clear console\n * - `r` - Restart the server\n * - `u` - Show server URL\n * - `o` - Open in browser\n *\n * @example\n * ```ts\n * if (key.name === KEY_MAPPINGS.RELOAD) {\n * console.log('Restarting server...');\n * }\n * ```\n *\n * @see WatchModule\n * @since 2.0.0\n */\n\nexport const KEY_MAPPINGS = {\n HELP: 'h',\n QUIT: 'q',\n CLEAR: 'c',\n RELOAD: 'r',\n VERBOSE: 'v',\n SHOW_URL: 'u',\n OPEN_BROWSER: 'o'\n} as const;\n\n/**\n * Maps operating system platform identifiers to their browser-opening commands.\n *\n * @remarks\n * This constant object provides the appropriate shell command for opening\n * URLs in the default browser on different operating systems. It is used\n * by {@link openInBrowser} to ensure cross-platform compatibility.\n *\n * The platform commands are:\n * - `win32` - Windows: `start`\n * - `darwin` - macOS: `open`\n * - `linux` - Linux: `xdg-open`\n *\n * For unsupported platforms, `xdg-open` is used as a fallback.\n *\n * @example\n * ```ts\n * const platform = process.platform as keyof typeof COMMAND_MAP;\n * const command = COMMAND_MAP[platform] ?? 'xdg-open';\n * exec(`${command} http://localhost:3000`);\n * ```\n *\n * @see WatchModule\n * @since 2.0.0\n */\n\nexport const COMMAND_MAP = {\n win32: 'start',\n darwin: 'open',\n linux: 'xdg-open'\n} as const;\n","/**\n * Import will remove at compile time\n */\n\nimport type { BuildOptions } from 'esbuild';\nimport type { xBuildConfigInterface } from '@providers/interfaces/config-file-provider.interface';\n\n/**\n * Imports\n */\n\nimport { existsSync } from 'fs';\nimport { runInThisContext } from 'vm';\nimport { createRequire } from 'module';\nimport { resolve } from '@remotex-labs/xmap';\nimport { inject } from '@symlinks/symlinks.module';\nimport { buildFiles } from '@services/transpiler.service';\nimport { FilesModel } from '@typescript/models/files.model';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * Transpilation options for configuration file compilation.\n *\n * @remarks\n * These esbuild options are used exclusively for transpiling TypeScript configuration\n * files (e.g., `config.xbuild.ts`) into executable JavaScript. The configuration\n * prioritizes correctness and simplicity over output size or performance.\n *\n * **Key settings:**\n * - **No bundling**: Dependencies are external to avoid conflicts\n * - **CommonJS output**: Enables `require()` and `module.exports` execution\n * - **Node.js platform**: Uses Node.js module resolution\n * - **Minimal minification**: Only syntax and whitespace for readability\n * - **Symbol preservation**: Maintains symlinks for monorepo support\n *\n * These options ensure configuration files can safely import types and utilities\n * without bundling their dependencies into the transpiled output.\n *\n * @since 2.0.0\n */\n\nconst transpileOptions: BuildOptions = {\n minify: false,\n format: 'cjs',\n platform: 'node',\n logLevel: 'silent',\n packages: 'external',\n minifySyntax: true,\n preserveSymlinks: true,\n minifyWhitespace: true,\n minifyIdentifiers: false\n};\n\n/**\n * Loads and executes a TypeScript configuration file, returning its exported configuration.\n *\n * @param path - Absolute or relative path to the configuration file\n * @returns Parsed configuration object, or empty object if file doesn't exist\n *\n * @template T - Configuration interface type (extends {@link xBuildConfigInterface})\n *\n * @remarks\n * This provider enables xBuild to load TypeScript configuration files with full type\n * safety and IDE support. It performs the following steps:\n *\n * 1. **Validation**: Checks if the file exists (returns an empty object if not)\n * 2. **Transpilation**: Compiles TypeScript to JavaScript using esbuild\n * 3. **Source map registration**: Registers the source map for error reporting\n * 4. **Environment setup**: Creates Node.js module context with `require()` support\n * 5. **Execution**: Runs the compiled code in an isolated VM context\n * 6. **Export extraction**: Retrieves the configuration from `module.exports`\n *\n * **Export resolution:**\n * - Prefers named export: `export const config = { ... }`\n * - Falls back to default export: `export default { ... }`\n * - Returns empty object if no valid export found\n *\n * **Module context:**\n * The function creates a temporary module context to execute the configuration file,\n * providing access to Node.js built-ins and the ability to import dependencies. This\n * allows configuration files to use dynamic imports, helper functions, and shared utilities.\n *\n * **Source map support:**\n * Source maps are registered with the framework service to ensure TypeScript error\n * locations are correctly mapped when errors occur in configuration files.\n *\n * @example\n * ```ts\n * // Load default configuration\n * const config = await configFileProvider<BuildConfigInterface>(\n * 'config.xbuild.ts'\n * );\n * ```\n *\n * @example\n * ```ts\n * // Load custom configuration with type safety\n * interface CustomConfig extends xBuildConfigInterface {\n * customField: string;\n * }\n *\n * const config = await configFileProvider<CustomConfig>(\n * 'custom.config.ts'\n * );\n *\n * console.log(config.customField); // Type-safe access\n * ```\n *\n * @example\n * ```ts\n * // Configuration file structure\n * // config.xbuild.ts\n * import { BuildConfigInterface } from '@xbuild/types';\n *\n * export const config: BuildConfigInterface = {\n * variants: {\n * esm: {\n * esbuild: {\n * entryPoints: ['src/index.ts'],\n * format: 'esm'\n * }\n * }\n * }\n * };\n * ```\n *\n * @example\n * ```ts\n * // Configuration with default export\n * // config.xbuild.ts\n * export default {\n * common: {\n * types: true\n * },\n * variants: { ... }\n * };\n * ```\n *\n * @see {@link buildFiles}\n * @see {@link xBuildConfigInterface}\n * @see {@link FrameworkService.setSource}\n *\n * @since 2.0.0\n */\n\nexport async function configFileProvider<T extends xBuildConfigInterface>(path: string): Promise<T> {\n if (!path || !existsSync(path)) return <T>{};\n inject(FilesModel).touchFile(path);\n\n const [ map, code ] = (await buildFiles([ path ], { ...transpileOptions, outdir: 'tmp' })).outputFiles!;\n inject(FrameworkService).setSource(map.text, path);\n\n globalThis.module = { exports: {} };\n globalThis.require = createRequire(resolve(path));\n\n await runInThisContext(code.text, { filename: path });\n const config = module.exports.config ?? module.exports.default;\n if (!config) return <T> {};\n\n return <T> config;\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { Metafile } from 'esbuild';\nimport type { IssueType } from '@components/interfaces/printer-component.interface';\nimport type { MacrosStateInterface } from '@directives/interfaces/analyze-directive.interface';\nimport type { DiagnosticInterface } from '@typescript/services/interfaces/typescript-service.interface';\nimport type { BuildContextInterface, ResultContextInterface } from '@providers/interfaces/lifecycle-provider.interface';\n\n/**\n * Imports\n */\n\nimport { relative } from '@remotex-labs/xmap';\nimport { DiagnosticCategory } from 'typescript';\nimport { TypesError } from '@errors/types.error';\nimport { xBuildError } from '@errors/xbuild.error';\nimport { inject } from '@symlinks/symlinks.module';\nimport { xBuildBaseError } from '@errors/base.error';\nimport { prefix } from '@components/banner.component';\nimport { VMRuntimeError } from '@errors/vm-runtime.error';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { mutedColor, pathColor, textColor, warnColor } from '@components/color.component';\nimport { errorColor, infoColor, keywordColor, okColor } from '@components/color.component';\nimport { enhancedBuildResult, isBuildResultError } from '@providers/esbuild-messages.provider';\n\n/**\n * Constants\n */\n\nexport const INDENT = ' ';\nexport const KILOBYTE = 1024;\nexport const MEGABYTE = KILOBYTE * 1024;\nexport const DASH_SYMBOL = '—';\nexport const ARROW_SYMBOL = '→';\nexport const ERROR_SYMBOL = '×';\nexport const WARNING_SYMBOL = '•';\n\n/**\n * Creates a formatted prefix for action log messages.\n *\n * @remarks\n * Generates a standardized prefix combining the build banner prefix,\n * a symbol (typically an arrow), and a colored action name. This ensures\n * consistent formatting across all build action logs.\n *\n * @param action - The action name to display (e.g., 'build', 'completed')\n * @param symbol - The symbol to display, defaults to a dimmed arrow\n *\n * @returns A formatted string with prefix, symbol, and colored action name\n *\n * @example\n * ```ts\n * const buildPrefix = createActionPrefix('build');\n * // Output: \"[xBuild] → build\"\n *\n * const errorPrefix = createActionPrefix('completed', errorColor(ERROR_SYMBOL));\n * // Output: \"[xBuild] × completed\"\n * ```\n *\n * @see {@link prefix}\n * @see {@link infoColor}\n *\n * @since 2.0.0\n */\n\nexport function createActionPrefix(action: string, symbol: string = infoColor.dim(ARROW_SYMBOL)): string {\n return `${ prefix() } ${ symbol } ${ infoColor(action) }`;\n}\n\n/**\n * Formats a byte size into a human-readable string with appropriate units.\n *\n * @remarks\n * Converts raw byte counts into formatted strings using B, KB, or MB units\n * depending on the size. Values are rounded to 2 decimal places for KB and MB.\n * This function is used primarily for displaying file sizes in build output.\n *\n * @param bytes - The number of bytes to format\n *\n * @returns A formatted string with the size and the appropriate unit (B, KB, or MB)\n *\n * @example\n * ```ts\n * formatByteSize(512); // \"512 B\"\n * formatByteSize(2048); // \"2.00 KB\"\n * formatByteSize(1572864); // \"1.50 MB\"\n * ```\n *\n * @since 2.0.0\n */\n\nexport function formatByteSize(bytes: number): string {\n if (bytes < KILOBYTE) return `${ bytes } B`;\n if (bytes < MEGABYTE) return `${ (bytes / KILOBYTE).toFixed(2) } KB`;\n\n return `${ (bytes / MEGABYTE).toFixed(2) } MB`;\n}\n\n/**\n * Formats a TypeScript diagnostic's file location into a readable string.\n *\n * @remarks\n * Creates a standardized location string in the format `file:line:column`,\n * similar to standard compiler output. Line and column numbers are 1-based\n * (incremented from TypeScript's 0-based values). The file path is made\n * relative to the current working directory for brevity.\n *\n * @param diagnostic - The TypeScript diagnostic containing location information\n *\n * @returns A formatted location string with colored path and position\n *\n * @example\n * ```ts\n * const diagnostic: DiagnosticInterface = {\n * file: '/project/src/index.ts',\n * line: 10,\n * column: 5,\n * code: 2304,\n * message: 'Cannot find name'\n * };\n *\n * formatDiagnosticLocation(diagnostic);\n * // Output: \"src/index.ts:11:6\"\n * ```\n *\n * @see {@link pathColor}\n * @see {@link warnColor}\n * @see {@link DiagnosticInterface}\n *\n * @since 2.0.0\n */\n\nexport function formatDiagnosticLocation(diagnostic: DiagnosticInterface): string {\n const filePath = diagnostic.file ? relative(process.cwd(), diagnostic.file) : '(unknown)';\n const lineNumber = warnColor(String((diagnostic.line ?? 0) + 1));\n const columnNumber = warnColor(String((diagnostic.column ?? 0) + 1));\n\n return `${ pathColor(filePath) }:${ lineNumber }:${ columnNumber }`;\n}\n\n/**\n * Appends formatted error metadata to a buffer array.\n *\n * @remarks\n * Internal helper that adds formatted code snippets and enhanced stack traces\n * to the provided buffer. Only processes errors that have metadata with formatted\n * code. Used by {@link appendIssue} to include additional error context.\n *\n * @param buffer - Array to append formatted lines to\n * @param error - The xBuild error containing metadata to format\n *\n * @since 2.0.0\n */\n\nexport function appendErrorMetadata(buffer: Array<string>, error: xBuildBaseError): void {\n if (!error.metadata?.formatCode) return;\n\n const codeLines = error.metadata.formatCode.split('\\n');\n const stackTrace = error.metadata.stack.map((stack) => stack.format).join('\\n ');\n\n buffer.push('');\n for (const line of codeLines) {\n buffer.push(`${ INDENT }${ line }`);\n }\n buffer.push('');\n buffer.push(`${ INDENT }Enhanced Stack Trace:`);\n buffer.push(` ${ stackTrace }`);\n}\n\n/**\n * Logs formatted error metadata to the console.\n *\n * @remarks\n * Outputs formatted code snippets and enhanced stack traces for xBuild errors\n * that contain metadata. Used by {@link logError} to provide detailed error\n * context in the console output.\n *\n * @param error - The xBuild error containing metadata to log\n *\n * @example\n * ```ts\n * const error = new xBuildBaseError('Build failed', {\n * formatCode: 'const x = undefined;\\nx.toString();',\n * stacks: ['at build.ts:45:12', 'at main.ts:10:5']\n * });\n *\n * logErrorMetadata(error);\n * // Outputs formatted code and stack trace to console\n * ```\n *\n * @see {@link logError}\n * @see {@link xBuildBaseError}\n *\n * @since 2.0.0\n */\n\nexport function logErrorMetadata(error: xBuildBaseError): void {\n if (!error.metadata?.formatCode) return;\n\n const formattedCode = error.metadata.formatCode\n .split('\\n')\n .map(line => `${ INDENT }${ line }`)\n .join('\\n');\n\n const stackTrace = error.metadata.stack.map(stack => stack.format).join('\\n ');\n\n console.log(`\\n${ formattedCode }\\n\\n${ INDENT }Enhanced Stack Trace:\\n ${ stackTrace }`);\n}\n\n/**\n * Formats a TypeScript diagnostic into a single-line string.\n *\n * @remarks\n * Internal helper that creates a formatted diagnostic string with location,\n * error code, and message. Used by {@link appendTypesError} to prepare\n * diagnostics for buffer output.\n *\n * @param diagnostic - The TypeScript diagnostic to format\n * @param symbol - The symbol to prefix the diagnostic with\n * @param codeColor - Color function for the error code\n *\n * @returns A formatted diagnostic string\n *\n * @since 2.0.0\n */\n\nexport function formatTypescriptDiagnostic(diagnostic: DiagnosticInterface, symbol: string, codeColor: typeof errorColor): string {\n const location = formatDiagnosticLocation(diagnostic);\n const diagnosticCode = codeColor(`TS${ diagnostic.code }`);\n const message = mutedColor(diagnostic.message);\n\n return `${ INDENT }${ symbol } ${ location } ${ textColor(ARROW_SYMBOL) } ${ diagnosticCode } ${ textColor(DASH_SYMBOL) } ${ message }`;\n}\n\n/**\n * Logs a formatted TypeScript diagnostic to the console.\n *\n * @remarks\n * Outputs a single TypeScript diagnostic with location, error code, and message\n * in a standardized format. Used internally for immediate console output of\n * diagnostics during type checking.\n *\n * @param diagnostic - The TypeScript diagnostic to log\n * @param symbol - The symbol to prefix the diagnostic with\n * @param codeColor - Color function for the error code, defaults to error color\n *\n * @since 2.0.0\n */\n\nexport function logTypescriptDiagnostic(diagnostic: DiagnosticInterface, symbol: string, codeColor: typeof errorColor = errorColor): void {\n const location = formatDiagnosticLocation(diagnostic);\n const diagnosticCode = codeColor(`TS${ diagnostic.code }`);\n const message = mutedColor(diagnostic.message);\n\n console.log(\n `${ INDENT }${ symbol } ${ location }`,\n textColor(ARROW_SYMBOL),\n `${ diagnosticCode } ${ textColor(DASH_SYMBOL) } ${ message }`\n );\n}\n\n/**\n * Appends formatted TypeScript type errors to a buffer array.\n *\n * @remarks\n * Internal helper that processes {@link TypesError} instances and adds their\n * diagnostics to the buffer. If no diagnostics exist, adds a generic warning\n * message. Returns the count of diagnostics processed.\n *\n * @param buffer - Array to append formatted lines to\n * @param error - The TypesError containing diagnostics to format\n * @param symbol - The symbol to prefix each diagnostic with\n *\n * @returns The number of diagnostics added to the buffer\n *\n * @since 2.0.0\n */\n\nexport function appendTypesError(buffer: Array<string>, error: TypesError, symbol: string): number {\n const diagnosticCount = error.diagnostics.length;\n\n if (diagnosticCount === 0) {\n buffer.push(`${ INDENT }${ warnColor(symbol) } ${ warnColor('TypesError') }: ${ mutedColor(error.message || 'Type checking warning') }`);\n\n return 1;\n }\n\n buffer.push('');\n for (const diagnostic of error.diagnostics) {\n buffer.push(formatTypescriptDiagnostic(diagnostic, warnColor(symbol), xterm.deepOrange));\n }\n\n return diagnosticCount;\n}\n\n/**\n * Appends a formatted generic issue to a buffer array.\n *\n * @remarks\n * Internal helper that processes non-TypesError issues and adds them to the buffer.\n * If the issue is an xBuildBaseError with metadata, also appends the error metadata.\n *\n * @param buffer - Array to append formatted lines to\n * @param issue - The issue to format and append\n * @param symbol - The symbol to prefix the issue with\n * @param color - Color function for the symbol and formatting\n *\n * @since 2.0.0\n */\n\nexport function appendGenericIssue(buffer: Array<string>, issue: IssueType, symbol: string, color: typeof errorColor): void {\n const title = `${ color(issue.name) }: ${ issue.message }`;\n buffer.push(`\\n${ INDENT }${ color(symbol) } ${ title }`);\n\n if (issue instanceof xBuildBaseError) {\n appendErrorMetadata(buffer, issue);\n }\n}\n\n/**\n * Appends a formatted build issue to a buffer array.\n *\n * @remarks\n * Processes different types of build issues (TypesError, xBuildBaseError, or\n * generic Error) and appends them to the provided buffer with appropriate\n * formatting. Returns the count of individual issues added, which may be\n * greater than 1 for TypesError containing multiple diagnostics.\n *\n * This function is used by {@link logBuildIssues} to prepare formatted issues\n * for batch console output.\n *\n * @param buffer - Array to append formatted issue lines to\n * @param issue - The build issue to format and append\n * @param symbol - The symbol to prefix the issue with (typically error or warning symbol)\n * @param color - Color function to apply to the symbol and formatting\n *\n * @returns The number of individual issues added to the buffer\n *\n * @example\n * ```ts\n * const buffer: string[] = [];\n * const error = new TypesError([diagnostic1, diagnostic2]);\n *\n * const count = appendIssue(buffer, error, ERROR_SYMBOL, errorColor);\n * // count = 2 (two diagnostics)\n * // buffer contains formatted diagnostic lines\n * ```\n *\n * @see {@link IssueType}\n * @see {@link TypesError}\n * @see {@link logBuildIssues}\n * @see {@link xBuildBaseError}\n *\n * @since 2.0.0\n */\n\nexport function appendIssue(buffer: Array<string>, issue: IssueType, symbol: string, color: typeof errorColor): number {\n if (issue instanceof TypesError) {\n return appendTypesError(buffer, issue, symbol);\n }\n\n appendGenericIssue(buffer, issue, symbol, color);\n\n return 1;\n}\n\n/**\n * Logs all build issues (errors or warnings) to the console in a formatted batch.\n *\n * @remarks\n * Processes an array of build issues and outputs them as a single formatted\n * block with a header showing the issue count. Uses buffering to prepare all\n * output before logging, ensuring clean and consistent console output.\n *\n * If no issues exist, this function returns early without logging anything.\n * The function handles different issue types (TypesError with multiple diagnostics,\n * xBuildBaseError with metadata, and generic errors) and formats them appropriately.\n *\n * @param issues - Array of build issues to log\n * @param issueType - Type label for the issues ('Errors' or 'Warnings')\n *\n * @example\n * ```ts\n * const errors = [\n * new xBuildBaseError('Build failed'),\n * new TypesError([diagnostic1, diagnostic2])\n * ];\n *\n * logBuildIssues(errors, 'Errors');\n * // Output:\n * // Errors (3)\n * // × Build failed\n * // × src/index.ts:10:5 → TS2304 — Cannot find name 'x'\n * // × src/index.ts:15:3 → TS2322 — Type mismatch\n * ```\n *\n * @see {@link IssueType}\n * @see {@link appendIssue}\n *\n * @since 2.0.0\n */\n\nexport function logBuildIssues(issues: Array<IssueType>, issueType: 'Errors' | 'Warnings'): void {\n if (issues.length === 0) return;\n if(issueType === 'Errors') process.exitCode = 1;\n\n const isError = issueType === 'Errors';\n const symbol = isError ? ERROR_SYMBOL : WARNING_SYMBOL;\n const color = isError ? errorColor : warnColor;\n\n let totalIssueCount = 0;\n const buffer: Array<string> = [ '' ];\n\n for (const issue of issues) {\n totalIssueCount += appendIssue(buffer, issue, symbol, color);\n }\n\n buffer[0] = `\\n ${ color(issueType) } (${ totalIssueCount })`;\n console.log(buffer.join('\\n'));\n}\n\n/**\n * Logs build output files with their sizes to the console.\n *\n * @remarks\n * Processes the esbuild metafile to extract output file information and\n * displays each output file with its size in a formatted list. The output\n * includes a header with the total count of output files.\n *\n * File sizes are automatically formatted using appropriate units (B, KB, MB)\n * for readability.\n *\n * @param metafile - The esbuild metafile containing output information\n *\n * @example\n * ```ts\n * const metafile: Metafile = {\n * outputs: {\n * 'dist/index.js': { bytes: 1024, inputs: {} },\n * 'dist/utils.js': { bytes: 512, inputs: {} }\n * }\n * };\n *\n * logBuildOutputs(metafile);\n * // Output:\n * // Outputs (2)\n * // → dist/index.js: 1.00 KB\n * // → dist/utils.js: 512 B\n * ```\n *\n * @see {@link Metafile}\n * @see {@link formatByteSize}\n *\n * @since 2.0.0\n */\n\nexport function logBuildOutputs(metafile: Metafile): void {\n const outputEntries = Object.entries(metafile.outputs);\n const outputCount = outputEntries.length;\n\n const buffer: Array<string> = [];\n buffer.push(`\\n ${ okColor('Outputs') } (${ outputCount })`);\n\n for (const [ outputPath, info ] of outputEntries) {\n const size = warnColor.dim(formatByteSize(info.bytes));\n buffer.push(`${ INDENT }${ infoColor(ARROW_SYMBOL) } ${ pathColor(outputPath) }: ${ size }`);\n }\n\n buffer.push('');\n console.log(buffer.join('\\n'));\n}\n\n/**\n * Logs an error or issue to the console with appropriate formatting.\n *\n * @remarks\n * Provides unified error logging with special handling for different error types:\n * - {@link AggregateError}: Recursively logs all contained errors\n * - {@link TypesError}: Logs TypeScript diagnostics with file locations\n * - {@link xBuildBaseError}: Logs error with enhanced metadata and stack traces\n * - Generic {@link Error}: Wraps in {@link VMRuntimeError} before logging\n * - Other types: Converts to string, wraps in VMRuntimeError, and logs\n *\n * This is the primary function for error output throughout the build system,\n * ensuring consistent error formatting and the appropriate detail level.\n *\n * @param issue - The error or issue to log\n *\n * @example\n * ```ts\n * try {\n * await build();\n * } catch (error) {\n * logError(error);\n * }\n * ```\n *\n * @example\n * ```ts\n * // Logs multiple TypeScript errors\n * const typesError = new TypesError([diagnostic1, diagnostic2]);\n * logError(typesError);\n * // Output:\n * // × src/index.ts:10:5 → TS2304 — Cannot find name 'x'\n * // × src/main.ts:20:3 → TS2322 — Type mismatch\n * ```\n *\n * @see {@link TypesError}\n * @see {@link VMRuntimeError}\n * @see {@link xBuildBaseError}\n * @see {@link logErrorMetadata}\n *\n * @since 2.0.0\n */\n\nexport function logError(issue: unknown): void {\n if (issue instanceof xBuildBaseError) {\n const title = `${ errorColor(issue.name) }: ${ issue.message }`;\n console.log(`\\n${ INDENT }${ errorColor(ERROR_SYMBOL) } ${ title }`);\n logErrorMetadata(issue);\n } else if (isBuildResultError(issue)) {\n for (const error of issue.errors) {\n logError(error);\n }\n } else if (issue instanceof TypesError) {\n for (const diagnostic of issue.diagnostics) {\n logTypescriptDiagnostic(diagnostic, errorColor(ERROR_SYMBOL));\n }\n } else if (issue instanceof Error) {\n logError(new VMRuntimeError(issue));\n } else {\n logError(new xBuildError(String(issue)));\n }\n}\n\n/**\n * Logs TypeScript diagnostics for a single variant to the console.\n *\n * @remarks\n * Internal helper that outputs diagnostics for a named variant with a\n * completion status. Shows an error symbol if diagnostics exist, or\n * an arrow symbol for successful completion.\n *\n * @param name - The variant name\n * @param diagnostics - Array of TypeScript diagnostics for this variant\n *\n * @since 2.0.0\n */\n\nexport function logTypeDiagnostic(name: string, diagnostics: Array<DiagnosticInterface>): void {\n const info = diagnostics.filter(d => d.category > DiagnosticCategory.Error);\n const errors = diagnostics.filter(d => d.category === DiagnosticCategory.Error);\n const warnings = diagnostics.filter(d => d.category === DiagnosticCategory.Warning);\n\n const nameColor = errors.length > 0 ? warnColor(name) : keywordColor(name);\n const statusSymbol = errors.length > 0 ? errorColor(ERROR_SYMBOL) : infoColor.dim(ARROW_SYMBOL);\n const status = createActionPrefix('completed', statusSymbol);\n\n console.log(`${ status } ${ nameColor }`);\n\n if(errors.length > 0) {\n process.exitCode = 1;\n console.log(`\\n ${ errorColor('Errors') } (${ errors.length })`);\n for (const diagnostic of errors) {\n logTypescriptDiagnostic(diagnostic, errorColor(ERROR_SYMBOL));\n }\n }\n\n if(warnings.length > 0) {\n console.log(`\\n ${ warnColor('Warnings') } (${ warnings.length })`);\n for (const diagnostic of warnings) {\n logTypescriptDiagnostic(diagnostic, warnColor(WARNING_SYMBOL));\n }\n }\n\n if(info.length > 0) {\n console.log(`\\n ${ pathColor('Info') } (${ info.length })`);\n for (const diagnostic of info) {\n logTypescriptDiagnostic(diagnostic, pathColor(ARROW_SYMBOL));\n }\n }\n\n console.log('');\n}\n\n/**\n * Logs TypeScript type diagnostics for all variants to the console.\n *\n * @remarks\n * Processes a record of variant names to diagnostic arrays and outputs\n * each variant's type checking results. Used to provide feedback after\n * TypeScript type checking operations across multiple build variants.\n *\n * Each variant is logged with its completion status and any diagnostics\n * found during type checking.\n *\n * @param diagnostics - Record mapping variant names to their diagnostic arrays\n *\n * @example\n * ```ts\n * const diagnostics = {\n * 'production': [diagnostic1, diagnostic2],\n * 'development': []\n * };\n *\n * logTypeDiagnostics(diagnostics);\n * // Output:\n * // [xBuild] → completed production\n * // × src/index.ts:10:5 → TS2304 — Cannot find name 'x'\n * // × src/main.ts:15:3 → TS2322 — Type mismatch\n * //\n * // [xBuild] → completed development\n * ```\n *\n * @see {@link DiagnosticInterface}\n *\n * @since 2.0.0\n */\n\nexport function logTypeDiagnostics(diagnostics: Record<string, Array<DiagnosticInterface>>): void {\n for (const [ name, errors ] of Object.entries(diagnostics)) {\n logTypeDiagnostic(name, errors);\n }\n}\n\n/**\n * Logs the start of a build operation for a variant.\n *\n * @remarks\n * Outputs a formatted message indicating that a build has started for the\n * specified variant. Used by the build lifecycle to provide feedback at\n * the beginning of build operations.\n *\n * @param context - Build context containing the variant name\n *\n * @example\n * ```ts\n * const context: BuildContextInterface = {\n * variantName: 'production',\n * // ... other properties\n * };\n *\n * logBuildStart(context);\n * // Output: [xBuild] → build production\n * ```\n *\n * @see {@link createActionPrefix}\n * @see {@link BuildContextInterface}\n *\n * @since 2.0.0\n */\n\nexport function logBuildStart({ variantName }: BuildContextInterface): void {\n console.log(`${ createActionPrefix('build') } ${ keywordColor(variantName) }`);\n}\n\n/**\n * Logs macro replacement information for a specific build variant.\n *\n * @remarks\n * Displays all macro transformations that occurred during the build process\n * for the specified variant. This function only outputs when verbose mode is enabled\n * in the configuration.\n *\n * Each replacement shows:\n * - The replacement value (if not 'undefined')\n * - The original source code as a comment\n *\n * Output is indented and color-coded for better readability.\n *\n * @param variant - The build variant name to retrieve replacements for\n * @param stage - The macro state interface containing replacement information\n *\n * @example\n * ```ts\n * const stage: MacrosStateInterface = {\n * defineMetadata: { ... },\n * replacementInfo: {\n * 'production': [\n * { source: \"$$ifdef('DEBUG', () => log())\", replacement: \"undefined\" },\n * { source: \"$$inline(() => 1 + 1)\", replacement: \"2\" }\n * ]\n * }\n * };\n *\n * logMacroReplacements('production', stage);\n * // Output (when verbose):\n * // [xBuild] macro replacement\n * // → 2 // $$inline(() => 1 + 1)\n * // → // $$ifdef('DEBUG', () => log())\n * ```\n *\n * @see {@link MacrosStateInterface}\n * @see {@link MacroReplacementInterface}\n *\n * @since 2.1.5\n */\n\nexport function logMacroReplacements(variant: string, stage: MacrosStateInterface): void {\n if (!inject(ConfigurationService).getValue().verbose) return;\n const replaceInfo = stage?.replacementInfo?.[variant];\n if (!replaceInfo || !Array.isArray(replaceInfo) || replaceInfo.length === 0) return;\n\n const prefix = INDENT + pathColor(ARROW_SYMBOL);\n const buffer: Array<string> = [ createActionPrefix(`macro ${ warnColor('replacement') }`) ];\n\n for (const { source, replacement } of replaceInfo) {\n const code = xterm.dim('// ' + source).replaceAll('\\n', `\\n${ INDENT }`);\n\n if (replacement && replacement !== 'undefined') {\n const resultCode = replacement.replaceAll('\\n', `\\n${ INDENT }`);\n buffer.push(`\\n${ prefix } ${ resultCode } ${ code }`);\n } else {\n buffer.push(`\\n${ prefix } ${ code }`);\n }\n }\n\n console.log(buffer.join('\\n'));\n}\n\n/**\n * Logs the completion of a build operation with results summary.\n *\n * @remarks\n * Outputs a comprehensive build summary including\n * - Completion status with build duration\n * - All errors encountered during the build\n * - All warnings encountered during the build\n * - Macro replacements (if verbose mode is enabled)\n * - Output files with their sizes (if build succeeded)\n *\n * The completion status shows an error symbol if the build failed (no metafile),\n * or an arrow symbol for successful builds. Build duration is displayed in\n * milliseconds.\n *\n * This is the primary function for providing build feedback to users and is\n * called by the build lifecycle at the end of each build operation.\n *\n * @param context - Result context containing variant name, duration, build result, and stage\n *\n * @example\n * ```ts\n * const context: ResultContextInterface = {\n * variantName: 'production',\n * duration: 1523,\n * buildResult: {\n * errors: [],\n * warnings: [warning1],\n * metafile: { outputs: { ... } }\n * },\n * stage: macroStage\n * };\n *\n * logBuildEnd(context);\n * // Output:\n * // [xBuild] → completed production in 1523 ms\n * //\n * // Warnings (1)\n * // • Unused variable warning\n * //\n * // [xBuild] macro replacement\n * // → 2 // $$inline(() => 1 + 1)\n * //\n * // Outputs (2)\n * // → dist/index.js: 45.23 KB\n * // → dist/utils.js: 12.45 KB\n * ```\n *\n * @see {@link logBuildIssues}\n * @see {@link logBuildOutputs}\n * @see {@link logMacroReplacements}\n * @see {@link ResultContextInterface}\n *\n * @since 2.0.0\n */\n\nexport function logBuildEnd({ variantName, duration, buildResult, stage }: ResultContextInterface): void {\n const { errors, warnings, metafile } = enhancedBuildResult(buildResult);\n const isSuccess = !!metafile;\n\n const nameColor = isSuccess ? keywordColor(variantName) : warnColor(variantName);\n const statusSymbol = isSuccess ? infoColor.dim(ARROW_SYMBOL) : errorColor(ERROR_SYMBOL);\n const status = createActionPrefix('completed', statusSymbol);\n\n console.log(`${ status } ${ nameColor } ${ xterm.dim(`in ${ duration } ms`) }`);\n\n logBuildIssues(errors, 'Errors');\n logBuildIssues(warnings, 'Warnings');\n\n if(errors.length || warnings.length) console.log(''); // add space line\n logMacroReplacements(variantName, <MacrosStateInterface> stage);\n\n if (isSuccess) {\n logBuildOutputs(metafile);\n } else {\n console.log(''); // add space line\n }\n}\n","/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xBuildBaseError } from '@errors/base.error';\n\n/**\n * Represents an error that occurs during VM runtime execution.\n *\n * Extends {@link xBuildBaseError} and adds support for wrapping native errors,\n * handling `AggregateError` instances, and preserving nested errors.\n *\n * @remarks\n * This class is designed to encapsulate runtime errors in a virtual machine context.\n * If the original error is already a `xJetBaseError`, it is returned as-is.\n * AggregateErrors are flattened into an array of `VMRuntimeError` instances.\n *\n * The formatted stack trace is automatically generated for both single and nested errors.\n *\n * @example\n * ```ts\n * try {\n * // Some VM execution code that throws\n * } catch (err) {\n * const vmError = new VMRuntimeError(err, { withFrameworkFrames: true });\n * console.error(vmError.formattedStack);\n * }\n * ```\n *\n * @since 2.0.0\n */\n\nexport class VMRuntimeError extends xBuildBaseError {\n /**\n * If the original error is an AggregateError, contains nested VMRuntimeError instances.\n *\n * @since 2.0.0\n */\n\n errors?: Array<VMRuntimeError> = [];\n\n /**\n * Creates a new `VMRuntimeError` instance from a native or xJetBaseError.\n *\n * @param originalError - The original error object thrown during execution.\n * @param options - Optional stack trace formatting options.\n *\n * @remarks\n * - If `originalError` is already an instance of `xJetBaseError`, it is returned as-is.\n * - If `originalError` is an `AggregateError`, each nested error is converted into a `VMRuntimeError`.\n * - The message and stack of the original error are preserved.\n * - The formatted stack trace is generated via {@link xBuildBaseError.reformatStack}.\n *\n * @since 2.0.0\n */\n\n constructor(private originalError: Error, options?: StackTraceInterface) {\n if (originalError instanceof xBuildBaseError) {\n return <VMRuntimeError> originalError;\n }\n\n // Pass the message to the base class Error\n super(originalError.message, 'VMRuntimeError');\n\n // Handle AggregateError\n if (this.originalError instanceof AggregateError && Array.isArray(this.originalError.errors)) {\n // Process nested errors\n this.errors = this.originalError.errors.map(error =>\n new VMRuntimeError(error, options)\n );\n }\n\n this.stack = this.originalError.stack;\n this.message = this.originalError.message;\n this.reformatStack(this.originalError, options);\n }\n\n /**\n * Custom Node.js inspect method for displaying the error in the console.\n *\n * @returns A string representation of the formatted stack trace, or\n * a concatenated list of nested errors if present.\n *\n * @remarks\n * Overrides the Node.js default inspection behavior.\n * If this instance contains nested errors, they are listed with their formatted stacks.\n *\n * @since 2.0.0\n */\n\n [Symbol.for('nodejs.util.inspect.custom')](): string | undefined {\n if (this.errors && this.errors.length > 0) {\n const errorList = this.errors.map(\n (error) => `${ error.formattedStack ?? error.stack }`\n ).join('');\n\n return `VMRuntimeError Contains ${ this.errors.length } nested errors:\\n${ errorList }\\n`;\n }\n\n return this.formattedStack || this.stack;\n }\n}\n","/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * Style token for successful/OK messages (green).\n *\n * @since 2.0.0\n */\n\nexport const okColor = xterm.hex('#80a36b');\n\n/**\n * Base text color token (neutral light).\n *\n * @since 2.0.0\n */\n\nexport const textColor = xterm.hex('#dcdfe4');\n\n/**\n * Style token for informational messages (blue).\n *\n * @since 2.0.0\n */\n\nexport const infoColor = xterm.hex('#5798cd');\n\n/**\n * Style token for warnings (yellow).\n *\n * @since 2.0.0\n */\n\nexport const warnColor = xterm.hex('#e5c07b');\n\n/**\n * Style token for file paths, URLs, and locations (cyan).\n *\n * @since 2.0.0\n */\n\nexport const pathColor = xterm.hex('#56b6c2');\n\n/**\n * Style token for errors and failures (red).\n *\n * @since 2.0.0\n */\n\nexport const errorColor = xterm.hex('#e06c75');\n\n/**\n * Style token for highlighted keywords and identifiers (purple).\n *\n * @since 2.0.0\n */\n\nexport const keywordColor = xterm.hex('#c678dd');\n\n/**\n * Style token for de-emphasized / secondary text (muted gray).\n *\n * @since 2.0.0\n */\n\nexport const mutedColor = xterm.hex('#a5a7ab');\n"],"mappings":"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","names":["rmSync","cwd","process","resolveError","SINGLETONS","INJECTABLES","isProviderUseClass","provider","isProviderUseFactory","isProviderUseValue","Injectable","options","target","providersIntoArgs","providers","args","scopeAgs","inject","token","metadata","instance","xterm","ts","resolve","closeSync","fstatSync","openSync","readFileSync","_FilesModel_decorators","_init","Injectable","FilesModel","path","resolvedPath","entry","cached","resolved","resolve","fd","openSync","mtimeMs","fstatSync","content","readFileSync","ts","closeSync","__decoratorStart","__decorateElement","__runInitializers","readFileSync","SourceService","resolve","toPosix","_FrameworkService_decorators","_init","Injectable","FrameworkService","position","source","sourceRoot","lowerCaseSource","path","resolve","key","error","map","sourceMapData","readFileSync","toPosix","sourceMap","SourceService","__decoratorStart","__decorateElement","__runInitializers","parseErrorStack","map","project","source","ObservableService","observer","value","result","err","distinctUntilChanged","compareFn","a","b","hasPrevious","previous","ObservableService","handler","observerOrNext","error","complete","observer","cleanup","err","operators","prev","op","SubjectService","ObservableService","observer","value","errors","o","err","e","BehaviorSubjectService","SubjectService","initialValue","observerOrNext","error","complete","observer","unsub","value","isObject","item","deepMerge","target","sources","source","key","sourceValue","targetValue","equals","a","b","strictCheck","deepEquals","hasKey","obj","val","i","aKeys","bKeys","DEFAULTS_COMMON_CONFIG","_ConfigurationService_decorators","_init","Injectable","ConfigurationService","initialConfig","DEFAULTS_COMMON_CONFIG","BehaviorSubjectService","deepMerge","selector","observer","map","distinctUntilChanged","prev","curr","equals","partial","mergedConfig","config","__decoratorStart","__decorateElement","__runInitializers","formatErrorCode","highlightCode","getSource","fileName","mapped","inject","FrameworkService","snapshot","FilesModel","code","lines","line","column","_bias","options","before","after","startLine","endLine","getErrorStack","raw","parseErrorStack","getErrorMetadata","framework","verbose","ConfigurationService","c","parsed","resolved","resolveError","path","frame","xterm","formatStack","metadata","name","message","notes","parts","note","stack","xBuildBaseError","message","name","error","options","getErrorMetadata","formatStack","formatErrors","reason","err","xBuildBaseError","metadata","getErrorMetadata","formatStack","process","join","yargs","hideBin","CLI_CONFIG_PATH","CLI_DEFAULT_OPTIONS","CLI_USAGE_EXAMPLES","_ArgvModule_decorators","_init","Injectable","ArgvModule","argv","yargs","CLI_DEFAULT_OPTIONS","argvOptions","userExtensions","parser","hideBin","originalShowHelp","consoleFunction","CLI_USAGE_EXAMPLES","command","description","__decoratorStart","__decorateElement","__runInitializers","readline","exec","cwd","readdirSync","matchesGlob","join","parseGlobs","globs","include","exclude","g","matchesAny","p","patterns","pattern","isDirectoryExcluded","relativePath","dirWithGlob","collectFilesFromGlob","baseDir","globs","include","exclude","parseGlobs","collected","rootDirLength","cwd","baseDirLength","hasExcludes","walk","dir","entries","readdirSync","len","i","entry","fullPath","join","relativeFromBase","isDirectoryExcluded","matchesAny","relativeFromRoot","lastDotIndex","keyPath","TypesError","_TypesError","message","diagnostics","xBuildError","xBuildBaseError","message","options","esBuildError","xBuildBaseError","message","options","getErrorMetadata","formatStack","normalizeMessageToError","msg","xBuildBaseError","TypesError","esBuildError","xBuildError","processEsbuildMessages","messages","target","error","enhancedBuildResult","source","isBuildResultError","http","https","extname","readFileSync","server_default","resolve","join","xterm","asciiLogo","bannerComponent","prefix","readdir","stat","readFile","xterm","ServerModule","config","dir","resolve","inject","FrameworkService","prefix","xterm","reject","err","address","req","res","options","readFileSync","join","defaultHandler","error","ext","requestPath","fullPath","stats","stat","msg","fileList","readdir","file","extname","activePath","segments","path","htmlResult","server_default","contentType","data","readFile","matchesGlob","stat","watch","normalize","join","WatchService","inject","FrameworkService","excludes","include","callback","changedFilesSet","watcher","watch","filename","fullPath","normalize","pattern","matchesGlob","absolutePath","join","stat","fn","delay","ts","build","writeFile","mkdir","readFile","ts","ts","dirname","relative","toPosix","SHEBANG_REGEX","EMPTY_EXPORT_REGEX","ORPHAN_COMMENT_REGEX","EXPORT_MODIFIER_REGEX","TRAILING_COMMENT_REGEX","removeShebang","content","removeEmptyExports","removeOrphanComments","removeExportModifiers","needsCleaning","cleanContent","calculateOutputPath","sourcePath","options","outDir","rootDir","declarationDir","outputBase","root","outputFileName","fullPath","_GraphModel_decorators","_init","Injectable","GraphModel","inject","FilesModel","ts","path","resolvedPath","source","languageService","languageHostService","self","version","cached","node","declarationSource","fileName","moduleSpecifier","currentFile","modulePath","resolvedFileName","target","elements","element","name","stmt","m","declarationText","sourceFile","namespaceImports","aliasRenames","keptStatements","nodeArray","printed","content","removeExportModifiers","cleanContent","original","local","namespace","importClause","moduleInfo","isExternal","namedBindings","exportClause","decl","__decoratorStart","__decorateElement","__runInitializers","ts","matchesGlob","relative","mkdir","writeFile","join","dirname","HeaderDeclarationBundle","BundlerService","languageService","languageHostService","inject","GraphModel","entryPoints","outdir","program","config","outputPath","entryFile","sourceFile","outputFile","join","source","output","entryDeclaration","content","mkdir","dirname","writeFile","entryPoint","visited","exportList","dependencyList","dependencyQueue","starExportModules","currentFile","declaration","starModule","dep","declarations","imports","module","name","moduleImports","names","statements","defaultImport","named","namespace","parts","fileName","exports","namespaceName","targetModule","nested","externalExports","HeaderDeclarationBundle","importStatements","uniqueExports","dirname","mkdir","writeFile","xterm","EmitterService","_EmitterService","languageService","languageHostService","outdir","program","xterm","config","filesToEmit","sourceFiles","i","file","source","outputPath","calculateOutputPath","version","currentVersion","sourceFile","options","output","content","fileName","cleanContent","mkdir","dirname","writeFile","ts","relative","dirname","LanguageHostService","_LanguageHostService","compilerOptions","ts","s","inject","FilesModel","options","filesCache","path","filesPath","file","encoding","extensions","exclude","include","depth","state","moduleName","containingFile","result","content","fileName","type","match","importPath","resolve","targetFile","relativePath","relative","dirname","config","paths","aliases","alias","_TypescriptService_decorators","_init","Injectable","_TypescriptService","configPath","config","host","service","EmitterService","BundlerService","filesList","program","files","file","cached","entryPoints","outdir","tsconfigPath","path","pattern","matchesGlob","relative","d","LanguageHostService","ts","diagnostic","result","line","character","__decoratorStart","__decorateElement","__runInitializers","TypescriptService","cwd","build","defaultBuildOptions","cwd","buildFiles","entryPoints","buildOptions","build","err","isBuildResultError","aggregateError","processEsbuildMessages","buildFromString","source","path","analyzeDependencies","entryPoint","relative","resolve","join","dirname","extractEntryPoints","baseDir","entryPoints","result","entry","collectFilesFromGlob","xBuildError","VariantService","name","lifecycle","buildConfig","argv","xBuildError","TypescriptService","config","error","inject","ConfigurationService","files","key","value","result","build","isBuildResultError","common","deepMerge","diagnostics","TypesError","errors","warnings","warning","d","ts","context","file","distPath","dirname","data","readFile","dataObject","source","join","writeFile","decl","shouldBundle","outDir","err","hooks","onStart","onResolve","onLoad","onEnd","onSuccess","type","mkdir","defineFromConfig","define","extractEntryPoints","variantConfig","commonConfig","filePath","lastDotIndex","esbuild","analysisOptions","metafile","analyzeDependencies","relativePath","relative","resolve","path","content","target","readFile","resolve","LifecycleProvider","variantName","argv","inject","FilesModel","handler","name","build","context","errors","id","err","names","warnings","hookContext","hook","result","buildResult","duration","args","hookResult","loader","filePath","resolve","snapshot","contents","readFile","ts","createSourceFile","highlightCode","ts","IFDEF_DIRECTIVE","transformToFunction","fnName","node","sourceFile","hasExport","prefix","transformFunctionLikeNode","asyncPrefix","m","params","p","returnType","body","getFunctionBody","bodyText","transformToIIFE","suffix","isDefinitionMet","defineName","directiveName","defines","isDefined","astDefineVariable","decl","init","state","defineArg","callbackArg","varName","astDefineCallExpression","outerSuffix","constPrefix","ts","createRequire","InlineError","xBuildBaseError","error","lineOffset","getErrorMetadata","formatStack","Script","createContext","sandboxExecute","code","sandbox","options","script","context","dirname","relative","evaluateCode","code","state","node","map","data","buildFromString","module","require","createRequire","context","createSandboxContext","result","sandboxExecute","err","handleExecutionError","fileName","dirname","mapText","start","line","inject","FrameworkService","error","InlineError","findFunctionByName","functionName","sourceFile","foundFunction","visit","ts","findFunctionInVariableStatement","decl","wrapInIIFE","getVariableKeyword","flags","extractExecutableCode","extractFromIdentifier","functionDeclaration","addFunctionNotFoundWarning","character","relativePath","relative","astInlineVariable","init","hasExport","arg","varKeyword","exportPrefix","varName","astInlineCallExpression","args","MACRO_FUNCTIONS","nodeContainsMacro","node","sourceFile","m","expectedArgCount","fnName","isVariableStatement","replacements","state","replacement","decl","suffix","call","init","ts","a","line","character","esBuildError","hasExport","astInlineVariable","astDefineCallExpression","astDefineVariable","isCallExpression","callExpr","astInlineCallExpression","macroCallExpression","callNode","astProcess","variant","fnToRemove","hasMacro","stack","kind","identifier","parent","parentText","key","children","i","replacementsArray","b","replacementInfo","start","end","highlightCode","transformerDirective","context","args","loader","stage","contents","variantName","options","argv","ext","tsOptions","createSourceFile","content","MACRO_PREFIX","IFDEF_REGEX","getLineAndColumn","text","name","file","index","line","i","startLinePosition","isCommentLine","content","lineStart","char1","char2","analyzeMacroMetadata","variant","context","metadata","warnings","filesModel","inject","FilesModel","defines","files","resolvedFile","match","matchIndex","fn","directive","define","isDefined","BuildService","argv","inject","ConfigurationService","callback","config","clearCache","LanguageHostService","files","instance","result","variant","names","ctx","targets","name","context","analyzeMacroMetadata","error","errors","err","dispose","obj1","obj2","key","xBuildError","lifecycle","LifecycleProvider","VariantService","transformerDirective","variantName","dependOn","visited","inStack","visit","chain","dep","deps","enhancedBuildResult","isBuildResultError","cached","promise","overwriteConfig","config","inject","ConfigurationService","patchConfig","platform","exit","stdin","stdout","xterm","EXIT_SIGNALS","KEY_MAPPINGS","COMMAND_MAP","generateHelp","activeUrl","shortcuts","prefix","xterm","addShortcut","key","description","KEY_MAPPINGS","clearScreen","repeatCount","stdout","readline","openInBrowser","url","command","COMMAND_MAP","platform","exec","handleKeypress","code","reload","help","EXIT_SIGNALS","exit","verbose","inject","ConfigurationService","cfg","patchConfig","init","stdin","helpString","existsSync","runInThisContext","createRequire","resolve","transpileOptions","configFileProvider","path","existsSync","inject","FilesModel","map","code","buildFiles","FrameworkService","createRequire","resolve","runInThisContext","config","relative","DiagnosticCategory","VMRuntimeError","_VMRuntimeError","xBuildBaseError","originalError","options","error","errorList","xterm","xterm","okColor","textColor","infoColor","warnColor","pathColor","errorColor","keywordColor","mutedColor","INDENT","KILOBYTE","MEGABYTE","DASH_SYMBOL","ARROW_SYMBOL","ERROR_SYMBOL","WARNING_SYMBOL","createActionPrefix","action","symbol","infoColor","prefix","formatByteSize","bytes","formatDiagnosticLocation","diagnostic","filePath","relative","lineNumber","warnColor","columnNumber","pathColor","appendErrorMetadata","buffer","error","codeLines","stackTrace","stack","line","logErrorMetadata","formattedCode","formatTypescriptDiagnostic","codeColor","location","diagnosticCode","message","mutedColor","textColor","logTypescriptDiagnostic","errorColor","appendTypesError","diagnosticCount","xterm","appendGenericIssue","issue","color","title","xBuildBaseError","appendIssue","TypesError","logBuildIssues","issues","issueType","isError","totalIssueCount","logBuildOutputs","metafile","outputEntries","outputCount","okColor","outputPath","info","size","logError","isBuildResultError","VMRuntimeError","xBuildError","logTypeDiagnostic","name","diagnostics","d","DiagnosticCategory","errors","warnings","nameColor","keywordColor","statusSymbol","status","logTypeDiagnostics","logBuildStart","variantName","logMacroReplacements","variant","stage","inject","ConfigurationService","replaceInfo","source","replacement","code","resultCode","logBuildEnd","duration","buildResult","enhancedBuildResult","isSuccess","DEFAULT_IGNORE_PATTERNS","WATCH_IGNORE_PATTERNS","configureEntryPoints","config","args","ignorePatterns","collectFilesFromGlob","cwd","applyCommandLineOverrides","variants","variant","collectWatchIgnorePatterns","startServer","urlString","serveDir","serverConfig","host","port","url","createActionPrefix","keywordColor","pathColor","ServerModule","executeBuild","buildService","distPath","join","rmSync","diagnostics","logTypeDiagnostics","result","name","errors","error","status","errorColor","ERROR_SYMBOL","logError","startWatchMode","watchService","WatchService","init","changedFiles","configFileProvider","prefix","mutedColor","main","bannerComponent","argvService","inject","ArgvModule","preConfig","userArgs","overwriteConfig","BuildService","logBuildEnd","logBuildStart"]}
|
|
1
|
+
{"version":3,"sources":["src/bash.ts","src/errors/uncaught.error.ts","src/providers/stack.provider.ts","src/models/files.model.ts","src/services/framework.service.ts","src/errors/base.error.ts","src/ui/screen.ui.ts","src/ui/interactive.ui.ts","src/ui/print.ui.ts","src/ui/banner.ui.ts","src/ui/color.ui.ts","src/constants/ui.constant.ts","src/services/configuration.service.ts","src/components/object.component.ts","src/constants/configuration.constant.ts","src/modules/typescript/services/typescript.service.ts","src/modules/typescript/models/declaration.model.ts","src/components/transformer.component.ts","src/modules/typescript/constants/typescript.constant.ts","src/modules/typescript/services/host.service.ts","src/components/glob.component.ts","src/constants/glob.constant.ts","src/modules/argv/argv.module.ts","src/modules/argv/constants/argv.constant.ts","src/modules/server/server.module.ts","src/modules/server/html/server.html","src/services/build.service.ts","src/errors/xbuild.error.ts","src/services/variant.service.ts","src/providers/log.provider.ts","src/directives/analyze.directive.ts","src/constants/macros.constant.ts","src/directives/define.directive.ts","src/directives/macros.directive.ts","src/directives/inline.directive.ts","src/services/vm.service.ts","src/services/transpiler.service.ts","src/constants/transpiler.constant.ts","src/components/entry-points.component.ts","src/constants/variant.constant.ts","src/providers/message.provider.ts","src/services/watch.service.ts","src/providers/config-file.provider.ts"],"sourceRoot":"https://github.com/remotex-labs/xBuild/tree/v3.0.1/","sourcesContent":["/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { ArgumentsInterface } from '@argv/interfaces/argv-module.interface';\nimport type { ConfigurationInterface } from '@interfaces/configuration.interface';\nimport type { ServerConfigurationInterface } from '@server/interfaces/server.interface';\nimport type { xBuildConfigInterface } from '@providers/interfaces/config-file-provider.interface';\n\n/**\n * Imports\n */\n\nimport { rmSync } from 'fs';\nimport '@errors/uncaught.error';\nimport { Screen } from '@ui/screen.ui';\nimport { bannerUi } from '@ui/banner.ui';\nimport { ArgvModule } from '@argv/argv.module';\nimport { inject } from '@remotex-labs/xinject';\nimport { FilesModel } from '@models/files.model';\nimport { ServerModule } from '@server/server.module';\nimport { startInteractive } from '@ui/interactive.ui';\nimport { BuildService } from '@services/build.service';\nimport { WatchService } from '@services/watch.service';\nimport { configFileProvider } from '@providers/config-file.provider';\n\n/**\n * Replaces the declared variants with one built from the entry points the command line named.\n *\n * @param config - Configuration read from the file, modified in place\n * @param args - Parsed command line the run was started with\n *\n * @remarks\n * Files named on the command line are a run of their own rather than an addition to what the file declares,\n * so the variants it declares are put aside, and a single variant named `argv` takes their place.\n * A command line naming no entry point leaves the configuration as the file wrote it.\n *\n * @example\n * ```ts\n * // xBuild src/index.ts\n * configureEntryPoints(config, args);\n * config.variants; // { argv: { esbuild: { entryPoints: [ 'src/index.ts' ] } } }\n * ```\n *\n * @since 3.0.0\n */\n\nexport function configureEntryPoints(config: xBuildConfigInterface, args: ArgumentsInterface): void {\n if (!args.entryPoints) return;\n\n config.variants = {\n argv: {\n esbuild: {\n entryPoints: args.entryPoints\n }\n }\n };\n}\n\n/**\n * Writes the flags the command line typed onto every variant.\n *\n * @param config - Configuration the overrides are written onto, modified in place\n * @param args - Parsed command line the run was started with\n *\n * @remarks\n * A flag left untyped is left alone rather than written as its default,\n * so what a configuration file states survives everything the command line did not say.\n * The overrides reach every variant, since a flag names what the run is for rather than which variant it is about.\n * Each output directory is also excluded from the watch as it is settled,\n * without which a build would write into the tree it is watching and set off the next one.\n *\n * @example\n * ```ts\n * // xBuild --outdir build --minify\n * applyCommandLineOverrides(config, args);\n * config.watch.filter; // [ '!build/**' ]\n * ```\n *\n * @since 3.0.0\n */\n\nexport function applyCommandLineOverrides(config: xBuildConfigInterface, args: ArgumentsInterface): void {\n const commonOutDir = config.common?.esbuild?.outdir ?? 'dist';\n const variants = Object.values(config.variants ?? {});\n if(commonOutDir) {\n config.watch?.filter?.push(`!${ commonOutDir }/**`);\n }\n\n for (const variant of variants) {\n if (args.types !== undefined) variant.types = args.types;\n if (args.outdir !== undefined) variant.esbuild.outdir = args.outdir;\n if (args.bundle !== undefined) variant.esbuild.minify = args.bundle;\n if (args.minify !== undefined) variant.esbuild.minify = args.minify;\n if (args.tsconfig !== undefined) variant.esbuild.tsconfig = args.tsconfig;\n if (args.platform !== undefined) variant.esbuild.platform = args.platform;\n if (args.declaration !== undefined) variant.declaration = args.declaration;\n if (args.failOnError !== undefined) {\n variant.types = { failOnError: args.failOnError };\n }\n\n if(variant.esbuild.outdir && variant.esbuild.outdir !== commonOutDir) {\n config.watch?.filter?.push(`!${ variant.esbuild.outdir }/**`);\n }\n }\n}\n\n/**\n * Clears the output of an earlier run where the command line asked for it, then builds.\n *\n * @param build - Service the variants are built through\n * @param args - Parsed command line the run was started with\n * @returns A promise settling once every variant asked for has finished\n *\n * @remarks\n * Bound to its two arguments and handed to the screen,\n * so a key or a watch starts the same build the command line asked for.\n * The directory cleared is `dist` rather than whatever the configuration writes to.\n * The `--build` flag decides which variants run, and naming none runs every variant the configuration declares.\n *\n * @since 3.0.0\n */\n\nasync function executeBuild(build: BuildService, args: ArgumentsInterface): Promise<void> {\n if (args.clean) rmSync('dist', { recursive: true, force: true });\n\n await build.build(args.build);\n}\n\n/**\n * Starts the development server where either the command line or the configuration asks for one.\n *\n * @param config - Configuration read for its `serve` block\n * @param args - Parsed command line the run was started with\n * @param screen - Screen the server reports through\n * @returns A promise settling once the server is listening, at once when none was asked for\n *\n * @remarks\n * `--serve` carries the directory to serve, so asking for a server and choosing what it serves are the one flag,\n * and a configuration that starts one of its own is honored even where the flag is absent.\n * The directory falls back to the configured one and then to `dist`, which is where a build writes by default.\n * The server reports through the screen rather than to the console,\n * so its address reaches the status line and its requests are held to the level the run reports at.\n *\n * @example\n * ```ts\n * // xBuild --serve dist\n * await startServer(config, args, screen);\n * // [xBuild] → serve http://localhost:3000\n * ```\n *\n * @see ServerModule\n * @since 3.0.0\n */\n\nexport async function startServer(config: xBuildConfigInterface, args: ArgumentsInterface, screen: Screen): Promise<void> {\n const shouldStartServer = (args.serve ?? false) !== false || config.serve?.start;\n if (!shouldStartServer) return;\n\n const serveDir = config.serve?.dir || args.serve || 'dist';\n const server = new ServerModule(<ServerConfigurationInterface> { ...config.serve }, serveDir);\n server.subscribe(screen.serverEvent.bind(screen));\n\n await server.start();\n}\n\n/**\n * Watches the project, rebuilds on a change, and takes the terminal for the shortcuts.\n *\n * @param buildService - Service the rebuilds run through\n * @param config - Configuration read for its `watch` block, and replaced when its file changes\n * @param args - Parsed command line the run was started with\n * @param screen - Screen the rebuilds are announced on\n * @returns A promise settling once the keys are listened for, at once when no watch was asked for\n *\n * @remarks\n * A run is watched where `--watch` asked for it, and also where a server is serving,\n * since output nobody rebuilds is not worth serving.\n * A change refreshes the file model before anything is rebuilt,\n * so the rebuild reads the files as they now are rather than as they were read the first time.\n * Reloading the TypeScript configuration belongs to the screen rather than to the watch,\n * which puts a rebuild started by a key on the same footing as one started by a change.\n * The configuration file is watched by its own version rather than by its path,\n * so an edit to it is reparsed and reapplied while every other change goes straight to a rebuild.\n * The shortcuts are listened for last, since they take the last row of the terminal,\n * and a run that never reaches here leaves the terminal as it found it.\n *\n * @example\n * ```ts\n * // xBuild --watch\n * await startWatchMode(build, config, args, screen);\n * // [xBuild] ↻ rebuild 2 files changed\n * ```\n *\n * @see WatchService\n * @see startInteractive\n *\n * @since 3.0.0\n */\n\nexport async function startWatchMode(\n buildService: BuildService, config: xBuildConfigInterface, args: ArgumentsInterface, screen: Screen\n): Promise<void> {\n const shouldWatch = args.watch || args.serve !== undefined || config.serve?.start;\n if (!shouldWatch) return;\n\n const files = inject(FilesModel);\n let configVersion = files.touch(args.config!).version;\n\n const watchService = new WatchService(process.cwd(), config.watch);\n watchService.subscribe(async (changedFiles) => {\n files.refreshAll();\n\n if(configVersion !== files.touch(args.config!).version) {\n configVersion = files.touch(args.config!).version;\n const config = await configFileProvider(args.config!);\n applyCommandLineOverrides(config, args);\n buildService.configuration = config;\n }\n\n const count = Object.keys(changedFiles).length;\n await screen.rebuild(`${ count } ${ count === 1 ? 'file' : 'files' } changed`);\n });\n\n await startInteractive(screen);\n}\n\n/**\n * Runs the command line from the banner to the last build.\n *\n * @returns A promise settling once the build has run, or never returning where a check ended the process\n *\n * @remarks\n * The configuration file is found before anything else is parsed, since it is what declares the rest of the flags,\n * and the full parse is written back onto the arguments the provider was handed.\n * The screen is built around the build itself, so a key pressed later starts the same run the command line asked for.\n * A run asking for a type check reports it and leaves from there, since nothing is built for one.\n * The server and the watch are started before the first build,\n * so a rebuild reaches a screen, and the output is served as soon as it is written.\n *\n * @since 3.0.0\n */\n\nasync function main(): Promise<void> {\n console.log(bannerUi());\n\n // Parse configuration\n const argvService = inject(ArgvModule);\n const preConfig = argvService.parseConfigFile(process.argv);\n\n const args = {} as ArgumentsInterface;\n const config = await configFileProvider(preConfig.config, args);\n\n // Configure build\n configureEntryPoints(config, args);\n applyCommandLineOverrides(config, args);\n\n const buildService = new BuildService(config as ConfigurationInterface, args);\n const screen = inject(Screen, executeBuild.bind({}, buildService, args));\n buildService.subscribe(screen.buildEvent.bind(screen));\n\n if (args.typeCheck) {\n screen.diagnostics(await buildService.typeChack(args.build));\n }\n\n // Execute build pipeline\n await startServer(config, args, screen);\n await startWatchMode(buildService, config, args, screen);\n await executeBuild(buildService, args);\n}\n\nawait main();\n","/**\n * Imports\n */\n\nimport process from 'node:process';\nimport { xBuildBaseError } from '@errors/base.error';\nimport { formatStack, getErrorMetadata } from '@providers/stack.provider';\n\n/**\n * Prints whatever reached a global handler the way the framework prints its own errors.\n *\n * @param reason - Error, aggregate error, or any other value that escaped\n *\n * @remarks\n * An {@link xBuildBaseError} already carries its resolved block, so it goes to the console untouched rather than\n * being resolved a second time.\n * Any other `Error` is resolved here with the framework and native frames kept,\n * since a value that got this far offers no other clue about where it came from.\n * An {@link AggregateError} is announced once and then unwrapped, each of its errors going through the same choice.\n * A value that is not an error is printed as it stands.\n *\n * @example\n * ```ts\n * formatErrors(new Error('connect ECONNREFUSED')); // heading, snippet and resolved trace\n * formatErrors(new xBuildError('bad config')); // the block the error already carries\n * formatErrors('not an error at all'); // 'not an error at all'\n * ```\n *\n * @see formatStack\n * @see xBuildBaseError\n * @see getErrorMetadata\n *\n * @since 2.0.0\n */\n\nexport function formatErrors(reason: unknown): void {\n if (reason instanceof AggregateError) {\n console.error('AggregateError:', reason.message);\n for (const err of reason.errors) {\n if (err instanceof Error && !(err instanceof xBuildBaseError)) {\n const metadata = getErrorMetadata(err, { withFrameworkFrames: true, withNativeFrames: true });\n console.error(formatStack(metadata, err.name, err.message));\n } else {\n console.error(err);\n }\n }\n\n return;\n }\n\n if (reason instanceof Error && !(reason instanceof xBuildBaseError)) {\n const metadata = getErrorMetadata(reason, { withFrameworkFrames: true, withNativeFrames: true });\n console.error(formatStack(metadata, reason.name, reason.message));\n } else {\n console.error(reason);\n }\n}\n\n/**\n * Prints an exception that escaped every `try` and leaves the process with exit code `2`.\n *\n * @remarks\n * Registered as a side effect of importing this file, which is why the CLI entry point imports it on its first line -\n * anything thrown while the later imports evaluate is already covered.\n * Node leaves the process in an undefined state once an exception gets this far, so the handler prints and exits\n * instead of letting the build carry on.\n *\n * @example\n * ```ts\n * import '@errors/uncaught.error';\n * throw new Error('unreachable state'); // the resolved block, then exit code 2\n * ```\n *\n * @see formatErrors\n * @see {@link https://nodejs.org/api/process.html#event-uncaughtexception | process 'uncaughtException'}\n *\n * @since 2.0.0\n */\n\nprocess.on('uncaughtException', (reason: unknown) => {\n formatErrors(reason);\n process.exit(2);\n});\n\n/**\n * Prints a rejection nobody awaited and leaves the process with exit code `2`.\n *\n * @remarks\n * Registered alongside the exception handler, since an unawaited rejection ends the build just as surely and would\n * otherwise print Node's own warning without any source resolution.\n * The exit code matches the one used for uncaught exceptions: both mean the build died on an unhandled failure, and\n * nothing downstream needs to tell them apart.\n *\n * @example\n * ```ts\n * import '@errors/uncaught.error';\n * Promise.reject(new Error('write after end')); // the resolved block, then exit code 2\n * ```\n *\n * @see formatErrors\n * @see {@link https://nodejs.org/api/process.html#event-unhandledrejection | process 'unhandledRejection'}\n *\n * @since 2.0.0\n */\n\nprocess.on('unhandledRejection', (reason: unknown) => {\n formatErrors(reason);\n process.exit(3);\n});\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { PartialMessage } from 'esbuild';\nimport type { SourceService } from '@remotex-labs/xmap';\nimport type { ParsedStackTraceInterface } from '@remotex-labs/xmap/parser.component';\nimport type { StackTraceInterface, ResolveMetadataInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { inject } from '@remotex-labs/xinject';\nimport { FilesModel } from '@models/files.model';\nimport { resolveError } from '@remotex-labs/xmap';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { FrameworkService } from '@services/framework.service';\nimport { parseErrorStack } from '@remotex-labs/xmap/parser.component';\nimport { formatErrorCode } from '@remotex-labs/xmap/formatter.component';\nimport { highlightCode } from '@remotex-labs/xmap/highlighter.component';\n\n/**\n * Returns a source resolver for a file, from its source map when one is registered and from its cached text otherwise.\n *\n * @param fileName - Path of the file a stack frame points at, relative or absolute\n * @returns The resolver for that file, or `null` when the file has neither a map nor cached text\n *\n * @remarks\n * A registered map wins since it resolves back to the authored file rather than to the emitted one.\n * Without a map the cached text stands in through a minimal resolver that slices the surrounding lines as its\n * code window, so an unmapped file still prints a snippet.\n * That window spans three lines either side unless the caller asks for a different span and is clamped to the\n * bounds of the file.\n * `startLine` and `endLine` come back as 1-based line numbers rather than as indexes into the text,\n * which is how {@link formatErrorCode} reads them, so a printed number labels the line it belongs to.\n * The line passes through as it arrived, while the column comes back one higher than it was given.\n *\n * @example\n * ```ts\n * getSource('dist/index.js'); // SourceService - the registered map\n * getSource('src/index.ts')?.getPositionWithCode(10, 4); // line 10, column 5, lines 7-13 as code\n * getSource('missing.ts'); // null\n * ```\n *\n * @see SourceService\n * @see FilesModel.touch\n * @see FrameworkService.getSourceMap\n *\n * @since 2.0.0\n */\n\nexport function getSource(fileName: string = ''): SourceService | null {\n const framework = inject(FrameworkService);\n const mapped = framework.getSourceMap(fileName);\n if (mapped) return mapped;\n\n const snapshot = inject(FilesModel).touch(fileName);\n const code = snapshot.snapshot?.text;\n\n if (!snapshot || !code) return null;\n const lines = code.split('\\n');\n\n return {\n getPositionWithCode: (line, column, _bias, options) => {\n const after = options?.linesAfter ?? 3;\n const before = options?.linesBefore ?? 3;\n\n // both bounds are 1-based line numbers, so only the slice start converts to an index\n const startLine = Math.max(line - before, 1);\n const endLine = Math.min(line + after, lines.length);\n\n return {\n line,\n name: null,\n code: lines.slice(startLine - 1, endLine).join('\\n'),\n source: fileName,\n column: column,\n endLine,\n startLine,\n sourceRoot: null,\n sourceIndex: -1,\n generatedLine: -1,\n generatedColumn: -1\n };\n }\n } as SourceService;\n}\n\n/**\n * Brings an error and an esbuild message to the same shape - a name, a message, and a list of frames.\n *\n * @param raw - Thrown error, or the message esbuild reported for a failed build\n * @returns The parsed trace, with an empty frame list when there is nothing to point at\n *\n * @remarks\n * An `Error` is parsed from its own stack text, whether it arrives on its own or wrapped as the `detail` of an\n * esbuild message.\n * A plain esbuild message carries no stack, so its location becomes the single frame of the trace, flagged as\n * ordinary code: not eval, not async, not native, and not a constructor call.\n * A message without a location resolves to no frames at all, which leaves the caller with the text alone.\n *\n * @example\n * ```ts\n * getErrorStack(new Error('boom')).stack.length; // 12 - frames parsed from error.stack\n *\n * getErrorStack({ text: 'Unexpected token', location: { file: 'src/index.ts', line: 4, column: 2 } }).stack;\n * // [ { source: '@src/index.ts', fileName: 'src/index.ts', line: 4, column: 2, ... } ]\n *\n * getErrorStack({ text: 'Could not resolve module' }).stack; // []\n * ```\n *\n * @see parseErrorStack\n * @see ParsedStackTraceInterface\n *\n * @since 2.0.0\n */\n\nexport function getErrorStack(raw: Partial<PartialMessage> | Error): ParsedStackTraceInterface {\n if (raw instanceof Error) return parseErrorStack(raw);\n if (raw.detail instanceof Error) return parseErrorStack(raw.detail);\n\n if (!raw.location) {\n return { stack: [], name: 'esBuildMessage', message: raw.text ?? '', rawStack: '' };\n }\n\n return {\n name: 'esBuildMessage',\n message: raw.text ?? '',\n rawStack: '',\n stack: [\n {\n source: `@${ raw.location.file }`,\n line: raw.location.line,\n column: raw.location.column || 1,\n fileName: raw.location.file,\n eval: false,\n async: false,\n native: false,\n constructor: false\n }\n ]\n };\n}\n\n/**\n * Resolves an error back to its authored sources and picks the code window to print with it.\n *\n * @param raw - Thrown error, or the message esbuild reported for a failed build\n * @param options - Frame selection and code window size, as {@link resolveError} takes them\n * @param verbose - Whether native frames stay in the resolved stack\n * @returns The resolved trace, carrying `formatCode` when a frame supplied a code window\n *\n * @remarks\n * Every frame resolves through {@link getSource}, so a mapped frame points at the authored file and an unmapped\n * one falls back to the cached text of the emitted file.\n * `verbose` and `withFrameworkFrames` each admit native frames to the stack, while `withFrameworkFrames` alone\n * decides whether a framework frame may supply the code window.\n * The window is taken from the first frame that carries code, highlighted and marked at that position, and is\n * left unset when no frame carries any - a resolve against sources that are gone prints as a bare trace.\n *\n * @example\n * ```ts\n * const metadata = getErrorMetadata(error, { linesBefore: 2, linesAfter: 2 });\n * metadata.stack[0].format; // 'at run src/index.ts:12:8'\n * metadata.formatCode; // lines 10-14, highlighted, with column 8 marked in bright pink\n * ```\n *\n * @see resolveError\n * @see getErrorStack\n * @see StackTraceInterface\n * @see ResolveMetadataInterface\n *\n * @since 3.0.0\n */\n\nexport function getErrorMetadata(raw: PartialMessage | Error, options?: StackTraceInterface, verbose: boolean = false): ResolveMetadataInterface {\n const framework = inject(FrameworkService);\n const parsed = getErrorStack(raw);\n const resolved: ResolveMetadataInterface = resolveError(parsed, {\n ...options,\n withNativeFrames: verbose || (options?.withFrameworkFrames ?? false),\n getSource(path: string): SourceService | null {\n return getSource(path);\n }\n });\n\n resolved.stack.filter(frame => {\n if (!(options?.withFrameworkFrames ?? false) && framework.isFrameworkFile(frame)) return false;\n if(!resolved.formatCode && frame.code) {\n resolved.formatCode = formatErrorCode(\n {\n code: highlightCode(frame.code),\n line: frame.line ?? 1,\n column: frame.column ?? 1,\n startLine: frame.stratLine ?? 1\n },\n { color: xterm.brightPink }\n );\n }\n });\n\n return resolved;\n}\n\n/**\n * Renders resolved metadata as the block that gets printed to the terminal.\n *\n * @param metadata - Resolved trace, as {@link getErrorMetadata} returns it\n * @param name - Name to head the block with, such as `TypeError` or `esBuildMessage`\n * @param message - Message to head the block with\n * @param notes - Extra lines esbuild attached to the message, printed in gray under the heading\n * @returns The block, ready to write as-is\n *\n * @remarks\n * The heading is always written, the code window and the trace only when the metadata holds them, so an error\n * resolved against missing sources still prints as a single readable line.\n * Coloring of the window and of each frame is left as {@link getErrorMetadata} produced it - nothing here is\n * highlighted a second time.\n *\n * @example\n * ```ts\n * formatStack(metadata, 'TypeError', 'x is not a function');\n * //\n * // TypeError: x is not a function\n * //\n * // 11 | x();\n * // | ^\n * //\n * // Enhanced Stack Trace:\n * // at run src/index.ts:11:2\n * ```\n *\n * @see xterm\n * @see getErrorMetadata\n * @see ResolveMetadataInterface\n *\n * @since 2.0.0\n */\n\nexport function formatStack(metadata: ResolveMetadataInterface, name: string, message: string, notes: PartialMessage['notes'] = []): string {\n const parts = [ `\\n${ name }: ${ xterm.lightCoral(message) }` ];\n for (const note of notes ?? []) {\n if(note.text) parts.push('\\n ' + xterm.gray(note.text));\n }\n\n if (metadata.formatCode) parts.push(`\\n\\n${ metadata.formatCode }`);\n if (metadata.stack.length) {\n parts.push(`\\n\\nEnhanced Stack Trace:\\n ${ metadata.stack.map(stack => stack.format).join('\\n ') }\\n`);\n }\n\n return parts.join('');\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Stats } from 'fs';\nimport type { TextChangeRange } from 'typescript';\nimport type { FileSnapshotInterface, ScriptSnapshotType } from './interfaces/files-model.interface';\n\n/**\n * Imports\n */\n\nimport { readFileSync, statSync } from 'fs';\nimport { resolve } from '@remotex-labs/xmap';\nimport { Injectable } from '@remotex-labs/xinject';\n\n/**\n * In-memory cache of file contents keyed by resolved absolute path.\n *\n * @remarks\n * Backs the TypeScript language service, which asks for a script version on every request and only reparses when\n * that version changes.\n * Content is read once and re-read only when the modification time moves,\n * so repeated lookups of an unchanged file cost a map read.\n * Reach for {@link touch} when any cached content will do,\n * {@link refresh} when the file may have changed on disk or when a watcher already carries its `Stats`,\n * and {@link refreshAll} to catch what the watcher failed to report.\n *\n * @example\n * ```ts\n * const model = inject(FilesModel);\n *\n * model.touch('src/index.ts').version; // 1 - read from disk\n * model.touch('src/index.ts').version; // 1 - served from the cache\n * model.refresh('src/index.ts').version; // 2 - the file changed on disk\n * model.clear(); // every entry dropped\n * ```\n *\n * @see FileSnapshotInterface\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class FilesModel {\n /**\n * Memoized mapping from an input path to its resolved absolute form.\n *\n * @remarks\n * Kept apart from {@link cache} because several input paths can resolve to the same absolute path,\n * and resolution is repeated far more often than content changes.\n *\n * @since 3.0.0\n */\n\n private readonly resolved = new Map<string, string>();\n\n /**\n * Entries keyed by resolved absolute path.\n *\n * @remarks\n * Holds one {@link FileSnapshotInterface} per tracked path, including paths that carry no readable file.\n *\n * @since 3.0.0\n */\n\n private readonly cache = new Map<string, FileSnapshotInterface>();\n\n /**\n * Drops every cached entry and every memoized path.\n *\n * @remarks\n * Leaves the model in its initial state, so the next request re-reads from disk and restarts versions at `1`.\n *\n * @example\n * ```ts\n * model.touch('src/index.ts');\n * model.clear();\n * model.getSnapshot('src/index.ts'); // undefined\n * ```\n *\n * @since 2.0.0\n */\n\n clear(): void {\n this.cache.clear();\n this.resolved.clear();\n }\n\n /**\n * Returns the cached entry for a path without touching the filesystem.\n *\n * @param path - Filesystem path, relative or absolute\n * @returns The cached entry, or `undefined` when the path was never tracked\n *\n * @remarks\n * A pure cache read: it never reads or stats the file, so an untracked path stays untracked.\n * Use {@link touch} to track the path instead.\n *\n * @example\n * ```ts\n * model.getSnapshot('src/index.ts'); // undefined - never tracked\n * model.touch('src/index.ts');\n * model.getSnapshot('src/index.ts'); // { mtimeMs: 1754000000000, version: 1, snapshot: { ... } }\n * ```\n *\n * @see touch\n * @since 2.0.0\n */\n\n getSnapshot(path: string): FileSnapshotInterface | undefined {\n return this.cache.get(this.resolve(path));\n }\n\n /**\n * Returns the entry for a path, reading the file when it is not tracked yet.\n *\n * @param path - Filesystem path, relative or absolute\n * @param encoding - Encoding used when the file is read, defaulting to `utf-8`\n * @returns The entry for the path, cached or newly created\n *\n * @remarks\n * A tracked path is returned as it stands, without a `stat` call, however stale it may be.\n * Use {@link refresh} when the file may have changed since it was cached.\n *\n * @example\n * ```ts\n * model.touch('src/index.ts').version; // 1 - read from disk\n * model.touch('src/index.ts').version; // 1 - served from the cache, no stat\n * ```\n *\n * @see refresh\n * @since 3.0.0\n */\n\n touch(path: string, encoding?: BufferEncoding): FileSnapshotInterface {\n const target = this.resolve(path);\n\n return this.cache.get(target) ?? this.sync(target, this.stat(target), encoding);\n }\n\n /**\n * Synchronizes a path with the filesystem and returns its entry.\n *\n * @param path - Filesystem path, relative or absolute\n * @param stats - Already obtained `Stats` for the path, sparing a `stat` call\n * @param encoding - Encoding used when the file is read, defaulting to `utf-8`\n * @returns The entry for the path, rebuilt only when the file actually changed\n *\n * @remarks\n * The content is re-read when the modification time differs from the cached one,\n * so calling this on an unchanged file leaves its version intact.\n * A path that is missing or is not a regular file yields an entry with an `undefined` snapshot.\n *\n * @example\n * ```ts\n * model.touch('src/index.ts').version; // 1\n * model.refresh('src/index.ts').version; // 1 - mtime unchanged\n * model.refresh('src/index.ts').version; // 2 - the file was written to\n * ```\n *\n * @see touch\n * @since 3.0.0\n */\n\n refresh(path: string, stats?: Stats, encoding?: BufferEncoding): FileSnapshotInterface {\n const target = this.resolve(path);\n\n return this.sync(target, stats ?? this.stat(target), encoding);\n }\n\n /**\n * Synchronizes a set of paths, or every path already tracked.\n *\n * @param paths - Paths to synchronize, defaulting to everything in the cache\n *\n * @remarks\n * The safety net under file watching: a change that goes unreported leaves an entry stale with nothing to\n * announce it - the version never moves,\n * so the language service is never told to reparse, and the build keeps compiling text that is no longer on disk.\n * Sweeping asks the filesystem rather than the watcher,\n * so a missed event costs a needless rebuild at worst rather than a wrong one.\n * Every path gets a `stat`, and only the ones whose time moved are read again.\n * The keys it walks are already resolved,\n * so re-synchronizing them writes back over the same keys and cannot extend the walk.\n * A tracked path that is still missing keeps the entry and the version it had,\n * so repeated sweeps do not inflate the versions of files that were deleted.\n *\n * @example\n * ```ts\n * model.refreshAll([ 'src/index.ts' ]); // that one path\n * model.refreshAll(); // every tracked path, re-read where it changed\n * ```\n *\n * @see refresh\n * @since 3.0.0\n */\n\n refreshAll(paths?: Array<string>): void {\n const pathList = paths ?? this.cache.keys();\n for (const path of pathList) {\n this.refresh(path);\n }\n }\n\n /**\n * Normalizes a path to its absolute form.\n *\n * @param path - Filesystem path, relative or absolute\n * @returns Absolute path with forward slashes\n *\n * @remarks\n * The result is memoized per input string, since the same paths are resolved on every cache lookup.\n *\n * @example\n * ```ts\n * model.resolve('src/index.ts'); // 'D:/project/src/index.ts'\n * ```\n *\n * @since 2.0.0\n */\n\n resolve(path: string): string {\n let target = this.resolved.get(path);\n if (target === undefined) this.resolved.set(path, target = resolve(path));\n\n return target;\n }\n\n /**\n * Brings the entry for a resolved path in line with the given filesystem state.\n *\n * @param target - Resolved absolute path\n * @param info - `Stats` for the path, or `undefined` when it does not exist\n * @param encoding - Encoding used when the file is read, defaulting to `utf-8`\n * @returns The entry for the path, reused when nothing changed\n *\n * @remarks\n * A path that is not a regular file keeps its already empty entry untouched,\n * so repeated events for a missing path do not inflate its version.\n * A file whose modification time matches the cached one is left as is, and the content is not read.\n *\n * @since 3.0.0\n */\n\n private sync(target: string, info: Stats | undefined, encoding: BufferEncoding = 'utf-8'): FileSnapshotInterface {\n const entry = this.cache.get(target);\n\n if (!info?.isFile()) {\n if (entry && !entry.snapshot) return entry;\n\n return this.store(target, { mtimeMs: 0, snapshot: undefined, version: (entry?.version ?? 0) + 1 });\n }\n\n if (entry?.mtimeMs === info.mtimeMs) return entry;\n\n return this.store(target, {\n mtimeMs: info.mtimeMs,\n version: (entry?.version ?? 0) + 1,\n snapshot: this.snapshot(readFileSync(target, encoding))\n });\n }\n\n /**\n * Computes the span that differs between two versions of a text.\n *\n * @param oldText - Text the language service last parsed\n * @param newText - Text that replaces it\n * @returns The replaced span in `oldText` together with the length of its replacement\n *\n * @remarks\n * Narrows the change by trimming the shared prefix and the shared suffix,\n * which lets the language service reuse the untouched parts of the syntax tree.\n * The suffix scan stops at the prefix boundary, so the two never overlap on a text that shrank.\n *\n * @since 3.0.0\n */\n\n private changeRange(oldText: string, newText: string): TextChangeRange {\n const oldLength = oldText.length;\n const newLength = newText.length;\n const max = Math.min(oldLength, newLength);\n\n let prefix = 0;\n while (prefix < max && oldText.charCodeAt(prefix) === newText.charCodeAt(prefix)) prefix++;\n\n let suffix = 0;\n while (suffix < max - prefix && oldText.charCodeAt(oldLength - 1 - suffix) === newText.charCodeAt(newLength - 1 - suffix)) suffix++;\n\n return {\n span: { start: prefix, length: oldLength - prefix - suffix },\n newLength: newLength - prefix - suffix\n };\n }\n\n /**\n * Wraps file content in a script snapshot.\n *\n * @param text - Content read from disk\n * @returns A snapshot exposing the content both as `text` and through the `IScriptSnapshot` methods\n *\n * @remarks\n * `getChangeRange` closes over this text as the new version and delegates to {@link changeRange},\n * so the language service can diff against any earlier snapshot it still holds.\n *\n * @since 3.0.0\n */\n\n private snapshot(text: string): ScriptSnapshotType {\n return {\n text,\n getText: (start, end): string => text.slice(start, end),\n getLength: (): number => text.length,\n getChangeRange: (previous):\n TextChangeRange => this.changeRange(previous.getText(0, previous.getLength()), text)\n };\n }\n\n /**\n * Writes an entry to the cache and hands it back.\n *\n * @param target - Resolved absolute path\n * @param entry - Entry to store under that path\n * @returns The stored entry\n *\n * @remarks\n * Exists so {@link sync} can store and return in a single expression.\n *\n * @since 3.0.0\n */\n\n private store(target: string, entry: FileSnapshotInterface): FileSnapshotInterface {\n this.cache.set(target, entry);\n\n return entry;\n }\n\n /**\n * Reads the filesystem state of a path.\n *\n * @param path - Resolved absolute path\n * @returns The `Stats` for the path, or `undefined` when it does not exist\n *\n * @remarks\n * A missing path is an ordinary outcome here rather than a failure, so the throwing form is disabled.\n *\n * @since 3.0.0\n */\n\n private stat(path: string): Stats | undefined {\n return statSync(path, { throwIfNoEntry: false });\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { PositionInterface, FormatStackFrameInterface } from '@remotex-labs/xmap';\n\n/**\n * Imports\n */\n\nimport { cwd } from 'process';\nimport { readFileSync } from 'fs';\nimport { FilesModel } from '@models/files.model';\nimport { inject, Injectable } from '@remotex-labs/xinject';\nimport { normalize, SourceService } from '@remotex-labs/xmap';\n\n/**\n * Matches a path that belongs to the framework rather than to the project being built.\n *\n * @remarks\n * Case-insensitive, since the same file surfaces as `xBuild` from a checkout and as `xbuild` from `node_modules`.\n * The lookahead spares a project's own `xbuild.config`, which names the framework without being part of it.\n *\n * @since 3.0.0\n */\n\nconst FRAMEWORK_PATH_REGEX = /xbuild(?!\\.config)/i;\n\n/**\n * Matches a source map whose `mappings` field is empty.\n *\n * @remarks\n * Such a map resolves nothing,\n * so keeping it would cost a lookup on every frame and answer with the generated position anyway.\n * Kept at module level so the pattern is compiled once rather than on every registration.\n *\n * @since 3.0.0\n */\n\nconst EMPTY_MAPPINGS_REGEX = /\"mappings\"\\s*:\\s*\"\"/;\n\n/**\n * Holds the framework's own paths and the source maps a stack trace is resolved through.\n *\n * @remarks\n * Two jobs in service of one thing - reporting an error against the source a reader recognizes.\n * It tells framework frames apart from a project's own,\n * and it hands out the {@link SourceService} that maps a generated position back to its source.\n * Maps arrive either as text through {@link addSourceMap} or read from a `.map` companion through\n * {@link loadSourceMap}, and both are keyed by resolved path, so the same file registered under a relative and an\n * absolute path is parsed once.\n * The framework's own map is loaded on construction, which is what lets an error thrown inside the build be reported\n * against its source.\n * Registered as a singleton, so every consumer shares one registry.\n *\n * @example\n * ```ts\n * const framework = inject(FrameworkService);\n *\n * framework.projectRoot; // 'D:/app' - where the build was started\n * framework.getSourceMap(framework.frameworkFile); // the framework's own SourceService\n * framework.isFrameworkFile({ source: 'D:/app/src/index.ts' }); // false - a project file\n * ```\n *\n * @see SourceService\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class FrameworkService {\n /**\n * Absolute path of the framework file this service was loaded from.\n *\n * @remarks\n * Normalized like {@link frameworkRoot} and {@link projectRoot},\n * so all three compare and join the same way whatever the platform.\n *\n * @example\n * ```ts\n * framework.frameworkFile; // 'D:/app/node_modules/@remotex-labs/xbuild/dist/index.js'\n * ```\n *\n * @since 3.0.0\n */\n\n readonly frameworkFile: string;\n\n /**\n * Absolute path of the directory the framework was distributed in.\n *\n * @remarks\n * Where anything shipped beside the build is found, the server's certificates among them.\n *\n * @example\n * ```ts\n * framework.frameworkRoot; // 'D:/app/node_modules/@remotex-labs/xbuild/dist'\n * ```\n *\n * @since 3.0.0\n */\n\n readonly frameworkRoot: string;\n\n /**\n * Absolute path of the directory the build was started from.\n *\n * @remarks\n * The user's project root rather than the framework's,\n * so it is what a path is made relative to when a frame is printed.\n *\n * @example\n * ```ts\n * framework.projectRoot; // 'D:/app'\n * ```\n *\n * @since 3.0.0\n */\n\n readonly projectRoot: string;\n\n /**\n * Shared file cache, held on the class so {@link resolve} needs no instance.\n *\n * @remarks\n * What is wanted here is the memo it keeps rather than the snapshots: resolving through it is what keeps this\n * registry, the file cache, and everything else keyed by path agreeing on what one path is.\n * Claimed by the first {@link resolve} rather than by a static initializer, since an initializer would run while\n * this module is being imported, and importing it must not reach the container.\n *\n * @see FilesModel\n * @since 3.0.0\n */\n\n private static files?: FilesModel;\n\n /**\n * Source maps keyed by the resolved path of the file each one describes.\n *\n * @since 2.0.0\n */\n\n private readonly sourceMaps = new Map<string, SourceService>();\n\n /**\n * Captures the framework's paths and loads its own source map.\n *\n * @throws Error - When the framework ships without a readable `.map` companion\n *\n * @remarks\n * A framework shipped without its map is a broken build rather than a supported one,\n * so the read failure surfaces here instead of being swallowed.\n *\n * @example\n * ```ts\n * const framework = new FrameworkService();\n * framework.getSourceMap(framework.frameworkFile); // SourceService\n * ```\n *\n * @see loadSourceMap\n * @since 2.0.0\n */\n\n constructor() {\n this.projectRoot = normalize(cwd());\n this.frameworkFile = normalize(import.meta.filename);\n this.frameworkRoot = normalize(import.meta.dirname);\n\n this.loadSourceMap(this.frameworkFile);\n }\n\n /**\n * Normalizes a path to the absolute form every cache here is keyed by.\n *\n * @param path - Filesystem path, relative or absolute\n * @returns Absolute path with forward slashes\n *\n * @remarks\n * Static so that a caller with no framework service in hand can still key a path the way this package does, which\n * is what keeps entry-point names, source-map keys, and file entries from disagreeing about one file.\n * The first call claims the file cache, and every later call finds it already claimed, so the container is reached\n * only once something asks for a path rather than when this module is imported.\n * Resolution is memoized by the cache behind it, so resolving the same path again costs a lookup.\n *\n * @example\n * ```ts\n * FrameworkService.resolve('src/index.ts'); // 'D:/app/src/index.ts'\n * ```\n *\n * @see FilesModel\n * @since 3.0.0\n */\n\n static resolve(path: string): string {\n return (FrameworkService.files ??= inject(FilesModel)).resolve(path);\n }\n\n /**\n * Reports whether a position belongs to the framework rather than to the project being built.\n *\n * @param position - Position or stack frame to judge, as the source map resolver reports it\n * @returns `true` when the position comes from framework code\n *\n * @remarks\n * The judgment is made on the path, matched case-insensitively, since the same file surfaces as `xBuild` from a\n * checkout and as `xbuild` from `node_modules`.\n * A project's own `xbuild.config` names the framework without being part of it, so it is excluded by name.\n * The source root is consulted only when the source itself does not settle the question.\n *\n * @example\n * ```ts\n * framework.isFrameworkFile({ source: 'D:/app/node_modules/xbuild/dist/index.js' }); // true\n * framework.isFrameworkFile({ source: 'D:/app/xbuild.config.ts' }); // false\n * framework.isFrameworkFile({ source: 'D:/app/src/index.ts' }); // false\n * ```\n *\n * @see PositionInterface\n * @see FormatStackFrameInterface\n *\n * @since 2.2.5\n */\n\n isFrameworkFile(position: PositionInterface | FormatStackFrameInterface): boolean {\n return FRAMEWORK_PATH_REGEX.test(position.source ?? '') || FRAMEWORK_PATH_REGEX.test(position.sourceRoot ?? '');\n }\n\n /**\n * Returns the source map registered for a file.\n *\n * @param path - Path of the file, relative or absolute\n * @returns The source map of that file, or `undefined` when none was registered\n *\n * @remarks\n * A pure registry read: a file that was never registered stays unregistered, since nothing here reaches the disk.\n * Use {@link loadSourceMap} to register one.\n *\n * @example\n * ```ts\n * framework.getSourceMap('dist/index.js'); // undefined - never registered\n * framework.loadSourceMap('dist/index.js');\n * framework.getSourceMap('dist/index.js'); // SourceService\n * ```\n *\n * @see SourceService\n * @since 2.0.0\n */\n\n getSourceMap(path: string): SourceService | undefined {\n return this.sourceMaps.get(FrameworkService.resolve(path));\n }\n\n /**\n * Registers a source map from its text.\n *\n * @param path - Path of the file the map describes, relative or absolute\n * @param source - Raw source map content\n * @param force - Whether a map the file already carries is replaced rather than kept\n *\n * @throws Error - When the content is not a source map the resolver can parse\n *\n * @remarks\n * A file that already carries a map keeps it, so the first registration wins, and a later call costs only a lookup.\n * A caller that knows the file was written again says so with `force`, which parses the map it was handed and puts\n * it in place of the one registered before: a watch rebuilding a file leaves the map registered for it describing\n * text that is no longer there, and a stale map resolves a frame to the wrong line rather than to none.\n * A map with empty mappings is dropped rather than registered, resolving through such a map being the same as not\n * resolving at all, and it leaves what was registered before it in place rather than clearing it.\n *\n * @example\n * ```ts\n * framework.addSourceMap('dist/index.js', readFileSync('dist/index.js.map', 'utf-8'));\n * framework.getSourceMap('dist/index.js'); // SourceService\n *\n * framework.addSourceMap('dist/index.js', rebuilt); // kept - the first registration wins\n * framework.addSourceMap('dist/index.js', rebuilt, true); // replaced - the file was written again\n * ```\n *\n * @see loadSourceMap\n * @since 3.0.0\n */\n\n addSourceMap(path: string, source: string, force: boolean = false): void {\n const key = FrameworkService.resolve(path);\n if (!force && this.sourceMaps.has(key)) return;\n\n this.register(key, source);\n }\n\n /**\n * Registers the source map a file's `.map` companion carries.\n *\n * @param path - Path of the generated file, relative or absolute\n *\n * @throws Error - When the companion cannot be read or does not parse\n *\n * @remarks\n * The companion is looked for beside the file, as `<path>.map`, which is where every file this toolchain emits\n * carries its map.\n * A file that already carries a map is left alone before the disk is touched,\n * so repeating the call on a tracked file costs only a lookup.\n * An empty path is ignored outright,\n * and a companion that parses but maps nothing registers no map and raises nothing.\n *\n * @example\n * ```ts\n * framework.loadSourceMap('dist/index.js'); // reads dist/index.js.map\n * framework.loadSourceMap('dist/index.js'); // cached - no read\n * ```\n *\n * @see addSourceMap\n * @since 3.0.0\n */\n\n loadSourceMap(path: string): void {\n if (!path) return;\n\n const key = FrameworkService.resolve(path);\n if (this.sourceMaps.has(key)) return;\n\n let source: string;\n try {\n source = readFileSync(`${ key }.map`, 'utf-8');\n } catch (error) {\n throw FrameworkService.failure(key, error);\n }\n\n this.register(key, source);\n }\n\n /**\n * Builds the error reported when a source map cannot be registered.\n *\n * @param key - Resolved path of the file the map describes\n * @param error - Failure raised while reading or parsing it\n * @returns The error to throw, naming the file and carrying the original reason\n *\n * @remarks\n * The reading and the parsing halves fail in the same way as far as a caller is concerned,\n * so both report the file first and the reason after it.\n *\n * @since 3.0.0\n */\n\n private static failure(key: string, error: unknown): Error {\n return new Error(\n `Failed to load source map for: ${ key }\\n${ error instanceof Error ? error.message : String(error) }`\n );\n }\n\n /**\n * Parses a source map and files it under a resolved path.\n *\n * @param key - Resolved path of the file the map describes\n * @param source - Raw source map content\n *\n * @throws Error - When the content is not a source map the resolver can parse\n *\n * @remarks\n * The single point where a map enters the registry,\n * so both entry points resolve their path once and skip an already registered file before reaching here.\n * A map with empty mappings is dropped rather than registered, since resolving through such a map answers with\n * the position it was given.\n *\n * @since 3.0.0\n */\n\n private register(key: string, source: string): void {\n if (EMPTY_MAPPINGS_REGEX.test(source)) return;\n\n try {\n this.sourceMaps.set(key, new SourceService(source, key));\n } catch (error) {\n throw FrameworkService.failure(key, error);\n }\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { StackTraceInterface, ResolveMetadataInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { formatStack, getErrorMetadata } from '@providers/stack.provider';\n\n/**\n * Base class for errors that print as authored code rather than as the stack of the emitted bundle.\n *\n * @remarks\n * A subclass gets nothing extra until it calls {@link reformatStack}, which resolves the captured stack through the\n * source maps and keeps both the frames as data and the block to print.\n * Node writes that block whenever the error reaches the console, so a caught error names the original file and line\n * and carries a highlighted snippet of the surrounding code.\n * Extend this class when callers need an error type of their own to branch on.\n * Throw {@link xBuildError} when a general framework error will do.\n *\n * @example\n * ```ts\n * class ValidationError extends xBuildBaseError {\n * constructor(message: string) {\n * super(message, 'ValidationError');\n * this.reformatStack(this, { withFrameworkFrames: false });\n * }\n * }\n *\n * const error = new ValidationError('email is not an address');\n * error.metadata?.stack[0].format; // 'at validate src/validator.ts:15:3'\n * console.error(error); // the heading, the snippet, and the resolved trace\n * ```\n *\n * @see formatStack\n * @see xBuildError\n * @see getErrorMetadata\n * @see StackTraceInterface\n * @see ResolveMetadataInterface\n *\n * @since 2.0.0\n */\n\nexport abstract class xBuildBaseError extends Error {\n /**\n * Resolved stack metadata, as {@link getErrorMetadata} produced it.\n *\n * @remarks\n * Undefined until {@link reformatStack} runs, and replaced whole by every later call.\n * Reachable read-only through {@link metadata} for callers that want the frames as data rather than as text.\n *\n * @see ResolveMetadataInterface\n * @since 2.0.0\n */\n\n protected errorMetadata: ResolveMetadataInterface | undefined;\n\n /**\n * The block to print for this error, as {@link formatStack} produced it.\n *\n * @remarks\n * Undefined until {@link reformatStack} runs, which leaves the native stack as the only thing to print.\n * Coloring and highlighting are already applied, so the string is written out as it stands.\n *\n * @see formatStack\n * @since 2.0.0\n */\n\n protected formattedStack: string | undefined;\n\n /**\n * Creates the error and captures its raw stack, leaving the resolving to the subclass.\n *\n * @param message - Message describing what went wrong\n * @param name - Name the error reports itself under\n *\n * @remarks\n * The prototype is restored from `new.target`, so `instanceof` answers for the subclass and not only for `Error`,\n * which a transpiled subclass would otherwise lose.\n * The captured stack starts at the caller rather than inside this constructor, and stays the raw one until the\n * subclass calls {@link reformatStack} - passing a name here only heads the block, it resolves nothing.\n *\n * @since 2.0.0\n */\n\n protected constructor(message: string, name: string = 'xBuildBaseError') {\n super(message);\n\n // Ensure a correct prototype chain (important for `instanceof`)\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * The resolved stack metadata of this error.\n *\n * @returns The metadata, or `undefined` when {@link reformatStack} has not run\n *\n * @remarks\n * The frames as data, for a logger or a reporting service that renders them itself instead of printing the block.\n *\n * @example\n * ```ts\n * error.metadata; // undefined - the subclass never reformatted\n * error.metadata?.stack.length; // 4 - after reformatStack\n * error.metadata?.formatCode; // the highlighted snippet, when a frame carried code\n * ```\n *\n * @see ResolveMetadataInterface\n * @since 2.0.0\n */\n\n get metadata(): ResolveMetadataInterface | undefined {\n return this.errorMetadata;\n }\n\n /**\n * Renders the error for `console.log`, `console.error` and `util.inspect`.\n *\n * @returns The resolved block when there is one, and the native stack otherwise\n *\n * @remarks\n * Node calls this in place of printing the error's own fields, which is what puts the resolved trace on the\n * terminal without the caller having to format anything.\n * An empty block counts as no block, so an error whose sources could not be resolved still prints its native\n * stack rather than nothing.\n *\n * @example\n * ```ts\n * console.error(error); // 'ValidationError: email is not an address', the snippet, and the resolved trace\n * ```\n *\n * @see {@link https://nodejs.org/api/util.html#custom-inspection-functions-on-objects | Custom inspection}\n * @since 2.0.0\n */\n\n [Symbol.for('nodejs.util.inspect.custom')](): string | undefined {\n return this.formattedStack || this.stack;\n }\n\n /**\n * Resolves an error's stack against its sources and keeps both the metadata and the block to print.\n *\n * @param error - Error to resolve, usually `this`\n * @param options - Frame selection and code window size\n *\n * @remarks\n * Call it from the subclass constructor, after the name and the message are in place, since both are read off\n * the error to head the block with.\n * The error need not be `this` - a wrapper passes the cause it carries to report the trace of the failure that\n * actually happened.\n * Calling it again replaces both fields, so resolving a second time under different options is safe.\n *\n * @see formatStack\n * @see getErrorMetadata\n * @see StackTraceInterface\n *\n * @since 2.0.0\n */\n\n protected reformatStack(error: Error, options?: StackTraceInterface): void {\n this.errorMetadata = getErrorMetadata(error, options);\n this.formattedStack = formatStack(this.errorMetadata, error.name, error.message);\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { ServerEventsType } from '@server/interfaces/server.interface';\nimport type { LogLevelType } from '@providers/interfaces/log-provider.interface';\nimport type { LifecycleEventsType, LifecycleLogsType } from '@interfaces/lifecycle.interface';\n\n/**\n * Imports\n */\n\nimport { exit } from 'process';\nimport { setActivity } from '@ui/interactive.ui';\nimport { Injectable, inject } from '@remotex-labs/xinject';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { TypescriptService } from '@typescript/services/typescript.service';\nimport { clearScreen, createActionPrefix, printGroup, printOutputs } from '@ui/print.ui';\nimport { keywordColor, mutedColor, warnColor, errorColor, infoColor, okColor, pathColor } from '@ui/color.ui';\nimport { WarningSymbol, ErrorSymbol, DotSymbol, ArrowSymbol, ReloadSymbol, SuccessSymbol, Levels } from '@constants/ui.constant';\n\n/**\n * Turns what a run reports into what a terminal shows.\n *\n * @remarks\n * Every event of a run arrives here: a build starting and ending, a server answering, a check reporting.\n * Each one becomes a printed line, the groups of messages under it, and a word on the status line,\n * so the scrollback carries the whole run while the bar carries only what is happening now.\n * A singleton, since a run has one terminal and the level it reports at is read from every corner of it.\n *\n * @example\n * ```ts\n * const screen = inject(Screen, () => build.build());\n * build.subscribe(screen.buildEvent.bind(screen));\n *\n * screen.toggleVerbose(); // 'verbose' - and the bar says so\n * ```\n *\n * @see LifecycleEventsType\n * @since 3.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class Screen {\n /**\n * The configuration service the reporting level is read and written through.\n *\n * @remarks\n * The injected instance rather than one of its own,\n * so a level a key changes here is the level every other reader of the configuration sees.\n *\n * @example\n * ```ts\n * screen.config$.getValue().logLevel; // 'info'\n * ```\n *\n * @see ConfigurationService\n * @since 3.0.0\n */\n\n readonly config$ = inject(ConfigurationService);\n\n /**\n * The address a running server answers on, absent while none is running.\n *\n * @remarks\n * Written as the server reports its start and cleared as it stops,\n * so the status line offers a URL only while there is one to open.\n *\n * @since 3.0.0\n */\n\n private serverUrl?: string;\n\n /**\n * The level to go back to once reporting is turned down again.\n *\n * @remarks\n * Held so that turning `verbose` off restores the level the run was started at rather than a default,\n * which is what makes the toggle reversible for a run started at `error`.\n *\n * @since 3.0.0\n */\n\n private restoreLevel: LogLevelType;\n\n /**\n * Takes the build a key or a watch asks for, and settles the level to fall back to.\n *\n * @param build - What to run when a rebuild is asked for\n *\n * @remarks\n * The build arrives as a callback rather than as a service,\n * so the screen starts a run without knowing what a run is made of.\n * A run already started at `verbose` has no quieter level to remember, so `info` stands in as the one to return to.\n *\n * @example\n * ```ts\n * const screen = inject(Screen, runBuild); // runBuild is what a key or a watch will call\n * ```\n *\n * @since 3.0.0\n */\n\n constructor(private readonly build: () => Promise<void>) {\n this.restoreLevel = this.logLevel !== 'verbose' ? this.logLevel : 'info';\n }\n\n /**\n * Sets the level the run reports at.\n *\n * @param value - Level to report at from now on\n *\n * @remarks\n * Written through the configuration rather than held here,\n * so a variant reading the level for its own messages and the screen reading it for its groups agree.\n *\n * @example\n * ```ts\n * screen.logLevel = 'warning'; // info and verbose stop printing\n * ```\n *\n * @see LogLevelType\n * @since 3.0.0\n */\n\n set logLevel(value: LogLevelType) {\n this.config$.patch({ logLevel: value });\n }\n\n /**\n * The level the run is reporting at.\n *\n * @returns The configured level, `info` where the configuration names none\n *\n * @example\n * ```ts\n * screen.logLevel; // 'info'\n * ```\n *\n * @see LogLevelType\n * @since 3.0.0\n */\n\n get logLevel(): LogLevelType {\n return this.config$.getValue().logLevel ?? 'info';\n }\n\n /**\n * The address the running server answers on.\n *\n * @returns The URL, empty while no server is running\n *\n * @remarks\n * Empty rather than absent, so a caller writing it into a line needs no guard of its own.\n *\n * @example\n * ```ts\n * screen.url; // 'http://localhost:3000'\n * ```\n *\n * @since 3.0.0\n */\n\n get url(): string {\n return this.serverUrl ?? '';\n }\n\n /**\n * Records the address a server has begun answering on.\n *\n * @param value - URL the server bound to\n *\n * @example\n * ```ts\n * screen.url = 'http://localhost:3000';\n * ```\n *\n * @since 3.0.0\n */\n\n set url(value: string) {\n this.serverUrl = value;\n }\n\n /**\n * Reports either end of a build: its start or its finish.\n *\n * @param event - What the variant reported, carrying its context and, at the end, its result\n *\n * @remarks\n * A start says which variant is building and no more, since nothing has been found out yet.\n * An end prints the messages first and the outcome last,\n * so a reader scrolling up meets the verdict before its reasons.\n * A build that wrote no output is the failing case, whether it threw or only reported errors,\n * and it sets the exit code, which is what lets a pipeline read the run without reading its output.\n * Reporting at `verbose` lists every output rather than the largest few.\n *\n * @example\n * ```ts\n * build.subscribe(screen.buildEvent.bind(screen));\n * // [xBuild] → build esm\n * // [xBuild] ✓ esm in 128 ms\n * ```\n *\n * @see LifecycleEventsType\n * @since 3.0.0\n */\n\n buildEvent(event: LifecycleEventsType): void {\n if (event.type === 'start')\n return this.say(`${ infoColor.dim(ArrowSymbol) } ${ mutedColor('building') } ${ keywordColor(event.context.variantName) }`,\n `${ createActionPrefix('build') } ${ keywordColor(event.context.variantName) }`);\n\n const { errors, warnings, info, verbose: notes, metafile } = event.buildResult;\n const failed = !metafile;\n if (failed) process.exitCode = 1;\n else process.exitCode = 0;\n\n this.groups({ error: errors, warning: warnings, info, verbose: notes });\n if (metafile) printOutputs(metafile, this.logLevel === 'verbose' ? Infinity : undefined);\n\n const symbol = failed ? errorColor(ErrorSymbol) : okColor(SuccessSymbol);\n const name = failed ? warnColor(event.context.variantName) : keywordColor(event.context.variantName);\n\n this.say(`${ symbol } ${ name } ${ mutedColor.dim(`in ${ event.duration } ms`) }`,\n `\\n${ createActionPrefix('build', symbol) } ${ name } ${ mutedColor.dim(`in ${ event.duration } ms`) }`);\n }\n\n /**\n * Reports what the development server is doing.\n *\n * @param event - What the server reported: its start, its stop, a request, or a failure\n *\n * @remarks\n * A start is where the address comes from, and a stop is what takes it away again,\n * so the status line offers the URL for exactly as long as something answers on it.\n * A stop is reported only where a server was running, since a stop is worth a line only where something was answering.\n * Requests are reported only at `verbose`, one line being worth little against a page that fetches thirty files.\n * A failed `favicon.ico` is dropped whatever the level, since browsers ask for one unprompted on every visit.\n *\n * @example\n * ```ts\n * server.subscribe(screen.serverEvent.bind(screen));\n * // [xBuild] → serve http://localhost:3000\n * ```\n *\n * @see ServerEventsType\n * @since 3.0.0\n */\n\n serverEvent(event: ServerEventsType): void {\n switch (event.type) {\n case 'start':\n this.url = event.url;\n\n return console.log(`${ createActionPrefix('serve') } ${ pathColor(event.url) }`);\n case 'stop':\n this.serverUrl = undefined;\n if (event.running) console.log(`${ createActionPrefix('serve') } ${ mutedColor('stopped') }`);\n\n return;\n case 'request':\n if (this.logLevel === 'verbose')\n console.log(`${ createActionPrefix('serve') } ${ mutedColor.dim(event.url) }`);\n\n return;\n case 'error':\n if (event.url?.includes('favicon')) return;\n console.log(\n `${ createActionPrefix('serve', errorColor(ErrorSymbol)) } ${ mutedColor(event.error.message) }`\n );\n }\n }\n\n /**\n * Reports a type check and ends the process on what it found.\n *\n * @param diagnostics - Messages each variant's check reported, keyed by the variant's name\n *\n * @remarks\n * Every variant gets a heading carrying what it found, followed by its groups,\n * so a clean variant is still reported rather than left out of a run that named it.\n * The count is of everything the check reported rather than of what the level prints,\n * which is what keeps a quiet run from reading as a clean one.\n * The process leaves from here, and an error anywhere leaves with `1`,\n * since a check is the whole of what a run asking for one wanted.\n *\n * @example\n * ```ts\n * screen.diagnostics(await build.typeChack());\n * // [xBuild] → type-check esm 2 to look at\n * ```\n *\n * @see LifecycleLogsType\n * @since 3.0.0\n */\n\n diagnostics(diagnostics: Record<string, LifecycleLogsType>): void {\n let failed = false;\n\n for (const [ name, logs ] of Object.entries(diagnostics)) {\n const total = logs.error.length + logs.warning.length + logs.info.length + logs.verbose.length;\n\n failed ||= logs.error.length > 0;\n console.log(`${ createActionPrefix('type-check') } ${ keywordColor(name) } ${ mutedColor.dim(`${ total } to look at`) }`);\n this.groups(logs);\n console.log('');\n }\n\n exit(failed ? 1 : 0);\n }\n\n /**\n * Clears what the last build left, takes up any configuration change, says what asked for this build, and runs it.\n *\n * @param reason - What asked for the build, such as the files that changed or the key that was pressed\n * @param force - Whether every TypeScript project reparses its configuration even where its file has not moved\n *\n * @remarks\n * Every rebuild of a watch goes through here, so the screen is cleared and the run announced the same way\n * whichever asked for it.\n * The build itself is the one the run handed over when the screen was made.\n * The TypeScript configurations are reloaded here rather than by the watch,\n * so a rebuild started by a key reads them as freshly as one started by a changed file.\n * A configuration that has stayed put costs a lookup and nothing more.\n * Forcing reparses every project regardless, which is what the reload key asks for\n * and what catches a change the configuration file's own version misses.\n *\n * @example\n * ```ts\n * await screen.rebuild('2 files changed'); // [xBuild] rebuild 2 files changed\n * await screen.rebuild('reloading', true); // the same, with every tsconfig reparsed first\n * ```\n *\n * @see TypescriptService.reload\n * @since 3.0.0\n */\n\n async rebuild(reason: string, force: boolean = false): Promise<void> {\n clearScreen();\n TypescriptService.reload(force);\n\n this.say(`${ infoColor.dim(ReloadSymbol) } ${ mutedColor(reason) }`,\n `${ createActionPrefix('rebuild', infoColor.dim(ReloadSymbol)) } ${ mutedColor(reason) }`);\n\n await this.build();\n }\n\n /**\n * Turns reporting all the way up, or back to what it was before it was turned up.\n *\n * @returns The level the run now reports at\n *\n * @remarks\n * The level the run was set to is remembered rather than assumed,\n * so a run started at `error` goes back to `error` rather than to the default.\n * The level is written back through the configuration, so everything reading it follows in the same breath.\n *\n * @example\n * ```ts\n * screen.toggleVerbose(); // 'verbose'\n * screen.toggleVerbose(); // 'info' - what it was before\n * ```\n *\n * @since 3.0.0\n */\n\n toggleVerbose(): LogLevelType {\n if (this.logLevel === 'verbose') this.logLevel = this.restoreLevel;\n else {\n this.restoreLevel = this.logLevel;\n this.logLevel = 'verbose';\n }\n\n return this.logLevel;\n }\n\n /**\n * Writes a line to the scrollback and says the same thing on the status line.\n *\n * @param activity - What is happening, as the bar says it\n * @param line - The line printed to the scrollback\n *\n * @remarks\n * The two are worded apart rather than shared, since the bar carries no prefix and has one row to say it in,\n * while the printed line stands on its own long after the run has moved past it.\n *\n * @see setActivity\n * @since 3.0.0\n */\n\n private say(activity: string, line: string): void {\n console.log(line);\n setActivity(activity);\n }\n\n /**\n * Prints the message groups the current level allows.\n *\n * @param logs - Messages to print, filed under the level each was reported at\n *\n * @remarks\n * The groups run loudest first, so what failed a build is read before what merely remarked on it.\n * Each group is compared against the level the run is set to,\n * which is what leaves a quiet run its errors and drops everything under them.\n * An error always carries its code window and its trace, since that is what an error is read for,\n * while the quieter groups carry theirs only at `verbose`.\n *\n * @see Levels\n * @see printGroup\n *\n * @since 3.0.0\n */\n\n private groups(logs: LifecycleLogsType): void {\n const lowest = Levels[this.logLevel];\n const code = this.logLevel === 'verbose';\n\n if (Levels.error >= lowest) printGroup(logs.error, 'Errors', errorColor, ErrorSymbol, true);\n if (Levels.warning >= lowest) printGroup(logs.warning, 'Warnings', warnColor, WarningSymbol, code);\n if (Levels.info >= lowest) printGroup(logs.info, 'Info', infoColor, ArrowSymbol, code);\n if (Levels.verbose >= lowest) printGroup(logs.verbose, 'Verbose', mutedColor, DotSymbol, code);\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Key } from 'readline';\nimport type { Screen } from '@ui/screen.ui';\n\n/**\n * Imports\n */\n\nimport { exec } from 'child_process';\nimport * as readline from 'node:readline';\nimport { clearScreen, width } from '@ui/print.ui';\nimport { platform, stdin, stdout, exit } from 'process';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { ANSI, moveCursor, writeRaw } from '@remotex-labs/xansi';\nimport { ShadowRenderer } from '@remotex-labs/xansi/shadow.service';\nimport { infoColor, keywordColor, mutedColor, pathColor } from '@ui/color.ui';\nimport { DotSymbol, Indent, MinimumRows, RepaintInterval, ReloadSymbol, ReportTimeout } from '@constants/ui.constant';\n\n/**\n * The command each platform opens a URL with.\n *\n * @remarks\n * Anything the table does not name falls back to the freedesktop opener, which is what every other Unix carries.\n *\n * @since 3.0.0\n */\n\nconst OpenCommands: Record<string, string> = { darwin: 'open', win32: 'start' };\n\n/**\n * What each key does, paired with the line the menu describes it by.\n *\n * @remarks\n * One table drives both the menu and the dispatch, so a key cannot be listed without an action or the other way round.\n * The key that opens a browser is listed only while a server is running, which is what `server` marks it by.\n *\n * @since 3.0.0\n */\n\nconst Keys = [\n { key: 'h', describe: 'show this menu', server: false },\n { key: 'b', describe: 'run the build', server: false },\n { key: 'r', describe: 'reload and rebuild', server: false },\n { key: 'v', describe: 'toggle verbose', server: false },\n { key: 'c', describe: 'clear the screen', server: false },\n { key: 'o', describe: 'open it in a browser', server: true },\n { key: 'q', describe: 'quit', server: false }\n] as const;\n\n/**\n * The screen the keys act on and the bar reads, absent while no watch is listening.\n *\n * @remarks\n * The settings a run is under live on the screen rather than here,\n * so a key that changes one and a report that reads it are looking at the same value.\n *\n * @since 3.0.0\n */\n\nlet session: Screen | undefined;\n\n/**\n * What the run is doing, as the bar says it, empty while the watch rests between builds.\n *\n * @since 3.0.0\n */\n\nlet activity = '';\n\n/**\n * The row the bar draws through, absent while the terminal has none to spare.\n *\n * @remarks\n * A viewport one row tall pinned to the foot of the terminal.\n * Its rows count from one, so the row it is offset by is the one above the last,\n * which is what puts its only row on the last one rather than a line past the bottom of the screen.\n * It holds what it drew, so redrawing writes only the cells that moved, and a line too long for the terminal is cut\n * to fit rather than wrapping onto the row above and breaking the region the report scrolls in.\n *\n * @see ShadowRenderer\n * @since 3.0.0\n */\n\nlet row: ShadowRenderer | undefined;\n\n/**\n * The beat the bar is painted on, absent while no watch holds a row.\n *\n * @since 3.0.0\n */\n\nlet repaint: NodeJS.Timeout | undefined;\n\n/**\n * The row the cursor sits on, as the terminal itself reports it.\n *\n * @returns The row, or the last one where the terminal did not answer\n *\n * @remarks\n * Where a run has printed to is the one thing it cannot know for itself, and it decides everything the row rests on:\n * a watch started on a screen already full leaves the cursor on the last row, which is the row the line is about\n * to take, and every line printed afterward would land under the line and be painted over rather than scrolled.\n * The terminal is asked outright, and it answers on the input the shortcuts have yet to claim,\n * so the reply is read before the keys are listened for rather than swallowed by them.\n * A terminal that does not answer is taken to be full, which is the safe half of the guess.\n *\n * @since 3.0.0\n */\n\nfunction cursorRow(): Promise<number> {\n return new Promise(resolve => {\n const answer = (data: Buffer): void => {\n const reported = /\\[(\\d+);\\d+R/.exec(data.toString());\n if (!reported) return;\n\n stdin.off('data', answer);\n resolve(Number(reported[1]));\n };\n\n stdin.on('data', answer);\n writeRaw('\\u001B[6n');\n setTimeout(() => (stdin.off('data', answer), resolve(stdout.rows)), ReportTimeout).unref();\n });\n}\n\n/**\n * Opens a URL in whatever the platform treats as the browser.\n *\n * @param url - Address to open\n *\n * @remarks\n * The command is spawned and left to itself, so a browser that takes its time does not hold the watch up,\n * and a platform without an opener fails silently rather than taking down the run with it.\n *\n * @example\n * ```ts\n * openInBrowser('http://localhost:3000');\n * ```\n *\n * @since 3.0.0\n */\n\nexport function openInBrowser(url: string): void {\n exec(`${ OpenCommands[platform] ?? 'xdg-open' } ${ url }`);\n}\n\n/**\n * Renders the menu of what the keys do.\n *\n * @returns The menu, ready to write\n *\n * @remarks\n * The key that opens a browser is listed only while a server is running, there being nothing to open otherwise.\n *\n * @example\n * ```ts\n * console.log(helpMenu());\n * // Shortcuts\n * // press h to show this menu\n * ```\n *\n * @since 3.0.0\n */\n\nexport function helpMenu(): string {\n const lines = [ `\\n🚀 ${ keywordColor('Shortcuts') }` ];\n for (const { key, describe, server } of Keys) {\n if (!server || session?.url)\n lines.push(`${ Indent }${ mutedColor.dim('press') } ${ xterm.bold(key) } ${ mutedColor.dim(`to ${ describe }`) }`);\n }\n\n return `${ lines.join('\\n') }\\n`;\n}\n\n/**\n * Draws the status line on the row it holds, leaving the cursor where it found it.\n *\n * @param force - Whether to paint every cell rather than the ones that moved\n *\n * @remarks\n * Only what changed is written, unless the caller asks for the whole row,\n * which is what the repainting beat asks for: a terminal cleared behind the run's back is not what the row\n * remembers drawing, so nothing would be found to differ and nothing would be written.\n * What the run is doing leads, and the rest reads left to right:\n * where the server is, whether it is reporting everything, and how to see the keys.\n *\n * @example\n * ```ts\n * drawStatusBar();\n * // PASS main in 134 ms · http://localhost:3000 · verbose · press h for shortcuts\n * ```\n *\n * @since 3.0.0\n */\n\nexport function drawStatusBar(force = false): void {\n if (!row) return;\n\n const parts = [ activity || `${ infoColor.dim(ReloadSymbol) } ${ mutedColor('watching') }` ];\n if (session?.url) parts.push(pathColor(session.url));\n if (session?.logLevel === 'verbose') parts.push(keywordColor('verbose'));\n parts.push(mutedColor.dim('press h for shortcuts'));\n\n writeRaw(ANSI.SAVE_CURSOR);\n row.writeText(0, 0, ` ${ parts.join(mutedColor.dim(` ${ DotSymbol } `)) }`, true);\n row.render(force);\n writeRaw(ANSI.RESTORE_CURSOR);\n}\n\n/**\n * Says what the run is doing and redraws the bar.\n *\n * @param text - What is happening, already colored, empty to say the watch is resting\n *\n * @example\n * ```ts\n * setActivity(`${ infoColor(ArrowSymbol) } building index`);\n * ```\n *\n * @see drawStatusBar\n * @since 3.0.0\n */\n\nexport function setActivity(text: string): void {\n activity = text;\n drawStatusBar();\n}\n\n/**\n * Listens for the shortcuts and takes the last row of the terminal for the status line.\n *\n * @param screen - Screen the keys act on and the bar reads its settings from\n * @returns A promise settling once the row is held and the keys are listened for\n *\n * @remarks\n * A terminal that is not one - a pipe, a log file, a pipeline - is left alone,\n * since raw mode would take a run that nobody is watching and break its input.\n * Where the run has printed to is asked of the terminal before the keys are listened for, the answer coming back\n * on the same input: only a run that has reached the last row needs one scrolled free,\n * and one that has not keeps the blank line it would have cost.\n * The region is set so that everything printed afterward scrolls above the line rather than over it,\n * which keeps it out of the scrollback.\n * The row is painted again on a beat, so a terminal cleared from outside the run gets the line back at once,\n * and the beat is unreferenced, so it never holds the process open on its own.\n * The cursor is put away for as long as the line holds the row, and everything is given back as the run leaves.\n *\n * @example\n * ```ts\n * startInteractive(screen);\n * ```\n *\n * @see handleKey\n * @see drawStatusBar\n *\n * @since 3.0.0\n */\n\nexport async function startInteractive(screen: Screen): Promise<void> {\n if (!stdin.isTTY || !stdout.isTTY || repaint) return;\n session = screen;\n\n stdin.setRawMode(true);\n writeRaw(ANSI.HIDE_CURSOR);\n\n const printed = await cursorRow();\n if (printed >= stdout.rows) writeRaw('\\n');\n claimRow(Math.min(printed, stdout.rows - 1));\n\n readline.emitKeypressEvents(stdin);\n stdin.on('keypress', (_, key: Key) => handleKey(key));\n\n stdout.on('resize', () => claimRow());\n repaint = setInterval(() => drawStatusBar(true), RepaintInterval).unref();\n process.on('exit', stopInteractive);\n}\n\n/**\n * Gives the row back and clears what the status line left on it.\n *\n * @remarks\n * Run as the process leaves, so the terminal is handed back scrolling in the whole of itself, cursor and all.\n * A run that never took a row has none to give, and returns.\n *\n * @since 3.0.0\n */\n\nexport function stopInteractive(): void {\n if (!repaint) return;\n\n clearInterval(repaint);\n repaint = undefined;\n row = undefined;\n\n writeRaw(`\\u001B[r${ moveCursor(stdout.rows, 1) }${ ANSI.CLEAR_LINE }${ ANSI.SHOW_CURSOR }`);\n}\n\n/**\n * Cuts the region the output scrolls in out of the terminal as it now stands, and draws the line under it.\n *\n * @param anchor - Row the run had printed to, left out by a resize to put the cursor back where it was\n *\n * @remarks\n * Run on every resize as well as on the first claim, so the row is rebuilt for the size the terminal now is.\n * Setting a region homes the cursor, so it is put back where the caller says the run had printed to:\n * the next line printed belongs under the last one written, not at the foot of a screen it has yet to fill,\n * and never on the row the line holds, where it would be painted over rather than read.\n * A resize is given no row to go back to and restores what was saved, the run printing inside the region by then.\n * The row is cleared before it is drawn, since the line has no claim on what a resize reflowed onto it.\n * A terminal too short to spare a row keeps all of itself and goes without the line until it is resized larger.\n *\n * @since 3.0.0\n */\n\nfunction claimRow(anchor?: number): void {\n if (stdout.rows < MinimumRows) {\n row = undefined;\n\n return writeRaw(`\\u001B[r${ ANSI.CLEAR_LINE }`);\n }\n\n const last = stdout.rows - 1;\n const back = anchor === undefined ? ANSI.RESTORE_CURSOR : moveCursor(anchor, 1);\n\n row = new ShadowRenderer(1, width(), last, 1);\n writeRaw(\n `${ ANSI.SAVE_CURSOR }\\u001B[1;${ last }r`\n + `${ moveCursor(stdout.rows, 1) }${ ANSI.CLEAR_LINE }${ back }`\n );\n\n drawStatusBar(true);\n}\n\n/**\n * Runs what a key asks for.\n *\n * @param key - Key that was pressed, as the terminal reported it\n *\n * @remarks\n * Interrupts leave through the same door as `q`, so a watch stopped by a keystroke and one stopped by a signal\n * end the same way, and both hand the terminal back before they go.\n * The run leaves only once the line saying so has been written, since leaving outright would cut the terminal\n * off before what was written for it had reached it.\n * Building and reloading part on one flag: `b` builds again from the configurations as they were parsed,\n * while `r` has every TypeScript project reparse its own first.\n * That reparse is what catches a change their versions miss, such as an edit to a file one of them extends.\n * A key with nothing bound to it is passed over, since a watch is left running rather than surprised by a typo.\n *\n * @see helpMenu\n * @since 3.0.0\n */\n\nasync function handleKey(key: Key): Promise<void> {\n if (key.ctrl && (key.name === 'c' || key.name === 'd')) key.name = 'q';\n\n switch (key.name) {\n case 'q':\n stopInteractive();\n stdout.write(`${ mutedColor('Stopped.') }\\n`, () => exit(process.exitCode ? Number(process.exitCode) : 0));\n\n return;\n case 'c':\n clearScreen();\n\n return drawStatusBar(true);\n case 'h':\n return console.log(helpMenu());\n case 'v':\n session?.toggleVerbose();\n\n return drawStatusBar(true);\n case 'o':\n if (session?.url) openInBrowser(session.url);\n\n return;\n case 'b':\n return session?.rebuild('rebuilding');\n case 'r':\n return session?.rebuild('reloading', true);\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { errorColor } from '@ui/color.ui';\nimport type { Metafile, PartialMessage } from 'esbuild';\nimport type { MessageRowInterface } from '@ui/interfaces/print-ui.interface';\nimport type { ResolveMetadataInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { resolve } from 'path';\nimport { stdout } from 'process';\nimport { prefix } from '@ui/banner.ui';\nimport { relative } from '@remotex-labs/xmap';\nimport { inject } from '@remotex-labs/xinject';\nimport { stripAnsi } from '@remotex-labs/xansi';\nimport { cursorTo, clearScreenDown } from 'readline';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { getErrorMetadata } from '@providers/stack.provider';\nimport { FrameworkService } from '@services/framework.service';\nimport { infoColor, mutedColor, okColor, pathColor, warnColor } from '@ui/color.ui';\nimport { ArrowSymbol, DefaultWidth, DotSymbol, Indent, Kilobyte, Megabyte, OutputLimit } from '@constants/ui.constant';\n\n/**\n * Opens a reported line with the package's mark, a symbol, and the action being reported.\n *\n * @param action - What the line reports, such as `build` or `serve`\n * @param symbol - Symbol between the mark and the action, a dimmed arrow by default\n * @returns The opening of the line, colored\n *\n * @remarks\n * Every line printed outside a message group opens this way,\n * so the mark, the symbol, and the action sit in the same three places whatever printed them.\n * The symbol is what a caller varies to say how the action went, since the action itself reads the same either way.\n *\n * @example\n * ```ts\n * createActionPrefix('build'); // '[xBuild] → build'\n * createActionPrefix('build', okColor(SuccessSymbol)); // '[xBuild] ✓ build'\n * ```\n *\n * @see prefix\n * @since 3.0.0\n */\n\nexport function createActionPrefix(action: string, symbol: string = infoColor.dim(ArrowSymbol)): string {\n return `${ prefix() } ${ symbol } ${ infoColor(action) }`;\n}\n\n/**\n * Counts the characters a text takes on screen.\n *\n * @param text - Text to measure, colored or not\n * @returns The number of characters that print\n *\n * @remarks\n * The escape sequences a color leaves behind take no width of their own,\n * so measuring the string itself would pad a colored column by however many bytes its color cost.\n *\n * @example\n * ```ts\n * visible(pathColor('src/index.ts')); // 12\n * ```\n *\n * @since 3.0.0\n */\n\nexport function visible(text: string): number {\n return stripAnsi(text).length;\n}\n\n/**\n * Pads a text with spaces up to a width.\n *\n * @param text - Text to pad, colored or not\n * @param size - Width to pad it to, counted in printed characters\n * @returns The text, followed by the spaces that carry it to the width\n *\n * @remarks\n * The width is measured through {@link visible}, so a colored text pads to what it prints rather than to what it holds.\n * A text already at or past the width comes back as it is rather than cut,\n * since a column that overflows reads better than one that loses the end of a name.\n *\n * @example\n * ```ts\n * pad('src', 6); // 'src '\n * pad('src/index', 6); // 'src/index' - already past the width\n * ```\n *\n * @see visible\n * @since 3.0.0\n */\n\nexport function pad(text: string, size: number): string {\n return text + ' '.repeat(Math.max(0, size - visible(text)));\n}\n\n/**\n * Brings the path a frame resolved to back to one the project can be read against.\n *\n * @param file - Path the frame named, as the source map spelled it\n * @returns The path relative to the directory the run was started in\n *\n * @remarks\n * A map spells its sources relative to what was written rather than to what is being read,\n * so a config compiled by this package resolves as a path reaching back out of the framework's own directory.\n * Such a path is resolved from there rather than from the project, which is the only place it means anything,\n * and every other path is resolved the way this package keys files everywhere else.\n * A source that names a URL rather than a path is left as it is, there being no root to read it against.\n *\n * @example\n * ```ts\n * sourcePath('../config.xbuild.ts'); // 'config.xbuild.ts'\n * sourcePath('src/index.ts'); // 'src/index.ts'\n * sourcePath('https://github.com/x/y.ts'); // 'https://github.com/x/y.ts'\n * ```\n *\n * @see FrameworkService\n * @since 3.0.0\n */\n\nexport function sourcePath(file: string): string {\n if (file.includes('://')) return file;\n const absolute = file.startsWith('.')\n ? resolve(inject(FrameworkService).frameworkRoot, file)\n : FrameworkService.resolve(file);\n\n return relative(process.cwd(), absolute);\n}\n\n/**\n * Renders where a message points.\n *\n * @param file - Path the message points at, absent when it points nowhere\n * @param line - Line within that file\n * @param column - Column within that line\n * @returns The location, colored, empty when there is no file to point at\n *\n * @example\n * ```ts\n * formatLocation('src/index.ts', 12, 8); // 'src/index.ts:12:8'\n * formatLocation(undefined); // ''\n * ```\n *\n * @see sourcePath\n * @since 3.0.0\n */\n\nexport function formatLocation(file?: string, line: number = 0, column: number = 0): string {\n if (!file) return '';\n const separator = mutedColor.dim(':');\n\n return `${ pathColor(sourcePath(file)) }${ separator }${ warnColor(String(line)) }${ separator }${ warnColor(String(column)) }`;\n}\n\n/**\n * Renders the code window and the trace printed under a message.\n *\n * @param metadata - Already resolved trace of the message, so nothing is resolved twice\n * @param indent - What every line is indented by\n * @returns The lines to print under the message, empty when it resolved to neither code nor a trace\n *\n * @remarks\n * A trace of a single frame says nothing the location line has not said already, so it is left out.\n * Paths are printed from the directory the run was started in, the absolute part being the same for every frame.\n *\n * @see getErrorMetadata\n * @since 3.0.0\n */\n\nexport function formatDetail(metadata: ResolveMetadataInterface, indent: string): Array<string> {\n const root = `${ process.cwd() }/`;\n const lines: Array<string> = [];\n\n if (metadata.formatCode)\n lines.push('', ...metadata.formatCode.split('\\n').map(line => `${ indent }${ xterm.dim(line) }`));\n\n if (metadata.stack.length > 1) lines.push('', ...metadata.stack.map(frame => {\n return `${ indent }${ mutedColor.dim(frame.format.replaceAll(root, '')) }`;\n }));\n\n return lines.length > 0 ? [ ...lines, '' ] : lines;\n}\n\n/**\n * Works a message out into the parts a report line is laid out from.\n *\n * @param message - Message to describe\n * @param code - Whether the code window and trace are wanted under the line\n * @returns The message worked out, ready to be measured and printed\n *\n * @remarks\n * A diagnostic filed under a TypeScript code - an id of `TS<code>` - already points at the file that was written,\n * so it is taken at its word.\n * Anything else points at what was built rather than at what was written - a plugin throwing from a config that was\n * compiled to run reports the offset it failed at in the compiled text - so it is resolved through the source map\n * and read off the first frame instead.\n * The resolve is done once and serves both the location and what is printed under it,\n * and is skipped entirely by a diagnostic that needs neither.\n *\n * @example\n * ```ts\n * describeMessage({ id: 'TS2304', location: { file: 'src/index.ts', line: 12, column: 8 } }, false);\n * // { id: 'TS2304', location: 'src/index.ts:12:8', detail: [] }\n * ```\n *\n * @see getErrorMetadata\n * @see MessageRowInterface\n *\n * @since 3.0.0\n */\n\nexport function describeMessage(message: PartialMessage, code: boolean): MessageRowInterface {\n const typescript = message.id?.startsWith('TS') ?? false;\n const metadata = typescript && !code\n ? undefined\n : getErrorMetadata(message, { linesAfter: 1, linesBefore: 1, withFrameworkFrames: true });\n\n const frame = typescript ? undefined : metadata?.stack[0];\n const point = frame ?? message.location;\n\n return {\n id: message.id ?? '',\n detail: code && metadata ? formatDetail(metadata, Indent.repeat(2)) : [],\n location: formatLocation(frame?.fileName ?? message.location?.file, point?.line, point?.column)\n };\n}\n\n/**\n * Prints a group of messages under a heading, in columns sized to what they hold.\n *\n * @param messages - Messages to print, the group being skipped when there are none\n * @param title - Heading the group is printed under\n * @param color - Color the heading, the symbol, and the ids are printed in\n * @param symbol - Symbol each message is marked with\n * @param code - Whether each message carries its code window and trace\n *\n * @remarks\n * Every message is worked out once, in the pass that measures the columns,\n * since neither the location column nor the id column can be sized until all of them have been seen.\n * An id column is left out entirely when nothing in the group carries one.\n *\n * @example\n * ```ts\n * printGroup(errors, 'Errors', errorColor, ErrorSymbol, true);\n * // Errors (1)\n * // x config.xbuild.ts:126:27 asdasd\n * ```\n *\n * @see describeMessage\n * @since 3.0.0\n */\n\nexport function printGroup(\n messages: Array<PartialMessage>, title: string, color: typeof errorColor, symbol: string, code = false\n): void {\n if (messages.length < 1) return;\n\n let left = 0;\n let middle = 0;\n const rows: Array<MessageRowInterface> = [];\n\n for (const message of messages) {\n const row = describeMessage(message, code);\n left = Math.max(left, visible(row.location));\n middle = Math.max(middle, row.id.length);\n rows.push(row);\n }\n\n const lines = [ `\\n ${ color(title) } ${ mutedColor.dim(`(${ rows.length })`) }` ];\n for (const [ index, { id, location, detail }] of rows.entries()) {\n const tag = middle > 0 ? `${ pad(color(id), middle) } ` : '';\n\n lines.push(`${ Indent }${ color(symbol) } ${ pad(location, left) } ${ tag }${ mutedColor(messages[index].text ?? '') }`);\n lines.push(...detail);\n }\n\n console.log(lines.join('\\n'));\n}\n\n/**\n * Clears the terminal and puts the cursor back at the top.\n *\n * @remarks\n * The screen is pushed out of view rather than wiped, so the scrollback survives a clear.\n *\n * @since 3.0.0\n */\n\nexport function clearScreen(): void {\n const rows = Math.max(0, stdout.rows - 2);\n if (rows > 0) console.log('\\n'.repeat(rows));\n\n cursorTo(stdout, 0, 0);\n clearScreenDown(stdout);\n}\n\n/**\n * The width of the terminal, or what stands in for one that does not report it.\n *\n * @returns Columns the report is laid out in\n *\n * @since 3.0.0\n */\n\nexport function width(): number {\n return stdout.columns || DefaultWidth;\n}\n\n/**\n * Renders a byte count in the largest unit that keeps it above one.\n *\n * @param bytes - Size to render\n * @returns The size with its unit\n *\n * @example\n * ```ts\n * formatSize(512); // '512 B'\n * formatSize(458520); // '447.77 KB'\n * ```\n *\n * @since 3.0.0\n */\n\nexport function formatSize(bytes: number): string {\n if (bytes < Kilobyte) return `${ bytes } B`;\n if (bytes < Megabyte) return `${ (bytes / Kilobyte).toFixed(2) } KB`;\n\n return `${ (bytes / Megabyte).toFixed(2) } MB`;\n}\n\n/**\n * Writes what a build wrote, largest first, with the sizes set against the right margin.\n *\n * @param metafile - Metafile of the finished build, read for its outputs\n * @param limit - How many outputs to name before the rest are counted rather than listed, `Infinity` for all of them\n *\n * @remarks\n * The sizes are set flush against the right margin, so their digits line up under one another,\n * and the heading carries the total, which is the number a reader is usually after.\n * A build of many entry points writes more than a reader wants to scroll,\n * so the largest few are named and the rest left as a count carrying what it comes to.\n *\n * @example\n * ```ts\n * printOutputs(metafile);\n * // Outputs (18) 1.24 MB\n * // dist/index.js.map 681 B\n * ```\n *\n * @since 3.0.0\n */\n\nexport function printOutputs(metafile: Metafile, limit: number = OutputLimit): void {\n const outputs = Object.entries(metafile.outputs).sort(\n ([ , a ], [ , b ]) => b.bytes - a.bytes\n );\n\n if (outputs.length < 1) return;\n const listed = outputs.slice(0, limit);\n const sizes = listed.map(([ , { bytes }]) => formatSize(bytes));\n const right = Math.max(...sizes.map(size => size.length));\n const total = outputs.reduce((sum, [ , { bytes }]) => sum + bytes, 0);\n\n const room = width() - Indent.length - right - 4;\n const header = ` ${ okColor('Outputs') } ${ mutedColor.dim(`(${ outputs.length })`) }`;\n const lines = [ `\\n${ pad(header, width() - right - 1) }${ warnColor.dim(formatSize(total)) }` ];\n\n for (const [ index, [ path ]] of listed.entries())\n lines.push(\n `${ Indent }${ infoColor.dim(ArrowSymbol) } ${ pad(pathColor(path), room + 1) }`\n + warnColor.dim(sizes[index].padStart(right))\n );\n\n if (outputs.length > limit) {\n const rest = outputs.slice(limit).reduce((sum, [ , { bytes }]) => sum + bytes, 0);\n const more = mutedColor.dim(`${ DotSymbol } ${ outputs.length - limit } more`);\n lines.push(`${ Indent } ${ pad(more, room + 1) }${ warnColor.dim(formatSize(rest).padStart(right)) }`);\n }\n\n console.log(lines.join('\\n'));\n}\n","/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * The xBuild wordmark drawn in ASCII art.\n *\n * @remarks\n * Opens and closes with a newline, so it stands on its own lines wherever it is printed.\n * The backslashes are escaped for the template literal,\n * so the string holds one backslash everywhere the source shows two.\n *\n * @example\n * ```ts\n * console.log(asciiLogo);\n * ```\n *\n * @see bannerUi\n * @since 1.0.0\n */\n\nexport const asciiLogo = `\n ______ _ _ _\n | ___ \\\\ (_) | | |\n__ _| |_/ /_ _ _| | __| |\n\\\\ \\\\/ / ___ \\\\ | | | | |/ _\\` |\n > <| |_/ / |_| | | | (_| |\n/_/\\\\_\\\\____/ \\\\__,_|_|_|\\\\__,_|\n`;\n\n/**\n * Renders the startup banner, the logo above the version.\n *\n * @returns The banner as one string, colored and ready to print\n *\n * @remarks\n * The logo is drawn in burnt orange and the version in bright pink.\n * Every line opens with a carriage return, so the text starts at column zero\n * whatever indentation the template literal carries.\n * The version reads `__VERSION`, which the build replaces with the `package.json` version at compile time.\n *\n * @example\n * ```ts\n * console.log(bannerComponent());\n * ```\n *\n * @see asciiLogo\n * @since 1.0.0\n */\n\nexport function bannerUi(): string {\n return `\n \\r${ xterm.burntOrange(asciiLogo) }\n \\rVersion: ${ xterm.brightPink(__VERSION) }\n \\r`;\n}\n\n/**\n * The `[xBuild]` tag that marks a line as coming from the build.\n *\n * @returns The tag in light coral\n *\n * @remarks\n * Prepended to log lines so xBuild output stays recognizable when several tools write to the same console.\n *\n * @example\n * ```ts\n * console.log(`${ prefix() } Starting build`); // [xBuild] Starting build\n * ```\n *\n * @since 1.0.0\n */\n\nexport function prefix(): string {\n return xterm.lightCoral('[xBuild]');\n}\n","/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * Style token for a step that finished as it should.\n *\n * @remarks\n * Green.\n * Reserved for an outcome the reader can stop reading at, so a step that merely progressed stays unstyled.\n *\n * @example\n * ```ts\n * console.log(okColor('build finished'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const okColor = xterm.hex('#a6da95');\n\n/**\n * Style token for ordinary body text.\n *\n * @remarks\n * Neutral light.\n * The default weight everything else is read against, so it carries no meaning of its own.\n *\n * @example\n * ```ts\n * console.log(textColor('4 entry points'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const textColor = xterm.hex('#cad3f5');\n\n/**\n * Style token for a notice the reader may act on but need not.\n *\n * @remarks\n * Blue.\n * Distinguished from {@link warnColor} by carrying no fault - it reports what happened rather than what went wrong.\n *\n * @example\n * ```ts\n * console.log(infoColor('watching for changes'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const infoColor = xterm.hex('#91d7e3');\n\n/**\n * Style token for something suspect that did not stop the build.\n *\n * @remarks\n * Yellow.\n * The middle ground between {@link infoColor} and {@link errorColor}, for output worth reading after the run.\n *\n * @example\n * ```ts\n * console.log(warnColor('3 files matched no entry point'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const warnColor = xterm.hex('#eed49f');\n\n/**\n * Style token for a file path, a URL, or a location.\n *\n * @remarks\n * Cyan.\n * Marks the part of a line the reader is most likely to copy, so it stays distinct inside an otherwise styled message.\n *\n * @example\n * ```ts\n * console.log(pathColor('src/index.ts'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const pathColor = xterm.hex('#f5a97f');\n\n/**\n * Style token for a failure.\n *\n * @remarks\n * Red.\n * For an outcome that stopped the work, which keeps it rare enough to still register when it appears.\n *\n * @example\n * ```ts\n * console.log(errorColor('Cannot resolve module'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const errorColor = xterm.hex('#ed8796');\n\n/**\n * Style token for a keyword or an identifier quoted inside a message.\n *\n * @remarks\n * Purple.\n * Picks a name out of surrounding prose the way {@link pathColor} picks out a location.\n *\n * @example\n * ```ts\n * console.log(keywordColor('bundleDeclaration'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const keywordColor = xterm.hex('#c6a0f6');\n\n/**\n * Style token for text that belongs on the line but not at the front of the reader's attention.\n *\n * @remarks\n * Muted gray.\n * For figures that qualify a message rather than carry it, such as a timing or a count.\n *\n * @example\n * ```ts\n * console.log(mutedColor('in 412ms'));\n * ```\n *\n * @since 2.0.0\n */\n\nexport const mutedColor = xterm.hex('#939ab7');\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { LogLevelType } from '@providers/interfaces/log-provider.interface';\n\n/**\n * The three spaces that indent one level of reported detail.\n *\n * @remarks\n * Wide enough to clear the symbol marking the line above,\n * so a message sits under the heading it belongs to rather than against the margin.\n * A code window and a trace are indented twice over, which sets them under the message they explain.\n *\n * @example\n * ```ts\n * `${ Indent }dist/index.js`; // ' dist/index.js'\n * ```\n *\n * @since 3.0.0\n */\n\nexport const Indent = ' ';\n\n/**\n * The width a report is laid out in where the terminal reports none.\n *\n * @remarks\n * A pipe and a log file have no column count to answer with,\n * so the sizes a report sets against the right margin would have nothing to measure from.\n *\n * @example\n * ```ts\n * width(); // 100 - piped, so the terminal reported nothing\n * ```\n *\n * @see width\n * @since 3.0.0\n */\n\nexport const DefaultWidth = 100;\n\n/**\n * How many outputs a build names before the rest are counted rather than listed.\n *\n * @remarks\n * A build of many entry points writes more than a reader wants to scroll,\n * so the largest few are named and what is left becomes one line carrying its count and its size.\n * Reporting at `verbose` lifts the limit rather than raising it.\n *\n * @example\n * ```ts\n * printOutputs(metafile); // the six largest, then '· 12 more'\n * printOutputs(metafile, Infinity); // all of them\n * ```\n *\n * @since 3.0.0\n */\n\nexport const OutputLimit = 6;\n\n/**\n * The fewest rows a terminal can have and still give one up to the status line.\n *\n * @remarks\n * Below this the scrolling region would be shorter than the report it carries,\n * so the line is given up and the terminal keeps all of itself until it is resized larger.\n *\n * @since 3.0.0\n */\n\nexport const MinimumRows = 4;\n\n/**\n * How long the status line waits between repaints, in milliseconds.\n *\n * @remarks\n * The beat is what brings the line back after a terminal is cleared from outside the run,\n * since the row remembers what it drew and would otherwise find nothing to redraw.\n * Short enough to read as immediate, long enough that a resting watch costs a repaint three times a second.\n *\n * @since 3.0.0\n */\n\nexport const RepaintInterval = 300;\n\n/**\n * How long the terminal is given to say where the cursor is, in milliseconds.\n *\n * @remarks\n * A terminal that answers does so at once, so the wait is only ever spent on one that never will,\n * and a run under a terminal like that is taken to have filled the screen.\n *\n * @since 3.0.0\n */\n\nexport const ReportTimeout = 100;\n\n/**\n * The number of bytes in one kilobyte.\n *\n * @remarks\n * Binary rather than decimal, `1024` rather than `1000`,\n * which is what makes a reported size agree with the one a file manager shows.\n *\n * @example\n * ```ts\n * 2048 / Kilobyte; // 2\n * ```\n *\n * @since 3.0.0\n */\n\nexport const Kilobyte = 1024;\n\n/**\n * The number of bytes in one megabyte.\n *\n * @remarks\n * Derived from {@link Kilobyte} rather than written out, so the two cannot drift apart,\n * and binary for the same reason it is.\n *\n * @example\n * ```ts\n * Megabyte / Kilobyte; // 1024\n * ```\n *\n * @see Kilobyte\n * @since 3.0.0\n */\n\nexport const Megabyte = Kilobyte * 1024;\n\n/**\n * The middle dot that separates one part of a line from the next.\n *\n * @remarks\n * A separator rather than a mark, so it stands between two values instead of opening a line,\n * which is what keeps it apart from {@link WarningSymbol}.\n * It also marks the quietest group of messages, where a bare dot is as much as a note deserves.\n *\n * @example\n * ```ts\n * `esm ${ DotSymbol } 12 ms`; // 'esm · 12 ms'\n * ```\n *\n * @since 3.0.0\n */\n\nexport const DotSymbol = '·';\n\n/**\n * The arrow that marks work under way.\n *\n * @remarks\n * Opens the line of a variant while it builds and the line of every output a build wrote,\n * so a reader follows what is happening down the same column.\n * One of {@link SuccessSymbol} or {@link ErrorSymbol} takes its place once the build ends.\n *\n * @example\n * ```ts\n * `${ ArrowSymbol } building esm`; // '→ building esm'\n * ```\n *\n * @since 3.0.0\n */\n\nexport const ArrowSymbol = '→';\n\n/**\n * The cross that marks a failure.\n *\n * @remarks\n * Closes the line of a variant that produced no output, and opens each of its errors,\n * so a run scanned from the left reads its failures without their text.\n *\n * @example\n * ```ts\n * `${ ErrorSymbol } esm`; // '× esm'\n * ```\n *\n * @see SuccessSymbol\n * @since 3.0.0\n */\n\nexport const ErrorSymbol = '×';\n\n/**\n * The circular arrow that marks a rebuild.\n *\n * @remarks\n * Written when a watch starts the build again, beside the reason it restarted,\n * and again on the status line while the watch rests between builds.\n *\n * @example\n * ```ts\n * `${ ReloadSymbol } 2 files changed`; // '↻ 2 files changed'\n * ```\n *\n * @since 3.0.0\n */\n\nexport const ReloadSymbol = '↻';\n\n/**\n * The bullet that marks a warning.\n *\n * @remarks\n * A filled dot rather than a cross, so a warning reads as quieter than a failure\n * and still stands out from a line carrying no mark at all.\n *\n * @example\n * ```ts\n * `${ WarningSymbol } unsupported require call`; // '• unsupported require call'\n * ```\n *\n * @see ErrorSymbol\n * @since 3.0.0\n */\n\nexport const WarningSymbol = '•';\n\n/**\n * The check mark that marks a build that finished clean.\n *\n * @remarks\n * Closes the line of a variant that wrote its output, opposite {@link ErrorSymbol},\n * so the two read as one column of outcomes down the left of a run.\n *\n * @example\n * ```ts\n * `${ SuccessSymbol } esm in 128 ms`; // '✓ esm in 128 ms'\n * ```\n *\n * @see ErrorSymbol\n * @since 3.0.0\n */\n\nexport const SuccessSymbol = '✓';\n\n/**\n * How loud each level is, as a number the levels can be compared by.\n *\n * @remarks\n * A report prints the groups that rank at or above the level the run is set to,\n * which needs an order that the level names do not carry on their own.\n * `silent` ranks above every group, so nothing reaches a run set to it.\n *\n * @example\n * ```ts\n * Levels.warning >= Levels.info; // true - warnings print at the info level\n * Levels.info >= Levels.error; // false - info is quiet at the error level\n * ```\n *\n * @see LogLevelType\n * @since 3.0.0\n */\n\nexport const Levels: Record<LogLevelType, number> = { verbose: 0, info: 1, warning: 2, error: 3, silent: 4 };\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { DeepPartialType } from '@interfaces/types.interface';\nimport type { UnsubscribeType, Observable } from '@remotex-labs/xobservable';\nimport type { ConfigurationInterface } from '@interfaces/configuration.interface';\nimport type { xBuildConfigInterface } from '@providers/interfaces/config-file-provider.interface';\n\n/**\n * Imports\n */\n\nimport { Injectable } from '@remotex-labs/xinject';\nimport { BehaviorSubject } from '@remotex-labs/xobservable';\nimport { deepMerge, equals } from '@components/object.component';\nimport { map, distinctUntilChanged } from '@remotex-labs/xobservable';\nimport { DefaultsCommonConfig } from '@constants/configuration.constant';\n\n/**\n * Holds the build configuration and lets the rest of the build watch it change.\n *\n * @typeParam T - Shape of the configuration, at least a {@link ConfigurationInterface}\n *\n * @remarks\n * The configuration is not settled once and read forever: a watch reloads the file behind it, so whatever depends on\n * a setting has to be told when it moves rather than reading it once at startup.\n * That is what {@link select} is for - it reports only when the value that a caller actually asked for has changed,\n * so a change elsewhere in the configuration wakes nobody.\n * Updates merge rather than replace, so an update says what changes and leaves the rest standing.\n * Registered as a singleton, so every consumer reads and watches the same configuration.\n *\n * @example\n * ```ts\n * const configuration = inject(ConfigurationService);\n *\n * configuration.getValue(config => config.logLevel); // info\n * configuration.select(config => config.variants)\n * .subscribe(variants => rebuild(variants)); // told whenever the variants change\n * configuration.patch({ verbose: true }); // the variant's watcher hears nothing\n * ```\n *\n * @see xBuildConfigInterface\n * @see ConfigurationInterface\n *\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class ConfigurationService<T extends ConfigurationInterface = Required<xBuildConfigInterface>> {\n /**\n * The configuration and everything watching it.\n *\n * @remarks\n * A behavior subject rather than a plain one, so a subscriber arriving late is handed the configuration as it\n * stands instead of waiting for the next change.\n *\n * @since 2.0.0\n */\n\n private readonly config$: BehaviorSubject<T>;\n\n /**\n * Creates the service around a starting configuration.\n *\n * @param initialConfig - Configuration to start from the built-in defaults when omitted\n *\n * @remarks\n * The configuration is copied on the way in, so the object handed over is never written to - which is what makes\n * the frozen defaults usable as a starting point.\n * It is also kept as it was passed, since {@link reload} needs something to return to.\n *\n * @example\n * ```ts\n * const configuration = new ConfigurationService({ variants: { esm: { esbuild: { format: 'esm' } } } });\n * configuration.getValue().variants.esm; // { esbuild: { format: 'esm' } }\n * ```\n *\n * @see DefaultsCommonConfig\n * @since 2.0.0\n */\n\n constructor(private initialConfig: T = DefaultsCommonConfig as T) {\n this.config$ = new BehaviorSubject<T>(deepMerge({}, initialConfig) as T);\n }\n\n /**\n * Reads the whole configuration as it stands.\n *\n * @returns The current configuration\n *\n * @example\n * ```ts\n * configuration.getValue().verbose; // false\n * ```\n *\n * @since 2.0.0\n */\n\n getValue(): T;\n\n /**\n * Reads one value out of the configuration as it stands.\n *\n * @typeParam R - What the selector returns\n * @param selector - Picks the value to read\n * @returns Whatever the selector returned\n *\n * @remarks\n * The one-off counterpart of {@link select}: it answers once and never again, which suits a decision taken at a\n * point in time rather than something that has to follow the configuration.\n *\n * @example\n * ```ts\n * configuration.getValue(config => Object.keys(config.variants)); // [ 'esm', 'cjs' ]\n * ```\n *\n * @since 2.0.0\n */\n\n getValue<R>(selector: (config: T) => R): R;\n\n /**\n * Serves both reading forms.\n *\n * @param selector - Picks a value, or reads the whole configuration when absent\n * @returns The configuration, or what the selector returned\n *\n * @since 2.0.0\n */\n\n getValue<R>(selector?: (config: T) => R): T | R {\n if (!selector)\n return this.config$.value;\n\n return selector(this.config$.value);\n }\n\n /**\n * Watches the whole configuration.\n *\n * @param observer - Called with the configuration, now and on every change\n * @returns A function that stops the watching\n *\n * @remarks\n * Called straight away with the configuration as it stands, so a subscriber needs no separate first read.\n * It hears every change, whatever moved, which is why {@link select} is the better choice for anything that cares\n * about one corner of the configuration.\n *\n * @example\n * ```ts\n * const stop = configuration.subscribe(config => console.log(config.verbose)); // logs at once\n * configuration.patch({ verbose: true }); // logs again\n * stop();\n * ```\n *\n * @see select\n * @since 1.0.0\n */\n\n subscribe(observer: (value: T) => void): UnsubscribeType {\n return this.config$.subscribe(observer);\n }\n\n /**\n * Watches one value in the configuration.\n *\n * @typeParam R - What the selector returns\n * @param selector - Picks the value to watch\n * @returns A stream of that value, reporting only when it has actually changed\n *\n * @remarks\n * The selector runs on every change, but its result is compared against the one before and only a real difference\n * is passed on - so a change elsewhere costs a comparison rather than the work behind a subscriber.\n * The comparison is structural, so a selector that builds an equal object each time still reports nothing.\n *\n * @example\n * ```ts\n * configuration.select(config => config.common?.esbuild?.minify)\n * .subscribe(minify => console.log(minify)); // true, then again only when it changes\n *\n * configuration.patch({ verbose: true }); // nothing reported - minify did not move\n * ```\n *\n * @see equals\n * @see subscribe\n *\n * @since 2.0.0\n */\n\n select<R>(selector: (config: T) => R): Observable<R> {\n return this.config$.pipe(\n map(selector),\n distinctUntilChanged((prev, curr) => equals(prev, curr))\n ) as Observable<R>;\n }\n\n /**\n * Merges changes into the configuration and reports them.\n *\n * @param partial - The parts to change, nested as deeply as needed\n *\n * @remarks\n * Merged over what is there now, so anything left out keeps its value and only the corners named are touched.\n * Arrays are concatenated rather than replaced, so patching a list adds to it - which is a reason to reach for\n * {@link reload} when a list has to be replaced rather than extended.\n * Every subscriber is told, while a {@link select} passes it on only if the value it picked actually moved.\n *\n * @example\n * ```ts\n * configuration.patch({ common: { esbuild: { minify: false } } });\n * configuration.getValue().common?.esbuild?.format; // 'cjs' - untouched\n * ```\n *\n * @see reload\n * @since 1.0.0\n */\n\n patch(partial: DeepPartialType<T>): void {\n const mergedConfig = deepMerge<T>(\n {} as T,\n this.config$.value,\n partial\n );\n\n this.config$.next(mergedConfig);\n }\n\n /**\n * Starts again from the initial configuration, with the given one merged over it.\n *\n * @param config - Configuration to apply over the initial one\n *\n * @remarks\n * Not a replacement: the result is the configuration this service was constructed with,\n * merged with what is passed here.\n * What the initial configuration carried therefore survives, and only what accumulated since is dropped.\n * That is what re-reading an edited file wants, since a patch has no way to take something back.\n * To be rid of the initial configuration too, construct another service.\n *\n * @example\n * ```ts\n * configuration.patch({ verbose: true });\n * configuration.reload({ common: { types: false } });\n * configuration.getValue().verbose; // false again - the patch is gone\n * ```\n *\n * @see patch\n * @since 2.0.0\n */\n\n reload(config: DeepPartialType<T>): void {\n this.config$.next(deepMerge({}, this.initialConfig, config) as T);\n }\n}\n","/**\n * Reports whether a value can be treated as a keyed object.\n *\n * @param item - Value to test\n * @returns `true` when the value is a non-null object that is not an array\n *\n * @remarks\n * Narrows to `Record<string, unknown>`, which is what lets the merge and comparison helpers index a value they were\n * handed as `unknown`.\n * Only arrays and `null` are ruled out, so a `Date`, a `RegExp`, and a class instance all pass - the callers that\n * care treat those specially before asking.\n *\n * @example\n * ```ts\n * isObject({ key: 'value' }); // true\n * isObject(new Date()); // true - an object, whatever else it is\n * isObject([]); // false\n * isObject(null); // false\n * ```\n *\n * @see deepMerge\n * @since 2.0.0\n */\n\nexport function isObject(item: unknown): item is Record<string, unknown> {\n return !!item && typeof item === 'object' && !Array.isArray(item);\n}\n\n/**\n * Reports whether a value is an ordinary keyed object rather than an instance of something.\n *\n * @param item - Value to test\n * @returns `true` when the value is an object literal, or one built with a null prototype\n *\n * @remarks\n * Where {@link isObject} asks whether a value can be indexed, this asks whether walking its keys describes it.\n * A `Date`, a `RegExp`, a `Map`, and a class instance carry their state somewhere other than their own enumerable\n * keys, so merging into a fresh object would leave nothing of them behind.\n * The test is that the prototype is a root of its chain rather than this realm's `Object.prototype`.\n * An object literal built inside a `vm` context therefore counts as plain,\n * which is what a configuration file executed in a sandbox hands back.\n *\n * @example\n * ```ts\n * isPlainObject({ key: 'value' }); // true\n * isPlainObject(Object.create(null)); // true\n * isPlainObject(runInNewContext('({ a: 1 })')); // true - plain, whatever realm built it\n * isPlainObject(/^_/); // false - a value, not a shape\n * isPlainObject(new Date()); // false\n * ```\n *\n * @see isObject\n * @see deepMerge\n *\n * @since 3.0.0\n */\n\nexport function isPlainObject(item: unknown): item is Record<string, unknown> {\n if (!isObject(item)) return false;\n const prototype = Object.getPrototypeOf(item);\n\n return prototype === null || Object.getPrototypeOf(prototype) === null;\n}\n\n/**\n * Merges objects into a target, recursing into nested objects.\n *\n * @typeParam T - Type of the object being merged into\n *\n * @param target - Object the sources are merged into, modified in place\n * @param sources - Objects to merge, applied left to right so a later one wins\n * @returns The target, for chaining\n *\n * @remarks\n * Three rules decide each key: two arrays concatenate, two plain objects merge, and anything else is overwritten.\n * A `Date`, a `RegExp`, a `Map`, and a class instance are values rather than shapes to walk,\n * so they are carried across as they stand.\n * Recursing into such a value would reduce it to a plain object holding whatever its own enumerable keys are.\n * Concatenation rather than replacement means merging the same configuration twice doubles its arrays,\n * so an accumulating merge wants a fresh target each time.\n * That is also the way to use this as a deep copy, by merging into `{}`.\n * The target is modified rather than copied, so pass a literal unless the caller means to have its object rewritten.\n *\n * @example\n * ```ts\n * deepMerge({ a: 1, b: { x: 10 } }, { b: { y: 20 }, c: 3 }); // { a: 1, b: { x: 10, y: 20 }, c: 3 }\n * deepMerge({ items: [ 1, 2 ] }, { items: [ 3 ] }); // { items: [ 1, 2, 3 ] } - concatenated\n * deepMerge({}, { pattern: /^_/ }); // { pattern: /^_/ } - the same regular expression\n * deepMerge({}, config); // a deep copy of config\n * ```\n *\n * @see isObject\n * @see isPlainObject\n *\n * @since 2.0.0\n */\n\nexport function deepMerge<T extends object>(target: T, ...sources: Array<object>): T {\n if (!sources.length) return target;\n const source = sources.shift();\n\n if (isObject(target) && isObject(source)) {\n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (Array.isArray(sourceValue) && Array.isArray(targetValue)) {\n Object.assign(target, { [key]: [ ...targetValue, ...sourceValue ] });\n } else if (isPlainObject(sourceValue)) {\n Object.assign(target, {\n [key]: deepMerge(\n isPlainObject(targetValue) ? targetValue : {},\n sourceValue\n )\n });\n } else {\n Object.assign(target, { [key]: sourceValue });\n }\n }\n\n return deepMerge(target, ...sources);\n }\n\n return target;\n}\n\n/**\n * Compares two values by structure rather than by identity.\n *\n * @param a - First value\n * @param b - Second value\n * @param strictCheck - Whether both sides must have the same number of entries, `true` by default\n * @returns `true` when the two are equal by these rules\n *\n * @remarks\n * `Date`, `RegExp`, and `URL` are compared by what they mean - timestamp, pattern and flags, href - rather than by\n * walking their properties, which would find nothing.\n * `NaN` equals itself here, unlike under `===`.\n * `0` and `-0` compare equal, since strict equality settles them before the question of sign arises.\n * Relaxing `strictCheck` turns the comparison into a subset test: every entry of the first value must appear in the\n * second, and extra entries in the second are ignored.\n *\n * @example\n * ```ts\n * equals(NaN, NaN); // true\n * equals(new Date('2024-01-01'), new Date('2024-01-01')); // true\n * equals({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2 } }); // true\n * equals([ 1, 2 ], [ 1, 2, 3 ], false); // true - a subset\n * equals([ 1, 2 ], [ 1, 2, 3 ]); // false - lengths differ\n * ```\n *\n * @see hasKey\n * @since 2.0.0\n */\n\nexport function equals(a: unknown, b: unknown, strictCheck = true): boolean {\n if (a === b) return true;\n if (Object.is(a, b)) return true;\n if (a === null || b === null) return false;\n\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n\n if (a instanceof RegExp && b instanceof RegExp)\n return a.source === b.source && a.flags === b.flags;\n\n if (URL && a instanceof URL && b instanceof URL)\n return a.href === b.href;\n\n if (typeof a === 'object' && typeof b === 'object') {\n return deepEquals(a, b, strictCheck);\n }\n\n return false;\n}\n\n/**\n * Reports whether a key can be reached on a value.\n *\n * @param obj - Value to look in\n * @param key - Key to look for, a name or a symbol\n * @returns `true` when the key is reachable, own or inherited\n *\n * @remarks\n * Answers for objects and functions only: a primitive returns `false` even where the key would resolve, so\n * `'length'` on a string is not found here.\n * `null` and `undefined` answer `false` rather than throwing, which is the point of asking through this rather than\n * with `in` directly.\n *\n * @example\n * ```ts\n * hasKey({ name: 'test' }, 'name'); // true\n * hasKey({ name: 'test' }, 'age'); // false\n * hasKey(null, 'key'); // false\n * hasKey('string', 'length'); // false - a primitive, not an object\n * ```\n *\n * @since 2.0.0\n */\n\nexport function hasKey(obj: unknown, key: string | symbol): boolean {\n if (obj == null || (typeof obj !== 'object' && typeof obj !== 'function'))\n return false;\n\n return key in obj || Object.prototype.hasOwnProperty.call(obj, key);\n}\n\n/**\n * Compares two objects or arrays entry by entry.\n *\n * @param a - First value\n * @param b - Second value\n * @param strictCheck - Whether both sides must have the same number of entries\n * @returns `true` when every entry of the first matches the second\n *\n * @remarks\n * The recursive half of {@link equals}, which handles the special types before delegating here.\n * Position compares arrays, so the same items in another order are not equal.\n * Objects are walked by the first value's own enumerable keys, which is what makes the relaxed mode a subset test -\n * a key the second value has and the first does not is never looked at.\n *\n * @since 2.0.0\n */\n\nfunction deepEquals(a: object, b: object, strictCheck: boolean = true): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n if(strictCheck && a.length !== b.length) return false;\n\n return a.every((val, i) => equals(val, b[i], strictCheck));\n }\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (strictCheck && aKeys.length !== bKeys.length) return false;\n\n for (const key of aKeys) {\n if (!hasKey(b, key)) return false;\n if (!equals((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key], strictCheck)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Serializes a value to JSON, carrying a `bigint` across as a string.\n *\n * @param value - Value to serialize\n * @returns The JSON text\n *\n * @throws TypeError - Raised when the value holds a circular reference\n *\n * @remarks\n * `JSON.stringify` throws on a `bigint` rather than serializing it, so this converts each to its decimal digits on\n * the way out.\n * The digits are written as a JSON string, since JSON has no number wide enough to hold them,\n * which is what keeps a value past `Number.MAX_SAFE_INTEGER` exact.\n * A reader therefore gets a string back where a `bigint` went in.\n * Everything else behaves as `JSON.stringify` does: an `undefined` property is dropped, a `Map` and a `Set` come out\n * as `{}`, and a `Date` comes out as the string its own `toJSON` produced.\n * A top-level `undefined`, function, or symbol still yields `undefined` rather than text,\n * which the declared return type does not admit.\n *\n * @example\n * ```ts\n * stringify({ id: 9007199254740993n }); // '{\"id\":\"9007199254740993n\"}' - the digits kept exactly\n * stringify({ a: 1, b: [ 1, 2 ] }); // '{\"a\":1,\"b\":[1,2]}'\n * stringify({ a: undefined, b: 1 }); // '{\"b\":1}' - the undefined key dropped\n * stringify(undefined); // undefined - not text, despite the signature\n * ```\n *\n * @since 3.0.0\n */\n\nexport function stringify(value: unknown): string {\n return JSON.stringify(value, (_, entry) => typeof entry === 'bigint' ? entry.toString() + 'n' : entry);\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { PartialConfigurationType } from '@interfaces/configuration.interface';\n\n/**\n * The configuration that a build starts from, before a file or a flag says otherwise.\n *\n * @remarks\n * The object, its `common` block, and its `esbuild` block are each frozen,\n * so nothing can rewrite the defaults for every other consumer that reads them.\n * {@link ConfigurationService} copies it on the way in rather than holding it directly,\n * which is what keeps the freeze from turning an ordinary patch into a failure.\n * `absWorkingDir` is read when this module is first imported, so it records the directory the process started in\n * rather than wherever a later build happens to look.\n *\n * @example\n * ```ts\n * DefaultsCommonConfig.common?.esbuild?.format; // 'cjs'\n * DefaultsCommonConfig.common?.esbuild?.outdir; // 'dist'\n * ```\n *\n * @see ConfigurationService\n * @since 3.0.0\n */\n\nexport const DefaultsCommonConfig: PartialConfigurationType = Object.freeze({\n common: Object.freeze({\n types: true,\n logOverride: {},\n declaration: true,\n esbuild: Object.freeze({\n write: true,\n bundle: true,\n minify: true,\n format: 'cjs',\n outdir: 'dist',\n platform: 'browser',\n absWorkingDir: process.cwd(),\n legalComments: 'none'\n })\n })\n});\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { ModuleResolutionCache, SourceFile } from 'typescript';\nimport type { LanguageService, Diagnostic, Program } from 'typescript';\nimport type { EmitAndSemanticDiagnosticsBuilderProgram } from 'typescript';\nimport type { CacheEntryInterface } from './interfaces/typescript-service.interface';\nimport type { ParsedCommandLine, BuilderProgramHost, ReadBuildProgramHost } from 'typescript';\nimport type { DiagnosticInterface, ResolvedModuleInterface } from './interfaces/typescript-service.interface';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { Injectable } from '@remotex-labs/xinject';\nimport { normalize, relative, dirname } from '@remotex-labs/xmap';\nimport { DeclarationModel } from '@typescript/models/declaration.model';\nimport { LanguageHostService } from '@typescript/services/host.service';\n\n/**\n * One TypeScript project, wrapping its language service, module resolution, and declaration emit.\n *\n * @remarks\n * Everything a build needs from TypeScript comes through here:\n *\n * - **Diagnostics** - {@link check}\n * - **Declaration files** - {@link emit} and {@link emitBundle}\n * - **Specifier resolution** - {@link resolve}\n *\n * Each configuration file gets one shared instance, reference counted,\n * so several consumers naming the same `tsconfig.json` share one language service,\n * and the last {@link dispose} tears it down.\n * The parse forces `emitDeclarationOnly` on,\n * since this asks the compiler for types alone while the bundler produces the JavaScript.\n *\n * @example\n * ```ts\n * const service = inject(TypescriptService, 'tsconfig.json');\n *\n * service.check(); // [] - the project type-checks\n * await service.emit({ index: 'src/index.ts' }); // [ 'D:/app/dist/index.d.ts' ]\n * service.dispose(); // released - torn down once nothing else holds it\n * ```\n *\n * @see DeclarationModel\n * @see LanguageHostService\n *\n * @since 2.0.0\n */\n\n@Injectable({\n factory(path?: string): TypescriptService {\n return TypescriptService.acquire(path);\n }\n})\nexport class TypescriptService {\n /**\n * The language service this project's queries run against.\n *\n * @remarks\n * Backed by {@link languageHostService} and a document registry,\n * so the syntax trees of shared files survive between requests.\n *\n * @example\n * ```ts\n * service.languageService.getProgram()?.getSourceFiles().length; // 214\n * ```\n *\n * @since 2.0.0\n */\n\n readonly languageService: LanguageService;\n\n /**\n * The host the language service reads files and versions through.\n *\n * @remarks\n * Exposed because it owns the tracked file set, which is what decides the program's file list.\n *\n * @example\n * ```ts\n * service.languageHostService.tracked.size; // grows as the language service resolves imports\n * ```\n *\n * @see LanguageHostService\n * @since 2.0.0\n */\n\n readonly languageHostService: LanguageHostService;\n\n /**\n * The live instances, keyed by their normalized configuration path.\n *\n * @remarks\n * Static, so sharing spans the whole process rather than one injector,\n * and each entry carries the reference count that decides when its language service is torn down.\n *\n * @see acquire\n * @since 3.0.0\n */\n\n private static readonly cache = new Map<string, CacheEntryInterface>();\n\n /**\n * The diagnostics of every file checked so far, keyed by the file name the compiler reported.\n *\n * @remarks\n * Only the affected files are recomputed on a {@link check},\n * so the untouched entries here are what makes the result whole-project rather than only-what-changed.\n * The key is the absolute path the compiler reported,\n * so a caller's own names are resolved before they are read back.\n *\n * @see reconcileDiagnostics\n * @since 3.0.0\n */\n\n private readonly diagnosticsCache = new Map<string, Array<DiagnosticInterface>>();\n\n /**\n * The host the builder program reads through.\n *\n * @remarks\n * Routes every read to {@link languageHostService},\n * so the builder sees the same cached content the language service does\n * rather than reaching the disk a second time and disagreeing with it.\n *\n * @since 3.0.0\n */\n\n private readonly builderHost: ReadBuildProgramHost & BuilderProgramHost = {\n createHash: ts.sys.createHash,\n readFile: (file: string, encoding?: BufferEncoding): string | undefined =>\n this.languageHostService.readFile(file, encoding),\n getCurrentDirectory: (): string => ts.sys.getCurrentDirectory(),\n useCaseSensitiveFileNames: (): boolean => ts.sys.useCaseSensitiveFileNames\n };\n\n /**\n * The declaration cache and emitter bound to this project.\n *\n * @remarks\n * Constructed with this service, whose {@link resolve} is what decides which specifiers name project files.\n *\n * @see DeclarationModel\n * @since 3.0.0\n */\n\n private readonly declaration: DeclarationModel;\n\n /**\n * The configuration currently in force, replaced whenever the file behind it is reparsed.\n *\n * @see parseConfig\n * @since 3.0.0\n */\n\n private parsedConfig: ParsedCommandLine;\n\n /**\n * The snapshot version of the configuration file behind the current parse.\n *\n * @remarks\n * Taken from the shared file model, which advances a version whenever the watcher re-reads a file that changed,\n * so comparing it against the version the model now holds tells {@link reload} whether anything needs reparsing.\n *\n * @see reload\n * @since 3.0.0\n */\n\n private configVersion: number;\n\n /**\n * The cache backing {@link resolve}, rebuilt whenever the compiler options change.\n *\n * @see createResolutionCache\n * @since 3.0.0\n */\n\n private resolutionCache: ModuleResolutionCache;\n\n /**\n * The builder program of the last {@link check}, carried forward, so the next check only revisits what changed.\n *\n * @remarks\n * Absent before the first check and after a {@link reload}, either of which makes the next check a full pass.\n *\n * @since 3.0.0\n */\n\n private builder?: EmitAndSemanticDiagnosticsBuilderProgram;\n\n /**\n * Creates a service for one configuration file.\n *\n * @param configPath - Path of the `tsconfig.json` to run against\n *\n * @remarks\n * Prefer injecting the service, which shares and reference counts instances per configuration path.\n * An instance built here stays outside the shared cache, so nothing else can reach it,\n * and {@link dispose} has no hold of its own to release.\n * A configuration that cannot be read does not throw - {@link parseConfig} falls back to a built-in default.\n *\n * @example\n * ```ts\n * const service = new TypescriptService('tsconfig.build.json');\n * service.config.options.emitDeclarationOnly; // true - forced on regardless of the file\n * ```\n *\n * @see acquire\n * @since 3.0.0\n */\n\n constructor(readonly configPath: string = 'tsconfig.json') {\n this.parsedConfig = this.parseConfig();\n this.languageHostService = new LanguageHostService(this.parsedConfig);\n this.configVersion = this.languageHostService.filesCache.touch(this.configPath).version;\n this.resolutionCache = this.createResolutionCache();\n this.languageService = ts.createLanguageService(\n this.languageHostService, ts.createDocumentRegistry(true)\n );\n\n this.declaration = new DeclarationModel(this);\n }\n\n /**\n * Reparses the configuration of every shared instance whose file has changed.\n *\n * @param force - Whether every instance reparses regardless of whether its configuration file has moved\n * @returns The configuration paths reparsed by this call, in the order their instances were acquired\n *\n * @remarks\n * This walks the whole shared cache rather than reaching one instance through a holder.\n * A single call after a watch event covers every project in the process,\n * and a configuration several consumers share is reparsed once rather than once per consumer.\n *\n * Each version comes from the shared file model as it stands rather than from disk,\n * since re-reading a changed file is the watcher's part,\n * so an instance whose configuration has not moved costs a map lookup and nothing more.\n *\n * Forcing skips that comparison and reparses every instance\n * that catches a change the configuration file's own version misses, such as an edit to a file it extends.\n * The cost is the state of every project in the process rather than the state of what moved.\n *\n * A change discards everything the old options fed:\n * the file set, the resolution cache, the cached declarations, the cached diagnostics, and the builder program,\n * so the next {@link check} runs as a full pass.\n * An instance the constructor built rather than the cache is never reached here.\n *\n * @example\n * ```ts\n * const service = inject(TypescriptService, 'tsconfig.json');\n *\n * TypescriptService.reload(); // [] - nothing has been written since the configuration was read\n * TypescriptService.reload(); // [ 'tsconfig.json' ] - reparsed, and service.config describes the edit\n * TypescriptService.reload(true); // [ 'tsconfig.json' ] - reparsed with nothing written since\n * ```\n *\n * @see check\n * @see acquire\n *\n * @since 3.0.0\n */\n\n static reload(force: boolean = false): Array<string> {\n const reloaded: Array<string> = [];\n for (const [ path, entry ] of TypescriptService.cache) {\n if (entry.instance.refresh(force)) reloaded.push(path);\n }\n\n return reloaded;\n }\n\n /**\n * The parsed configuration this service is running against.\n *\n * @returns The compiler options, file names, and raw configuration currently in force\n *\n * @remarks\n * {@link reload} replaces it wholesale,\n * so a reference taken from here describes the configuration as it stood when it was read.\n *\n * @example\n * ```ts\n * service.config.options.rootDir; // 'D:/app' - defaulted to the working directory when the file omits it\n * service.config.fileNames.length; // 42\n * ```\n *\n * @since 3.0.0\n */\n\n get config(): ParsedCommandLine {\n return this.parsedConfig;\n }\n\n /**\n * Type-checks the project and returns the diagnostics of the files named.\n *\n * @param reachable - Files to report on, as the build reaches them, reporting everything checked when omitted\n * @returns Diagnostics of those files, formatted for reporting\n *\n * @remarks\n * Only the files the builder reports as affected are rechecked,\n * their semantic, syntactic, and suggestion diagnostics replacing what was cached for them,\n * while untouched files keep the diagnostics they already had.\n * That is what makes the result whole-project without rechecking it whole.\n * A file matched by the configuration's `exclude` globs is skipped,\n * and a file that has left the program loses its cached diagnostics\n * rather than reporting them against a file that is no longer there.\n *\n * The check covers the program while the report covers `reachable`,\n * which is what lets several variants share one service:\n * the diagnostics are computed once for whatever changed,\n * and each variant reads back the files its own build reaches at the cost of a lookup per file.\n * Narrowing the check instead would consume a file for the variant that saw it first\n * and leave the next one with nothing to report.\n * Each name is resolved as it is read, so a build's own paths serve as they are, relative or absolute.\n *\n * @example\n * ```ts\n * service.check(); // [ { file: 'src/index.ts', line: 3, column: 7, code: 2322, category: 1, message: '...' } ]\n * service.check(); // [] once the file is fixed and the watcher has refreshed it\n *\n * service.check(context.stage.reachableFiles); // only what this variant's build reaches\n * ```\n *\n * @see DiagnosticInterface\n * @see reconcileDiagnostics\n *\n * @since 3.0.0\n */\n\n check(reachable?: Iterable<string>): Array<DiagnosticInterface> {\n const program = this.languageService.getProgram();\n if (!program) return [];\n\n const ignore = this.languageHostService.ignoreSourceFile;\n const skip = (file: SourceFile): boolean => {\n if(file.fileName.includes('node_modules')) return true;\n\n return ignore(file);\n };\n\n let affected;\n this.builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(program, this.builderHost, this.builder);\n while (affected = this.builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, skip)) {\n if ('fileName' in affected.affected) {\n const file = affected.affected;\n this.diagnosticsCache.set(file.fileName, [\n ...affected.result,\n ...this.builder!.getSyntacticDiagnostics(file),\n ...this.languageService.getSuggestionDiagnostics(file.fileName)\n ].map(diagnostic => this.formatDiagnostic(diagnostic)));\n }\n }\n\n return this.reconcileDiagnostics(program, reachable ?? this.diagnosticsCache.keys());\n }\n\n /**\n * Writes one declaration file per project file the entry points reach.\n *\n * @param entryPoints - Entry files to walk, keyed by the output name each entry itself is written under\n * @param outdir - Directory to write into, defaulting to the configuration's `outDir` and then to `dist`\n * @returns The output paths written by this call, empty when everything was already current\n *\n * @remarks\n * This path always passes a directory on, so `declarationDir` is never consulted.\n * Name it explicitly to write somewhere other than `outDir`.\n * The keys name the entries alone, while the files reached through them keep the layout of the source tree.\n * Declarations come out of this project's program, so the checker writes the types the source leaves out,\n * and a type it cannot write surfaces through {@link check} rather than as a failure to write.\n *\n * @example\n * ```ts\n * await service.emit({ index: 'src/index.ts' }); // [ 'dist/index.d.ts', 'dist/builder.d.ts' ] - absolute\n * await service.emit({ index: 'src/index.ts' }); // [] - nothing changed since\n * await service.emit({ index: 'src/index.ts' }, 'types'); // the same files, written under ./types\n * ```\n *\n * @see emitBundle\n * @since 3.0.0\n */\n\n async emit(entryPoints: Record<string, string>, outdir?: string): Promise<Array<string>> {\n outdir ??= this.config.options.outDir ?? 'dist';\n\n return this.declaration.emit(entryPoints, outdir);\n }\n\n /**\n * Writes one bundled declaration file per entry point.\n *\n * @param entryPoints - Entry files to bundle, keyed by the output name each is written under\n * @param outdir - Directory to write into, defaulting to the configuration's `outDir` and then to `dist`\n * @returns The output paths written, in the order the entry points were given\n *\n * @remarks\n * Each entry becomes one file carrying the declarations of everything it reaches,\n * so a package ships a single `.d.ts` instead of a tree mirroring its source.\n * The keys name the outputs, with `.d.ts` appended to each,\n * which is the shape the bundler's own entry points take and what keeps two entries of one name apart.\n * Every call rebuilds its bundles rather than reading a cache, so unlike {@link emit} this always writes.\n *\n * @example\n * ```ts\n * await service.emitBundle({ index: 'src/index.ts' }, 'dist'); // [ 'D:/app/dist/index.d.ts' ]\n * ```\n *\n * @see emit\n * @since 3.0.0\n */\n\n async emitBundle(entryPoints: Record<string, string>, outdir?: string): Promise<Array<string>> {\n outdir ??= this.config.options.outDir ?? 'dist';\n\n return this.declaration.emitBundle(entryPoints, outdir);\n }\n\n /**\n * Re-reads a batch of files so the language service sees their current content.\n *\n * @param files - Paths to refresh, relative or absolute\n *\n * @remarks\n * Each path is tracked as it is refreshed,\n * so naming a file the program has not reached yet adds it rather than passing over it.\n *\n * @example\n * ```ts\n * service.touchFiles([ 'src/index.ts' ]);\n * service.check(); // now reflects what is on disk\n * ```\n *\n * @see LanguageHostService.refreshFiles\n * @since 2.0.0\n */\n\n touchFiles(files: Array<string>): void {\n this.languageHostService.refreshFiles(files);\n }\n\n /**\n * Resolves a specifier the way the type checker resolves it.\n *\n * @param specifier - Module specifier as written in the source\n * @param containingFile - File the specifier was written in, since resolution is relative to its directory\n * @returns The resolved module, or `undefined` when the specifier resolves to nothing\n *\n * @remarks\n * An alias or a `paths` mapping resolves the way the compiler sees it rather than the way Node would,\n * which is what lets the declarations rewrite an alias into a path that still resolves.\n * The result carries two fields beyond what the compiler returns:\n * the directory the specifier resolved against, and the path from that directory to the target.\n * The first resolution attaches both, and the cached entry serves them back.\n * With no containing file, the working directory stands in for it.\n *\n * @example\n * ```ts\n * const module = service.resolve('@components/builder', 'D:/app/src/index.ts');\n *\n * module?.resolvedFileName; // 'D:/app/src/components/builder.ts'\n * module?.relativeFileName; // './components/builder.ts'\n * module?.isExternalLibraryImport; // false - a project file, not a package\n * ```\n *\n * @see ResolvedModuleInterface\n * @since 3.0.0\n */\n\n resolve(specifier: string, containingFile?: string): ResolvedModuleInterface | undefined {\n const container = containingFile ? this.languageHostService.filesCache.resolve(dirname(containingFile)) : process.cwd();\n const dirCache = this.resolutionCache.getOrCreateCacheForDirectory(container);\n const cached = dirCache.get(specifier, undefined)?.resolvedModule;\n if(cached) return cached as ResolvedModuleInterface;\n\n const result = <ResolvedModuleInterface> ts.resolveModuleName(\n specifier, containingFile ?? '', this.parsedConfig.options, this.languageHostService, this.resolutionCache\n ).resolvedModule;\n\n if (result) {\n const path = relative(container, result.resolvedFileName);\n\n result.container = container;\n result.relativeFileName = path.startsWith('.') ? path : `./${ path }`;\n }\n\n return result;\n }\n\n /**\n * Releases this consumer's hold on the shared instance.\n *\n * @remarks\n * The language service is torn down and the instance dropped from the shared cache\n * only once the last holder has released it,\n * so a service several consumers share outlives any one of them.\n * The hold released is the one the shared cache keeps under this service's configuration path,\n * so a release takes effect only on an instance the shared cache holds.\n *\n * @example\n * ```ts\n * const service = inject(TypescriptService);\n *\n * service.dispose(); // released - torn down only if nothing else holds it\n * ```\n *\n * @see acquire\n * @since 3.0.0\n */\n\n dispose(): void {\n const entry = TypescriptService.cache.get(this.configPath);\n if (!entry) return;\n\n entry.refCount--;\n if (entry.refCount > 0) return;\n\n this.languageService.dispose();\n TypescriptService.cache.delete(this.configPath);\n }\n\n /**\n * Releases the service when it leaves a `using` scope.\n *\n * @remarks\n * Delegates to {@link dispose}, so scope-bound and explicit release share one reference count.\n *\n * @example\n * ```ts\n * {\n * using service = inject(TypescriptService);\n * service.check();\n * } // released here\n * ```\n *\n * @see dispose\n * @since 3.0.0\n */\n\n [Symbol.dispose ?? Symbol.for('Symbol.dispose')](): void {\n this.dispose();\n }\n\n /**\n * Returns the shared instance for a configuration path, creating it on the first request.\n *\n * @param path - Path of the `tsconfig.json` the instance runs against\n * @returns The instance for that path, with its reference count raised\n *\n * @remarks\n * The path is normalized before it serves as the key,\n * so the same configuration reached by two spellings is one instance.\n * The instance is constructed with that normalized key,\n * which is what lets a release find its own entry.\n * Reached through the injectable factory rather than called directly.\n *\n * @see dispose\n * @since 3.0.0\n */\n\n private static acquire(path: string = 'tsconfig.json'): TypescriptService {\n const key = normalize(path);\n const entry = TypescriptService.cache.get(key);\n\n if (entry) {\n entry.refCount++;\n\n return entry.instance;\n }\n\n const instance = new TypescriptService(key);\n TypescriptService.cache.set(key, { instance, refCount: 1 });\n\n return instance;\n }\n\n /**\n * Rebuilds everything this instance derives from its compiler options once its configuration file has moved.\n *\n * @param force - Whether the rebuild runs even though the configuration file's version has not moved\n * @returns Whether the configuration was reparsed\n *\n * @remarks\n * Split out of {@link reload}, so the shared cache decides which instance reloads,\n * while the state it rebuilds stays with the instance holding it.\n * The version is the one the shared file model already holds,\n * since re-reading a file that changed is the watcher's part,\n * so this observes a change rather than going looking for one.\n * Forcing drops that guard and rebuilds regardless,\n * which is the only way through for a change the version leaves out.\n * The version is taken and stored either way,\n * so a forced rebuild leaves nothing behind for the next call to mistake for a change.\n *\n * @see reload\n * @since 3.0.0\n */\n\n private refresh(force: boolean = false): boolean {\n const { version } = this.languageHostService.filesCache.touch(this.configPath);\n if (!force && version === this.configVersion) return false;\n\n this.configVersion = version;\n this.parsedConfig = this.parseConfig();\n this.languageHostService.options = this.parsedConfig;\n this.resolutionCache = this.createResolutionCache();\n this.declaration.clear();\n this.diagnosticsCache.clear();\n this.builder = undefined;\n\n return true;\n }\n\n /**\n * Builds the module resolution cache for the current options.\n *\n * @returns A cache keyed the way the language host normalizes paths\n *\n * @remarks\n * Real paths go through the host,\n * so a symlinked file is keyed the same here as in the file cache,\n * and the two cannot disagree about which file a specifier reached.\n *\n * @since 3.0.0\n */\n\n private createResolutionCache(): ModuleResolutionCache {\n return ts.createModuleResolutionCache(\n ts.sys.getCurrentDirectory(),\n path => this.languageHostService.realpath(path),\n this.parsedConfig.options\n );\n }\n\n /**\n * Reads the diagnostics of a set of files out of the cache, dropping whatever no longer belongs to the program.\n *\n * @param program - Program the files are looked up in\n * @param reachable - Files to read, named as the caller has them, relative or absolute\n * @returns The cached diagnostics of those files, in the order they were named\n *\n * @remarks\n * The walk covers the files asked for rather than the cache,\n * so reporting one variant's inputs costs what that variant reaches rather than what the project holds.\n * Each name is resolved before the lookup,\n * since the cache is keyed by the absolute path the compiler reported,\n * while a build names its inputs relative to its own working directory.\n * A file that leaves the program - deleted, excluded, or no longer reached -\n * would otherwise keep reporting the diagnostics it had when it left,\n * since nothing marks it affected once it is gone,\n * so a name the program no longer carries is dropped from the cache as it is read.\n *\n * @since 3.0.0\n */\n\n private reconcileDiagnostics(program: Program, reachable: Iterable<string>): Array<DiagnosticInterface> {\n const files = this.languageHostService.filesCache;\n const result: Array<DiagnosticInterface> = [];\n\n for (const name of reachable) {\n const path = files.resolve(name);\n const diagnostics = this.diagnosticsCache.get(path);\n\n if (!diagnostics) continue;\n if (program.getSourceFile(path)) result.push(...diagnostics);\n else this.diagnosticsCache.delete(path);\n }\n\n return result;\n }\n\n /**\n * Reduces a compiler diagnostic to the shape that reporting consumes.\n *\n * @param diagnostic - Diagnostic as the compiler produced it\n * @returns The message and category, with the position and code when the diagnostic has a location\n *\n * @remarks\n * Chained messages are flattened into one string, and line and column are counted from one rather than from zero,\n * since the compiler counts from zero while every editor and terminal reports from one.\n * A diagnostic with no file - a configuration error, say - carries the message and category alone.\n *\n * @see DiagnosticInterface\n * @since 2.0.0\n */\n\n private formatDiagnostic(diagnostic: Diagnostic): DiagnosticInterface {\n const result: DiagnosticInterface = {\n message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n'),\n category: diagnostic.category\n };\n\n if (diagnostic.file && diagnostic.start !== undefined) {\n const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n result.file = diagnostic.file.fileName;\n result.line = line + 1;\n result.column = character + 1;\n result.code = diagnostic.code;\n }\n\n return result;\n }\n\n /**\n * Reads the configuration file and forces the options this build depends on.\n *\n * @returns The parsed configuration, with the forced options applied\n *\n * @remarks\n * Declaration emit is forced on and source maps off,\n * since this asks the compiler for types alone while the bundler produces the JavaScript.\n * `stripInternal` and `skipLibCheck` follow from that.\n * A configuration that cannot be read yields a built-in default rather than an error,\n * so a project without a `tsconfig.json` still type-checks under sensible settings.\n * `rootDir` falls back to the working directory,\n * without which output paths would follow whichever directory the sources happen to share.\n *\n * @since 2.0.0\n */\n\n private parseConfig(): ParsedCommandLine {\n let config = ts.getParsedCommandLineOfConfigFile(\n this.configPath,\n {\n sourceMap: false,\n skipLibCheck: true,\n stripInternal: true,\n declarationMap: false,\n emitDeclarationOnly: true\n },\n {\n ...ts.sys,\n onUnRecoverableConfigFileDiagnostic: () => {}\n }\n );\n\n if (!config) {\n config = {\n options: {\n strict: true,\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.NodeNext,\n sourceMap: false,\n skipLibCheck: true,\n stripInternal: true,\n declarationMap: false,\n emitDeclarationOnly: true,\n moduleResolution: ts.ModuleResolutionKind.NodeNext\n },\n errors: [],\n fileNames: [],\n projectReferences: undefined\n };\n }\n\n config.options = {\n ...config.options,\n noEmit: true,\n rootDir: config.options?.rootDir ?? process.cwd(),\n isolatedModules: false,\n useCaseSensitiveFileNames: true\n };\n\n return config;\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { TypescriptService } from '@typescript/services/typescript.service';\nimport type { DeclarationEntryInterface } from './interfaces/declaration-model.interface';\nimport type { NamedBindingInterface, ParseContextInterface } from './interfaces/declaration-model.interface';\nimport type { Declaration, Directive, ModuleExportName, Statement, StringLiteral } from '@oxc-project/types';\nimport type { BundleSurfaceInterface, MergedImportInterface } from './interfaces/declaration-model.interface';\nimport type { ExportNamedDeclaration, ImportDeclaration, TSImportEqualsDeclaration } from '@oxc-project/types';\nimport type { ExportAllDeclaration, ExportDefaultDeclaration, ExportDefaultDeclarationKind } from '@oxc-project/types';\n\n/**\n * Imports\n */\n\nimport { existsSync } from 'fs';\nimport { parseSync } from 'oxc-parser';\nimport { inject } from '@remotex-labs/xinject';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { Char } from '@constants/char.constant';\nimport { FilesModel } from '@models/files.model';\nimport { join, dirname, relative } from '@remotex-labs/xmap';\nimport { applyEdits, removeNode } from '@components/transformer.component';\nimport { HeaderDeclarationBundle } from '@typescript/constants/typescript.constant';\n\n/**\n * Builds and caches the declaration of every file a build touches, in both the forms it needs.\n *\n * @remarks\n * Each file is reduced to a {@link DeclarationEntryInterface}: the standalone declaration with its project specifiers\n * resolved, the same text stripped down to inlinable declarations, and the dependency, import, and export records that\n * stripping produced.\n * Declarations are emitted by the project's own program, so the checker writes the types an annotation leaves out,\n * and an entry costs one declaration emit and one parse.\n * Both forms and every record come out of that single parse.\n * Entries are held against the snapshot version of their file,\n * so a file is rebuilt only once the file model has observed the change,\n * and {@link clear} drops the cache when the compiler options behind the entries move.\n * One instance owns one cache,\n * so a build that wants entries shared across its steps passes the model around rather than constructing a second one.\n *\n * @example\n * ```ts\n * const declarations = new DeclarationModel(inject(TypescriptService));\n * const entry = declarations.touch('src/index.ts');\n *\n * entry.content; // 'declare const version: string;\\n'\n * entry.declaration; // the same text, prefixed with its imports\n * entry.projectDependencies; // Set { 'D:/app/src/builder.ts' }\n * declarations.touch('src/index.ts') === entry; // true - unchanged file, cached entry\n * ```\n *\n * @see DeclarationEntryInterface\n * @since 3.0.0\n */\n\nexport class DeclarationModel {\n /**\n * Entries keyed by the resolved absolute path of the file they describe.\n *\n * @remarks\n * Exposed for consumers that walk an already-built graph.\n * Use {@link touch} to build or refresh an entry.\n *\n * @example\n * ```ts\n * declarations.touch('src/index.ts');\n * declarations.cache.size; // 1\n * ```\n *\n * @see DeclarationEntryInterface\n * @since 3.0.0\n */\n\n readonly cache = new Map<string, DeclarationEntryInterface>();\n\n /**\n * Shared file snapshot cache the entries are versioned against.\n *\n * @since 3.0.0\n */\n\n private readonly filesCache = inject(FilesModel);\n\n /**\n * Entry version last written to each output path.\n *\n * @remarks\n * Keyed by output path rather than source path,\n * so emitting into a different directory writes every file again instead of reporting them as already current.\n * What it records is what was written rather than what is on disk,\n * so {@link emit} checks the file is still there before it passes over one,\n * which is what makes an output that something else removed come back on the next run.\n *\n * @since 3.0.0\n */\n\n private readonly emitted = new Map<string, number>();\n\n /**\n * Creates a declaration cache bound to one TypeScript service.\n *\n * @param ts - Service whose module resolution decides which specifiers are project files\n *\n * @example\n * ```ts\n * const declarations = new DeclarationModel(inject(TypescriptService));\n * declarations.cache.size; // 0\n * ```\n *\n * @see TypescriptService\n * @since 3.0.0\n */\n\n constructor(private readonly ts: TypescriptService) {}\n\n /**\n * Drops every cached entry.\n *\n * @remarks\n * Needed when something the declarations depend on has changed without the snapshot versions reflecting it -\n * the compiler options, or the resolution cache behind them.\n * A file whose content changed does not need this, since its entry is rebuilt on the next {@link touch}.\n * The record of what already reached the disk goes with them,\n * so the next call to {@link emit} writes every file again,\n * which is also what a cleaned output directory calls for.\n *\n * @example\n * ```ts\n * declarations.touch('src/index.ts');\n * declarations.clear();\n * declarations.cache.size; // 0\n * ```\n *\n * @see touch\n * @since 3.0.0\n */\n\n clear(): void {\n this.cache.clear();\n this.emitted.clear();\n }\n\n /**\n * Returns the declaration entry of a file, building it only when the cached one is stale.\n *\n * @param path - Filesystem path of the file, relative or absolute\n * @returns The entry describing the file's declarations, dependencies, and exports\n *\n * @remarks\n * The file is tracked through the file model, so a path never seen before is read from the disk once,\n * and a tracked path costs a map lookup.\n * The cached entry is returned whenever its version still matches the file's snapshot version, which only advances\n * when the file model observes a change on disk.\n * A file that is missing or unreadable yields an entry built from empty content rather than throwing.\n *\n * @example\n * ```ts\n * const entry = declarations.touch('src/index.ts');\n * entry.version; // 1\n * declarations.touch('src/index.ts') === entry; // true\n * ```\n *\n * @see clear\n * @see DeclarationEntryInterface\n *\n * @since 3.0.0\n */\n\n touch(path: string): DeclarationEntryInterface {\n const target = this.filesCache.resolve(path);\n const file = this.filesCache.touch(target);\n const cached = this.cache.get(target);\n\n if (cached?.version === file.version) return cached;\n\n const entry = this.build(target, file.version);\n this.cache.set(target, entry);\n\n return entry;\n }\n\n /**\n * Writes one declaration file per project file the entry points reach, skipping what has not changed.\n *\n * @param entryPoints - Entry files to walk, keyed by the output name each entry itself is written under\n * @param outdir - Directory to write into, overriding the configuration's `declarationDir` and `outDir`\n * @returns The output paths written by this call, empty when everything was already current\n *\n * @remarks\n * The walk follows the dependency edges out of each entry, so a project whose `tsconfig.json` lists only its entry\n * points still emits every file those entries reach.\n * Nothing outside the project is emitted, since only project files are edges,\n * and a `.d.ts` input is skipped along with everything only it reaches - it is already a declaration.\n * A key names the output of the entry it is keyed to and of nothing else.\n * The files reached through it keep mirroring the source tree the way `tsc` lays them out:\n * `declarationDir` wins over `outDir`, and the per-file path is taken relative to `rootDir`.\n * A file whose entry was written unchanged since the last call is left alone, so a watch cycle rewrites only what\n * moved.\n *\n * @example\n * ```ts\n * await declarations.emit({ main: 'src/index.ts' }); // [ 'dist/main.d.ts', 'dist/builder.d.ts' ]\n * await declarations.emit({ main: 'src/index.ts' }); // [] - nothing changed\n * await declarations.emit({ main: 'src/index.ts' }, './types'); // the same files, written under ./types\n * ```\n *\n * @see clear\n * @see emitBundle\n *\n * @since 3.0.0\n */\n\n async emit(entryPoints: Record<string, string>, outdir?: string): Promise<Array<string>> {\n const outputs: Array<string> = [];\n const contents: Array<string> = [];\n const visited = new Set<string>();\n const names = new Map<string, string>();\n\n for (const [ name, entry ] of Object.entries(entryPoints))\n names.set(this.filesCache.resolve(entry), name);\n\n const pending = [ ...names.keys() ];\n while (pending.length > 0) {\n const target = pending.pop()!;\n if (visited.has(target) || target.endsWith('.d.ts')) continue;\n visited.add(target);\n\n const entry = this.touch(target);\n for (const dependency of entry.projectDependencies)\n if (!visited.has(dependency)) pending.push(dependency);\n\n const output = this.outputPath(target, outdir, names.get(target));\n if (this.emitted.get(output) === entry.version && existsSync(output)) continue;\n\n this.emitted.set(output, entry.version);\n outputs.push(output);\n contents.push(entry.declaration);\n }\n\n return this.write(outputs, contents);\n }\n\n /**\n * Bundles every entry point and writes each one to a declaration file of its own.\n *\n * @param entryPoints - Entry files to bundle, keyed by the output name each is written under\n * @param outdir - Directory to write into, overriding the configuration's `declarationDir` and `outDir`\n * @returns The output paths written, in the order the entry points were given\n *\n * @remarks\n * The key names the output rather than the source doing so, `.d.ts` being appended to it, so two entries both\n * called `index.ts` are told apart by the names they were keyed under.\n * A key carrying a directory writes into it, and the directory is created if it is not there.\n * Bundles are always rebuilt, since assembling one from cached entries costs little,\n * and they open with {@link HeaderDeclarationBundle} so a generated file is recognizable as one.\n * With no output directory configured or passed, they land in the working directory.\n *\n * @example\n * ```ts\n * await declarations.emitBundle({ index: 'src/index.ts', 'utils/index': 'src/utils/index.ts' }, 'dist/types');\n * // [ 'D:/app/dist/types/index.d.ts', 'D:/app/dist/types/utils/index.d.ts' ]\n * ```\n *\n * @see emit\n * @since 3.0.0\n */\n\n async emitBundle(entryPoints: Record<string, string>, outdir?: string): Promise<Array<string>> {\n const options = this.ts.config.options;\n const base = this.filesCache.resolve(outdir ?? options.declarationDir ?? options.outDir ?? '.');\n\n return this.write(\n Object.keys(entryPoints).map(name => join(base, `${ name }.d.ts`)),\n Object.values(entryPoints).map(entry => this.bundle(entry))\n );\n }\n\n /**\n * Builds the bundled declaration text of one entry point.\n *\n * @param entry - Filesystem path of the entry file, relative or absolute\n * @returns The complete declaration file content, header included\n *\n * @remarks\n * Nothing is written and nothing is cached beyond the entries themselves, so the same entry can be bundled\n * repeatedly, and each call reflects the files as the cache currently sees them.\n * Declarations are inlined once per file even when several files depend on it, and a dependency cycle is walked\n * once rather than followed around.\n *\n * @see render\n * @since 3.0.0\n */\n\n private bundle(entry: string): string {\n const target = this.filesCache.resolve(entry);\n const node = this.touch(target);\n\n return this.render(this.collectClosure(target, node), this.collectSurface(target, node));\n }\n\n /**\n * Creates the directories of a batch and writes its files concurrently.\n *\n * @param outputs - Absolute output paths to write\n * @param contents - Content of each output, in the same order\n * @returns The written paths, for direct return by callers\n *\n * @remarks\n * Each directory is created once for the whole batch rather than once per file, and an empty batch touches the disk\n * not at all.\n *\n * @since 3.0.0\n */\n\n private async write(outputs: Array<string>, contents: Array<string>): Promise<Array<string>> {\n if (outputs.length < 1) return outputs;\n\n const directories = new Set(outputs.map(output => dirname(output)));\n await Promise.all([ ...directories ].map(directory => mkdir(directory, { recursive: true })));\n await Promise.all(outputs.map((output, index) => writeFile(output, contents[index], 'utf-8')));\n\n return outputs;\n }\n\n /**\n * Maps a source path to the declaration path it is written to.\n *\n * @param source - Resolved absolute path of the source file\n * @param outdir - Directory overriding both configured output directories\n * @param name - Output name to use instead of the one the source implies, carrying no extension\n * @returns The absolute output path\n *\n * @remarks\n * The directory is the first of `outdir`, `declarationDir`, and `outDir` that is set,\n * and the source's own directory only when none of them is.\n * A name replaces everything the source would have decided, `.d.ts` being appended to it, and a name carrying a\n * directory nests the output inside the base.\n * Without one the path mirrors the source tree relative to `rootDir` - the source directory standing in when no\n * `rootDir` is set, which flattens the output the way `tsc` does - and the extension follows the input, so `.ts`\n * and `.tsx` become `.d.ts` while `.mts` and `.cts` keep their module flavor as `.d.mts` and `.d.cts`.\n *\n * @since 3.0.0\n */\n\n private outputPath(source: string, outdir?: string, name?: string): string {\n const { declarationDir, outDir, rootDir } = this.ts.config.options;\n const base = outdir ?? declarationDir ?? outDir;\n const target = base ? this.filesCache.resolve(base) : dirname(source);\n if (name) return join(target, `${ name }.d.ts`);\n\n const root = rootDir ? this.filesCache.resolve(rootDir) : dirname(source);\n\n return join(target, relative(root, source).replace(/\\.([cm]?)tsx?$/, '.d.$1ts'));\n }\n\n /**\n * Collects every project file the entry reaches, dependencies first.\n *\n * @param target - Resolved absolute path of the entry file\n * @param entry - Cache entry of the entry file\n * @returns The entries to inline, in the order their content is concatenated\n *\n * @remarks\n * A depth-first walk over the dependency edges with an explicit stack, so a deep dependency chain cannot overflow\n * the stack, and a visited set, so a cycle terminates, and a shared dependency is inlined once.\n * The entry counts as visited from the start, so a dependency cycling back to it does not inline it twice, and it\n * lands last regardless, which keeps the file the bundle describes at the bottom.\n *\n * @since 3.0.0\n */\n\n private collectClosure(target: string, entry: DeclarationEntryInterface): Array<DeclarationEntryInterface> {\n const visited = new Set<string>([ target ]);\n const closure: Array<DeclarationEntryInterface> = [];\n const pending = [ ...entry.projectDependencies ];\n\n while (pending.length > 0) {\n const dependency = pending.pop()!;\n if (visited.has(dependency)) continue;\n visited.add(dependency);\n\n const node = this.touch(dependency);\n closure.push(node);\n\n for (const nested of node.projectDependencies)\n if (!visited.has(nested)) pending.push(nested);\n }\n\n closure.push(entry);\n\n return closure;\n }\n\n /**\n * Collects the names and re-export statements the bundle exposes.\n *\n * @param target - Resolved absolute path of the entry file\n * @param entry - Cache entry of the entry file\n * @returns The entry's surface, merged with the surface of every project file it star re-exports\n *\n * @remarks\n * Star re-exports of project files are followed transitively, their names becoming the entry's own, while package\n * re-exports are kept as statements and passed straight through.\n * The entry counts as visited from the start, so a star re-export cycling back to it is not walked again.\n * Namespace re-exports of project files are left out: flattening one would mean synthesizing a `declare namespace`\n * around the target's exports, which the inlined fragments do not describe well enough.\n *\n * @see BundleSurfaceInterface\n * @since 3.0.0\n */\n\n private collectSurface(target: string, entry: DeclarationEntryInterface): BundleSurfaceInterface {\n const exports = new Set<string>();\n const statements = new Set<string>();\n const visited = new Set<string>([ target ]);\n const pending = [ entry ];\n\n while (pending.length > 0) {\n const node = pending.pop()!;\n for (const binding of node.projectExports.exports) exports.add(this.clause(binding));\n\n for (const [ module, bindings ] of Object.entries(node.packageExports)) {\n if (bindings.star) statements.add(`export * from '${ module }';`);\n if (bindings.named?.length)\n statements.add(`export { ${ bindings.named.map(binding => this.clause(binding)).join(', ') } } from '${ module }';`);\n\n for (const name of bindings.namespaces ?? []) statements.add(`export * as ${ name } from '${ module }';`);\n }\n\n for (const star of node.projectExports.star) {\n if (visited.has(star)) continue;\n visited.add(star);\n pending.push(this.touch(star));\n }\n }\n\n return { exports, statements };\n }\n\n /**\n * Merges the package imports of every inlined file into one record per module.\n *\n * @param closure - Entries whose content the bundle carries\n * @returns The merged bindings, keyed by module specifier in first-seen order\n *\n * @remarks\n * One pass over the files and their modules folds each module's side effect flag, default binding, namespaces,\n * and named bindings into a single record the bundle can write back as statements.\n *\n * @see MergedImportInterface\n * @since 3.0.0\n */\n\n private mergeImports(closure: Array<DeclarationEntryInterface>): Map<string, MergedImportInterface> {\n const merged = new Map<string, MergedImportInterface>();\n\n for (const node of closure) {\n for (const [ module, bindings ] of Object.entries(node.packageImports)) {\n let entry = merged.get(module);\n if (!entry) merged.set(module, entry = { side: false, named: new Set(), namespaces: new Set() });\n\n if (bindings.side) entry.side = true;\n entry.default ??= bindings.default;\n for (const name of bindings.namespaces ?? []) entry.namespaces.add(name);\n for (const binding of bindings.named ?? []) entry.named.add(this.clause(binding));\n }\n }\n\n return merged;\n }\n\n /**\n * Writes the merged imports back out as import statements.\n *\n * @param merged - Bindings collected per module\n * @returns One statement per import form a module was used with\n *\n * @remarks\n * A module can need several statements: a side effect import, one for each namespace binding,\n * and one carrying its default and named bindings together.\n * Named bindings are sorted, so the same set of files always produces the same bundle.\n *\n * @since 3.0.0\n */\n\n private renderImports(merged: Map<string, MergedImportInterface>): Array<string> {\n const statements: Array<string> = [];\n\n for (const [ module, entry ] of merged) {\n if (entry.side) statements.push(`import '${ module }';`);\n for (const name of entry.namespaces) statements.push(`import * as ${ name } from '${ module }';`);\n\n const clauses: Array<string> = [];\n if (entry.default) clauses.push(entry.default);\n if (entry.named.size > 0) clauses.push(`{ ${ [ ...entry.named ].sort().join(', ') } }`);\n if (clauses.length > 0) statements.push(`import ${ clauses.join(', ') } from '${ module }';`);\n }\n\n return statements;\n }\n\n /**\n * Assembles the finished bundle from its header, imports, inlined content, and exports.\n *\n * @param closure - Entries to inline, dependencies first\n * @param surface - Names and statements the bundle exposes\n * @returns The complete declaration file content\n *\n * @remarks\n * Imports are merged over the whole closure rather than the surface, since every inlined declaration is free to\n * reference them, while the exports come from the surface alone.\n * A bundle that exposes nothing still closes with an empty export clause, without which its declarations would be\n * read as globals rather than as a module.\n *\n * @see HeaderDeclarationBundle\n * @since 3.0.0\n */\n\n private render(closure: Array<DeclarationEntryInterface>, surface: BundleSurfaceInterface): string {\n const parts: Array<string> = [ HeaderDeclarationBundle ];\n const imports = this.renderImports(this.mergeImports(closure));\n if (imports.length > 0) parts.push(...imports, '');\n\n for (const node of closure) {\n const content = node.content.trim();\n if (content) parts.push(content, '');\n }\n\n if (surface.exports.size > 0) parts.push(`export {\\n\\t${ [ ...surface.exports ].sort().join(',\\n\\t') }\\n};`);\n parts.push(...surface.statements);\n if (surface.exports.size < 1 && surface.statements.size < 1) parts.push('export {};');\n\n return `${ parts.join('\\n') }\\n`;\n }\n\n /**\n * Writes a binding the way an import or export clause spells it.\n *\n * @param binding - Name and the alias it was renamed to, if any\n * @returns The bare name, or `name as alias` when the clause renamed it\n *\n * @see NamedBindingInterface\n * @since 3.0.0\n */\n\n private clause(binding: NamedBindingInterface): string {\n return binding.alias ? `${ binding.name } as ${ binding.alias }` : binding.name;\n }\n\n /**\n * Emits the declarations of one file through the project's program.\n *\n * @param target - Resolved absolute path of the file\n * @returns The emitted declaration text, empty when the program reaches the file not at all\n *\n * @remarks\n * The emit runs against the shared program, so the checker supplies whatever an annotation leaves out\n * rather than every exported symbol having to spell its own type.\n * `forceDtsEmit` is what returns the text at all, since the parsed configuration forces `noEmit` on\n * to keep the compiler off the disk the bundler writes to.\n * A path the program has not reached is tracked and the program asked once more,\n * which covers a file the build reaches while `tsconfig.json` neither lists nor includes it.\n * A path its `exclude` globs match stays out even then, and yields no declarations rather than an error.\n *\n * @since 3.0.0\n */\n\n private emitDeclaration(target: string): string {\n const service = this.ts.languageService;\n\n if (!service.getProgram()?.getSourceFile(target)) {\n this.ts.touchFiles([ target ]);\n if (!service.getProgram()?.getSourceFile(target)) return '';\n }\n\n return service.getEmitOutput(target, true, true)\n .outputFiles.find(file => file.name.endsWith('.d.ts'))?.text ?? '';\n }\n\n /**\n * Emits the declarations of one file and reduces them to a cache entry.\n *\n * @param target - Resolved absolute path of the file\n * @param version - Snapshot version the entry is recorded against\n * @returns The freshly built entry\n *\n * @remarks\n * The emitted text is parsed once, and that parse drives everything: the statement walk queues both edit lists and\n * records the graph, and the comment walk that follows it queues the doc comments the stripping orphaned.\n * Emit diagnostics are not surfaced here - a declaration the checker cannot write is reported against the source\n * file itself by {@link TypescriptService.check}.\n *\n * @see strip\n * @see emitDeclaration\n * @see pruneComments\n *\n * @since 3.0.0\n */\n\n private build(target: string, version: number): DeclarationEntryInterface {\n // const declaration = isolatedDeclarationSync(target, source, { stripInternal: true }).code;\n const declaration = this.emitDeclaration(target);\n const context: ParseContextInterface = {\n edits: [],\n target,\n parsed: parseSync(target, declaration, { sourceType: 'module' }),\n content: declaration,\n bundleEdits: [],\n packageImports: Object.create(null),\n packageExports: Object.create(null),\n projectExports: { star: new Set(), exports: [], namespace: Object.create(null) },\n projectDependencies: new Set()\n };\n\n const kept: Array<number> = [];\n const { body } = context.parsed.program;\n\n for (const statement of body)\n if (this.strip(statement, context)) kept.push(statement.start);\n\n this.pruneComments(context, body, kept);\n\n return {\n version,\n content: applyEdits(declaration, context.bundleEdits),\n declaration: applyEdits(declaration, context.edits),\n packageImports: context.packageImports,\n packageExports: context.packageExports,\n projectExports: context.projectExports,\n projectDependencies: context.projectDependencies\n };\n }\n\n /**\n * Dispatches one top-level statement to the handler for its module syntax.\n *\n * @param statement - Statement to strip\n * @param context - Pass the edits are queued against and the bindings recorded on\n * @returns Whether the statement survives in the stripped content\n *\n * @remarks\n * Only top-level statements are visited, since only those can carry module syntax.\n * `export =` and `export as namespace` are dropped without a record: both describe how a module is consumed whole,\n * which a fragment inlined into a bundle can no longer express.\n * Anything that is not module syntax is kept untouched.\n *\n * @since 3.0.0\n */\n\n private strip(statement: Directive | Statement, context: ParseContextInterface): boolean {\n switch (statement.type) {\n case 'ImportDeclaration':\n this.stripImport(statement, context);\n\n return false;\n\n case 'ExportAllDeclaration':\n this.stripStarExport(statement, context);\n\n return false;\n\n case 'ExportNamedDeclaration':\n return this.stripNamedExport(statement, context);\n\n case 'ExportDefaultDeclaration':\n return this.stripDefaultExport(statement, context);\n\n case 'TSImportEqualsDeclaration':\n return this.stripImportEquals(statement, context);\n\n case 'TSExportAssignment':\n case 'TSNamespaceExportDeclaration':\n removeNode(statement, context.content, context.bundleEdits);\n\n return false;\n\n default:\n return true;\n }\n }\n\n /**\n * Removes an `import` statement, recording either a dependency or the package bindings it pulled in.\n *\n * @param statement - Import statement to strip\n * @param context - Pass the deletion is queued against\n *\n * @remarks\n * An import of a project file only contributes an edge, since the target's declarations are inlined,\n * and its bindings are already in scope in the bundle.\n * Everything else is recorded per module, so the bundle can reissue one import statement for it.\n *\n * @see link\n * @since 3.0.0\n */\n\n private stripImport(statement: ImportDeclaration, context: ParseContextInterface): void {\n removeNode(statement, context.content, context.bundleEdits);\n if (this.link(statement.source, context)) return;\n\n const module = context.packageImports[statement.source.value] ??= {};\n if (statement.specifiers.length < 1) {\n module.side = true;\n\n return;\n }\n\n for (const entry of statement.specifiers) {\n switch (entry.type) {\n case 'ImportDefaultSpecifier':\n module.default ??= entry.local.name;\n break;\n\n case 'ImportNamespaceSpecifier':\n (module.namespaces ??= []).push(entry.local.name);\n break;\n\n default:\n (module.named ??= []).push(this.binding(this.nameOf(entry.imported), entry.local.name));\n }\n }\n }\n\n /**\n * Removes an `import x = require('module')` statement the way its ESM equivalent is removed.\n *\n * @param statement - Import-equals statement to strip\n * @param context - Pass the deletion is queued against\n * @returns Whether the statement survives in the stripped content\n *\n * @remarks\n * Only the external-module form names a module.\n * `import A = B.C` aliases a local name and is kept as it stands, since the namespace it reaches into is inlined\n * with the rest of the fragment.\n * A package binding is recorded as a namespace import, which is what `require` binds in type space.\n *\n * @see stripImport\n * @since 3.0.0\n */\n\n private stripImportEquals(statement: TSImportEqualsDeclaration, context: ParseContextInterface): boolean {\n const { moduleReference } = statement;\n if (moduleReference.type !== 'TSExternalModuleReference') return true;\n\n removeNode(statement, context.content, context.bundleEdits);\n const source = moduleReference.expression;\n\n if (!this.link(source, context))\n ((context.packageImports[source.value] ??= {}).namespaces ??= []).push(statement.id.name);\n\n return false;\n }\n\n /**\n * Strips an `export` that carries a declaration, a specifier list, or a re-export clause.\n *\n * @param statement - Named export statement to strip\n * @param context - Pass the edits are queued against\n * @returns Whether the statement survives in the stripped content\n *\n * @remarks\n * A declaration keeps its body and loses only the `export` keyword, so `export declare const x` becomes\n * `declare const x` and stays valid where the fragment lands.\n * A specifier list is removed outright: names re-exported from a project file, or from nothing at all, are recorded\n * as this file's own surface, since the declarations behind them are inlined.\n * Only a clause pointing at a package is recorded as a re-export the bundle has to emit again.\n *\n * @see collectDeclared\n * @since 3.0.0\n */\n\n private stripNamedExport(statement: ExportNamedDeclaration, context: ParseContextInterface): boolean {\n const { exports } = context.projectExports;\n\n if (statement.declaration) {\n this.collectDeclared(statement.declaration, exports);\n context.bundleEdits.push({ start: statement.start, end: statement.declaration.start });\n\n return true;\n }\n\n removeNode(statement, context.content, context.bundleEdits);\n const named = statement.source && !this.link(statement.source, context)\n ? (context.packageExports[statement.source.value] ??= {}).named ??= []\n : exports;\n\n for (const entry of statement.specifiers)\n named.push(this.binding(this.nameOf(entry.local), this.nameOf(entry.exported)));\n\n return false;\n }\n\n /**\n * Removes an `export *` statement, recording the module or project file behind it.\n *\n * @param statement - Star export statement to strip\n * @param context - Pass the deletion is queued against\n *\n * @remarks\n * A star export of a project file becomes an edge plus an entry the bundler follows to collect the names it\n * exposes, whereas a namespace form records the name it is exposed under instead.\n *\n * @see link\n * @since 3.0.0\n */\n\n private stripStarExport(statement: ExportAllDeclaration, context: ParseContextInterface): void {\n removeNode(statement, context.content, context.bundleEdits);\n\n const target = this.link(statement.source, context);\n const exposed = statement.exported ? this.nameOf(statement.exported) : null;\n\n if (target) {\n if (exposed) context.projectExports.namespace[exposed] = target;\n else context.projectExports.star.add(target);\n\n return;\n }\n\n const module = context.packageExports[statement.source.value] ??= {};\n if (exposed) (module.namespaces ??= []).push(exposed);\n else module.star = true;\n }\n\n /**\n * Strips an `export default`, keeping the declaration behind it whenever there is one to keep.\n *\n * @param statement - Default export statement to strip\n * @param context - Pass the edits are queued against\n * @returns Whether the statement survives in the stripped content\n *\n * @remarks\n * A named class, function, or interface keeps its body and is recorded as `Name as default`,\n * with `export default` rewritten to `declare` so the fragment stays a valid ambient declaration.\n * A default export of an identifier is dropped, since the declaration it names is a statement of its own that\n * the fragment already carries.\n * An anonymous default has no binding a bundle could re-export, so it is dropped without a record.\n *\n * @see defaultBinding\n * @since 3.0.0\n */\n\n private stripDefaultExport(statement: ExportDefaultDeclaration, context: ParseContextInterface): boolean {\n const { declaration } = statement;\n const local = this.defaultBinding(declaration);\n if (local) context.projectExports.exports.push({ name: local, alias: 'default' });\n\n if (local && declaration.type !== 'Identifier') {\n context.bundleEdits.push({ start: statement.start, end: declaration.start, text: 'declare ' });\n\n return true;\n }\n\n removeNode(statement, context.content, context.bundleEdits);\n\n return false;\n }\n\n /**\n * Queues the removal of every doc comment the stripping left attached to nothing.\n *\n * @param context - Pass the deletions are queued against\n * @param body - Top-level statements of the file, in source order\n * @param kept - Start offsets of the surviving statements, in source order\n *\n * @remarks\n * Only comments that sit between two top-level statements are judged, so the documentation a surviving declaration\n * carries on its own members is never touched.\n * Such a comment is kept when nothing but whitespace separates it from the next surviving statement.\n * Anything else - a stripped statement between the two, another comment, or a trailing position with no statement\n * after it at all - makes it an orphan.\n * Only `/**` comments are considered, so line comments and plain block comments stay put.\n * Comments and statements are both in source order, so all three are walked together in one pass,\n * and a file with many comments does not cost a scan per comment.\n *\n * @see build\n * @since 3.0.0\n */\n\n private pruneComments(context: ParseContextInterface, body: Array<Directive | Statement>, kept: Array<number>): void {\n const { content, bundleEdits } = context;\n let inner = 0;\n let index = 0;\n\n for (const comment of context.parsed.comments) {\n if (comment.type !== 'Block' || comment.value.charCodeAt(0) !== Char.Star) continue;\n\n while (inner < body.length && body[inner].end <= comment.start) inner++;\n if (inner < body.length && body[inner].start < comment.start) continue;\n\n while (index < kept.length && kept[index] < comment.end) index++;\n if (index < kept.length && this.blank(content, comment.end, kept[index])) continue;\n\n removeNode(comment, content, bundleEdits);\n }\n }\n\n /**\n * Resolves a specifier, recording it as a dependency and rewriting it when it names a project file.\n *\n * @param source - Specifier literal as written in the declaration\n * @param context - Pass the specifier was read from\n * @returns The resolved absolute path, or `null` when the specifier names a package or does not resolve\n *\n * @remarks\n * The one place a specifier is looked at, so the two outputs cannot disagree on which files are inlined.\n * An internal target leaves an edge behind for the bundle and a relative rewrite for the standalone declaration,\n * while a package leaves both untouched.\n * The rewrite names the declaration rather than the source, the resolved extension giving way to `.d.ts`, so an\n * emitted file points at the file emitted beside it rather than at a source that was never shipped.\n * Resolution goes through the TypeScript service, so aliases and `paths` mappings resolve the way the type checker\n * sees them rather than the way Node would, and the path it reports is normalized the way the file cache keys are.\n *\n * @since 3.0.0\n */\n\n private link(source: StringLiteral, context: ParseContextInterface): string | null {\n const resolved = this.ts.resolve(source.value, context.target);\n if (!resolved || resolved.isExternalLibraryImport) return null;\n\n const { extension, relativeFileName, resolvedFileName } = resolved;\n const target = this.filesCache.resolve(resolvedFileName);\n\n context.projectDependencies.add(target);\n context.edits.push({\n end: source.end,\n start: source.start,\n text: `'${ extension ? relativeFileName.slice(0, -extension.length) : relativeFileName }.d.ts'`\n });\n\n return target;\n }\n\n /**\n * Appends the names a declaration binds to the exported surface.\n *\n * @param declaration - Declaration carried by an `export` statement\n * @param names - Bindings the declared names are appended to\n *\n * @remarks\n * A variable statement can bind several names at once, while every other declaration binds at most one.\n * Bindings that are not plain identifiers - a destructured variable, or an ambient module declared by its quoted\n * path - contribute nothing, having no name a bundle could re-export.\n *\n * @since 3.0.0\n */\n\n private collectDeclared(declaration: Declaration, names: Array<NamedBindingInterface>): void {\n if (declaration.type === 'VariableDeclaration') {\n for (const entry of declaration.declarations)\n if (entry.id.type === 'Identifier') names.push({ name: entry.id.name });\n\n return;\n }\n\n if ('id' in declaration && declaration.id && 'name' in declaration.id) names.push({ name: declaration.id.name });\n }\n\n /**\n * Returns the local name a default export binds, when it binds one.\n *\n * @param declaration - Declaration or expression behind `export default`\n * @returns The bound name, or `undefined` for an anonymous or non-binding default\n *\n * @since 3.0.0\n */\n\n private defaultBinding(declaration: ExportDefaultDeclarationKind): string | undefined {\n if (declaration.type === 'Identifier') return declaration.name;\n\n return 'id' in declaration ? declaration.id?.name : undefined;\n }\n\n /**\n * Reads the name out of an import or export clause entry.\n *\n * @param name - Identifier or string literal naming a binding\n * @returns The identifier, or the literal re-quoted so it can be emitted back into a clause\n *\n * @since 3.0.0\n */\n\n private nameOf(name: ModuleExportName): string {\n return 'name' in name ? name.name : JSON.stringify(name.value);\n }\n\n /**\n * Pairs the name a binding carries on the module with its local name.\n *\n * @param name - Name the binding is known by on the other side of the clause\n * @param alias - Local name the clause binds it under\n * @returns The bare name when the two match, and the pair when the clause renamed it\n *\n * @see NamedBindingInterface\n * @since 3.0.0\n */\n\n private binding(name: string, alias: string): NamedBindingInterface {\n return name === alias ? { name } : { name, alias };\n }\n\n /**\n * Reports whether a range of the content holds nothing but whitespace.\n *\n * @param content - Text the range points into\n * @param start - Inclusive start offset of the range\n * @param end - Exclusive end offset of the range\n * @returns `true` when every character in the range is a space, tab, or line break\n *\n * @remarks\n * Scans in place and stops at the first other character, so it costs nothing on the long ranges left behind by\n * stripped statements and allocates no substring on the short ones.\n *\n * @since 3.0.0\n */\n\n private blank(content: string, start: number, end: number): boolean {\n for (let index = start; index < end; index++) {\n const code = content.charCodeAt(index);\n if (code !== Char.Space && code !== Char.Tab && code !== Char.Lf && code !== Char.Cr) return false;\n }\n\n return true;\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { ParseResult } from 'oxc-parser';\nimport type { Span, StringLiteral } from '@oxc-project/types';\nimport type { TypescriptService } from '@typescript/services/typescript.service';\nimport type { SourceEditInterface } from './interfaces/transformer-component.interface';\n\n/**\n * Imports\n */\n\nimport { Char } from '@constants/char.constant';\n\n/**\n * Records an edit that deletes a node along with the rest of its line.\n *\n * @param node - Span of the node to delete, as the parser reported it\n * @param content - Source text the span points into\n * @param edits - Collector the deletion is appended to\n *\n * @remarks\n * The deleted range runs from the start of the node through the spaces and tabs that follow it and one line terminator,\n * so a statement that sat alone on its line does not leave a blank line behind.\n * Anything before the node on that line is kept, since the scan only moves forward from the node's end.\n *\n * @example\n * ```ts\n * const content = \"import 'a';\\nconst x = 1;\";\n * const edits: Array<SourceEditInterface> = [];\n *\n * removeNode({ start: 0, end: 11 }, content, edits);\n * edits; // [ { start: 0, end: 12 } ]\n * applyEdits(content, edits); // 'const x = 1;'\n * ```\n *\n * @see applyEdits\n * @since 3.0.0\n */\n\nexport function removeNode(node: Span, content: string, edits: Array<SourceEditInterface>): void {\n let cursor = node.end;\n\n while (cursor < content.length) {\n const code = content.charCodeAt(cursor);\n if (code !== Char.Space && code !== Char.Tab) break;\n cursor++;\n }\n if (content.charCodeAt(cursor) === Char.Cr) cursor++;\n if (content.charCodeAt(cursor) === Char.Lf) cursor++;\n\n edits.push({ start: node.start, end: cursor });\n}\n\n/**\n * Rewrites the source text with a set of edits applied.\n *\n * @param content - Source text the edits point into\n * @param edits - Edits to apply, sorted in place by start offset\n * @returns The rewritten text, or `content` itself when there is nothing to apply\n *\n * @remarks\n * The edits are ordered by start offset and applied left to right,\n * so a transform can collect them in whatever order it walks the tree.\n * An edit starting inside a range an earlier edit already replaced is dropped rather than merged,\n * which keeps the output well-formed when two passes claim overlapping spans.\n * An edit carrying no `text` deletes its span.\n * The array is sorted in place, so a caller that depends on its original order should pass a copy.\n *\n * @example\n * ```ts\n * applyEdits('const a = 1;', [ { start: 0, end: 5, text: 'let' } ]); // 'let a = 1';\n * applyEdits('const a = 1;', [ { start: 0, end: 6 } ]); // 'a = 1;' - deleted\n * applyEdits('const a = 1;', []); // 'const a = 1;' - returned untouched\n * ```\n *\n * @see SourceEditInterface\n * @since 3.0.0\n */\n\nexport function applyEdits(content: string, edits: Array<SourceEditInterface>): string {\n if (edits.length < 1) return content;\n edits.sort((left, right) => left.start - right.start);\n\n const parts: Array<string> = new Array(edits.length * 2 + 1);\n let index = 0;\n let cursor = 0;\n\n for (let i = 0; i < edits.length; i++) {\n const edit = edits[i];\n if (edit.start < cursor) continue;\n parts[index++] = content.slice(cursor, edit.start);\n parts[index++] = edit.text ?? '';\n cursor = edit.end;\n }\n\n parts[index++] = content.slice(cursor);\n parts.length = index;\n\n return parts.join('');\n}\n\n/**\n * Queues an edit rewriting a specifier to the relative path of the project file it resolves to.\n *\n * @param source - Specifier literal to rewrite, or `null` when the statement carries none\n * @param target - Resolved absolute path of the file the specifier was written in\n * @param edits - Collector the rewrite is appended to\n * @param ts - Service whose module resolution decides what the specifier names\n *\n * @remarks\n * Only a project file is rewritten, so a specifier naming a package or resolving nowhere is left as it was written.\n * So is a statement with no specifier at all, which is what `export { a }` without a `from` clause looks like.\n * The replacement is measured from the importing file's own directory and carries no extension,\n * so an alias or a `paths` mapping becomes a specifier that still resolves once the file no longer sits in the source\n * tree.\n *\n * @example\n * ```ts\n * const edits: Array<SourceEditInterface> = [];\n *\n * rewrite(statement.source, 'D:/app/src/index.ts', edits, ts);\n * edits; // [ { start: 21, end: 43, text: \"'./components/builder.js'\" } ]\n * ```\n *\n * @see resolveSource\n * @since 3.0.0\n */\n\nexport function rewrite(source: StringLiteral | null, target: string, edits: Array<SourceEditInterface>, ts: TypescriptService): void {\n if (!source) return;\n\n const resolved = ts.resolve(source.value, target);\n if (!resolved || resolved.isExternalLibraryImport) return;\n const { extension, relativeFileName } = resolved;\n const path = extension ? relativeFileName.slice(0, -extension.length) : relativeFileName;\n\n edits.push({ end: source.end, start: source.start, text: `'${ path }.js'` });\n}\n\n/**\n * Rewrites every project specifier in a parsed file and returns the text with the rewrites applied.\n *\n * @param parse - Parse of the text, whose spans are offsets into `content`\n * @param target - Resolved absolute path of the file the text belongs to\n * @param content - The text the parse describes, handed back unchanged when it is empty\n * @param ts - Service whose module resolution decides which specifiers name project files\n * @returns The text with every project specifier rewritten, or `content` itself when none was\n *\n * @remarks\n * Only top-level statements are visited, since only those can carry module syntax.\n * An import, an `export *`, and a named export are read for their `from` clause,\n * while `import x = require('m')` is read for its module name.\n * `import A = B.C` names no module, so it is left alone, as is an `export { a }` that carries no `from` clause.\n * Every specifier found goes through {@link rewrite}, so a package stays as it was written,\n * and only a project file is rewritten.\n * The parse and the text have to come from the same source, since the spans are offsets into it - a parse of one text\n * applied to another lands its edits in the wrong places.\n *\n * @example\n * ```ts\n * const content = \"import { build } from '@components/builder';\\nexport const x = 1;\";\n * const parse = parseSync('src/index.ts', content, { sourceType: 'module' });\n *\n * resolveSource(parse, 'D:/app/src/index.ts', content, ts);\n * // \"import { build } from './components/builder';\\nexport const x = 1;\"\n * ```\n *\n * @see rewrite\n * @see applyEdits\n *\n * @since 3.0.0\n */\n\nexport function resolveSource(parse: ParseResult, target: string, content: string = '', ts: TypescriptService): string {\n if(!content) return content;\n const edits: Array<SourceEditInterface> = [];\n\n for (const statement of parse.program.body) {\n switch (statement.type) {\n case 'ImportDeclaration':\n case 'ExportAllDeclaration':\n case 'ExportNamedDeclaration':\n rewrite(statement.source, target, edits, ts);\n break;\n\n case 'TSImportEqualsDeclaration':\n if (statement.moduleReference.type === 'TSExternalModuleReference')\n rewrite(statement.moduleReference.expression, target, edits, ts);\n }\n }\n\n return applyEdits(content, edits);\n}\n\n","/**\n * Header text included at the top of generated declaration bundle files.\n *\n * @remarks\n * This constant provides a standardized header comment prepended to all\n * declaration bundle files generated by the TypeScript module. The header clearly\n * indicates that the file was automatically generated and should not be edited manually.\n *\n * The header serves as:\n * - A warning to developers not to manually modify generated files\n * - Documentation indicating the source of the file\n * - A consistent marker for identifying generated declaration files\n *\n * @example\n * ```ts\n * import { HeaderDeclarationBundle } from './typescript.constant';\n * import { writeFileSync } from 'fs';\n *\n * const bundledContent = `${HeaderDeclarationBundle}\\n${actualDeclarations}`;\n * writeFileSync('dist/index.d.ts', bundledContent);\n * ```\n *\n * @since 1.5.9\n */\n\nexport const HeaderDeclarationBundle = `/**\n * This file was automatically generated by xBuild.\n * DO NOT EDIT MANUALLY.\n */\n`;\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { FileSnapshotInterface } from '@models/interfaces/files-model.interface';\nimport type { IScriptSnapshot, SourceFile, ParsedCommandLine, CompilerOptions } from 'typescript';\n\n/**\n * Imports\n */\n\nimport ts from 'typescript';\nimport { relative } from '@remotex-labs/xmap';\nimport { inject } from '@remotex-labs/xinject';\nimport { FilesModel } from '@models/files.model';\nimport { createMatcher } from '@components/glob.component';\n\n/**\n * A TypeScript language service host backed by cached file snapshots and the set of files it has tracked.\n *\n * @remarks\n * Satisfies `ts.LanguageServiceHost`, giving the language service its filesystem access, script snapshots, and\n * compiler configuration.\n * Reads and versions are delegated to the shared {@link FilesModel}, while the file set handed over through\n * {@link getScriptFileNames} is maintained here.\n * A path enters the tracked set the first time it is refreshed or its version is queried,\n * so the set grows from the configured entry files to every dependency the language service resolves into them.\n * Paths matched by the configuration's `exclude` globs are skipped by {@link refreshFiles} and reported as ignored\n * to incremental checks through {@link ignoreSourceFile}.\n *\n * @example\n * ```ts\n * const host = new LanguageHostService(parsedConfig); // entry files tracked and read up front\n *\n * host.refresh('src/index.ts'); // re-read and track one file\n * host.getScriptSnapshot('src/index.ts'); // what the language service parses\n * host.options = nextParsedConfig; // swap configuration and re-track from scratch\n * ```\n *\n * @see FilesModel\n * @since 2.0.0\n */\n\nexport class LanguageHostService implements ts.LanguageServiceHost {\n /**\n * Shared model that reads files, caches their snapshots, and tracks their versions.\n *\n * @remarks\n * Registered as a singleton, so every host and build step works against one cache keyed by resolved absolute path.\n *\n * @example\n * ```ts\n * host.filesCache.touch('src/index.ts').version; // 1\n * ```\n *\n * @see FilesModel\n * @since 3.0.0\n */\n\n readonly filesCache = inject(FilesModel);\n\n /**\n * Resolved absolute paths of every file this host has tracked for the language service.\n *\n * @remarks\n * Returned verbatim from {@link getScriptFileNames}.\n * A path is added the first time it is refreshed or its version is queried, then kept even after the file is\n * deleted, so the language service observes the deletion through an empty snapshot rather than a vanishing file.\n *\n * @see track\n * @since 3.0.0\n */\n\n private readonly trackedFiles = new Set<string>();\n\n /**\n * Memoized exclusion verdict per path, keyed by the resolved absolute path.\n *\n * @remarks\n * Exclusion is asked for on every refresh and on every source file an incremental check walks,\n * while the answer only changes with the configuration, so {@link reload} clears this rather than recomputing it.\n *\n * @see isExcluded\n * @since 3.0.0\n */\n\n private readonly exclusions = new Map<string, boolean>();\n\n /**\n * A predicate compiled from the configuration's `exclude` globs, tested against working-directory-relative\n * paths.\n *\n * @remarks\n * Assigned by {@link reload} before any lookup can reach it, hence the definite assignment.\n * It takes a relative path, so {@link isExcluded} is what callers use.\n *\n * @see compileExclude\n * @since 3.0.0\n */\n\n private matches!: (path: string) => boolean;\n\n /**\n * Initializes a new {@link LanguageHostService} from a parsed configuration.\n *\n * @param config - Parsed TypeScript configuration carrying the compiler options, entry file names,\n * and the raw `exclude` globs\n *\n * @remarks\n * Runs {@link reload}, so the entry files are read into the cache and tracked before the host is handed out.\n *\n * @example\n * ```ts\n * const config = ts.getParsedCommandLineOfConfigFile('tsconfig.json', {}, ts.sys as never)!;\n * const host = new LanguageHostService(config);\n * host.getScriptFileNames(); // the configuration's entry files\n * ```\n *\n * @see reload\n * @since 3.0.0\n */\n\n constructor(private config: ParsedCommandLine) {\n this.reload();\n }\n\n /**\n * The live set of resolved paths currently tracked by this host.\n *\n * @returns The tracked set itself, mutated as files are refreshed and cleared\n *\n * @remarks\n * Exposes the same paths as {@link getScriptFileNames} without copying,\n * so a caller can iterate them or feed them straight back into {@link refreshFiles}.\n *\n * @example\n * ```ts\n * host.refresh('src/index.ts');\n * host.tracked.has(host.realpath('src/index.ts')); // true\n * ```\n *\n * @see getScriptFileNames\n * @since 3.0.0\n */\n\n get tracked(): Set<string> {\n return this.trackedFiles;\n }\n\n /**\n * A source-file predicate that incremental checks can use to skip excluded files.\n *\n * @returns A predicate reporting `true` for a source file whose path matches the exclude globs\n *\n * @remarks\n * Bridges the path-based {@link isExcluded} to TypeScript's `ignoreSourceFile` hook by reading the absolute\n * `fileName`, so it agrees with how {@link refreshFiles} filters paths.\n *\n * @example\n * ```ts\n * builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, host.ignoreSourceFile);\n * ```\n *\n * @see refreshFiles\n * @since 3.0.0\n */\n\n get ignoreSourceFile(): (file: SourceFile) => boolean {\n return (file: SourceFile): boolean => this.isExcluded(file.fileName);\n }\n\n /**\n * Replaces the configuration and re-tracks the project from scratch.\n *\n * @param config - The new parsed configuration\n *\n * @remarks\n * Delegates to {@link reload}, so the exclude predicate is recompiled and the new `config.fileNames` replace the\n * tracked set entirely.\n *\n * @example\n * ```ts\n * host.options = ts.getParsedCommandLineOfConfigFile('tsconfig.json', {}, ts.sys as never)!;\n * host.getScriptFileNames(); // the new entry files, nothing carried over\n * ```\n *\n * @see reload\n * @since 3.0.0\n */\n\n set options(config: ParsedCommandLine) {\n this.config = config;\n this.reload();\n }\n\n /**\n * Drops the tracked set and repopulates it from the configured entry files.\n *\n * @remarks\n * The {@link filesCache} snapshots survive, so only membership is reset,\n * and the files are re-read on the way back in through {@link refreshFiles}.\n *\n * @example\n * ```ts\n * host.refresh('src/scratch.ts');\n * host.clearTracked();\n * host.getScriptFileNames(); // back to the configured entry files, scratch.ts dropped\n * ```\n *\n * @see refreshFiles\n * @since 3.0.0\n */\n\n clearTracked(): void {\n this.trackedFiles.clear();\n this.refreshFiles(this.config.fileNames);\n }\n\n /**\n * Rebuilds the exclude predicate and the tracked set from the current configuration.\n *\n * @remarks\n * The single initialization path shared by the constructor and the {@link options} setter:\n * - compiles the `exclude` globs into {@link matches},\n * - drops the memoized {@link exclusions}, whose verdicts belong to the previous globs,\n * - refreshes every entry file through {@link clearTracked}, which reads them into the cache and tracks them.\n *\n * Call it directly when the configuration object was edited in place rather than replaced.\n *\n * @example\n * ```ts\n * host.reload();\n * host.getScriptFileNames(); // what the configuration now selects\n * ```\n *\n * @see clearTracked\n * @since 3.0.0\n */\n\n reload(): void {\n this.matches = this.compileExclude(this.config.raw?.exclude);\n this.exclusions.clear();\n\n this.clearTracked();\n }\n\n /**\n * Re-reads a file from the disk, tracks it, and returns its entry.\n *\n * @param path - File path, relative or absolute\n * @returns The entry for the file, with `version` advanced when the content changed\n *\n * @remarks\n * The path is tracked before the read, so it stays listed even when the file turns out to be gone.\n * Exclusion is not consulted here - {@link refreshFiles} is the caller that filters.\n *\n * @example\n * ```ts\n * const state = host.refresh('src/index.ts');\n * state.version; // 1 at first sight, advanced on every later change\n * state.snapshot?.text; // the content just read\n * ```\n *\n * @see track\n * @since 3.0.0\n */\n\n refresh(path: string): FileSnapshotInterface {\n return this.filesCache.refresh(this.track(path));\n }\n\n /**\n * Refreshes and tracks a batch of files, skipping any path matched by the exclude globs.\n *\n * @param paths - Paths to refresh, defaulting to the currently tracked set\n *\n * @remarks\n * Each retained path goes through {@link refresh} and so becomes tracked.\n * Calling it with no argument brings the already tracked files current, which is what a watch cycle does.\n *\n * @example\n * ```ts\n * host.refreshFiles([ 'src/a.ts', 'src/a.spec.ts' ]); // a.spec.ts skipped when excluded\n * host.refreshFiles(); // re-read everything already tracked\n * ```\n *\n * @see refresh\n * @since 3.0.0\n */\n\n refreshFiles(paths: Array<string> | Set<string> = this.trackedFiles): void {\n for (const path of paths) {\n if (this.isExcluded(path)) continue;\n this.refresh(path);\n }\n }\n\n /**\n * Returns the compiler options currently in force.\n *\n * @returns The active TypeScript compiler options\n *\n * @example\n * ```ts\n * host.getCompilationSettings().target; // ts.ScriptTarget.ES2020\n * ```\n *\n * @since 2.0.0\n */\n\n getCompilationSettings(): CompilerOptions {\n return this.config.options;\n }\n\n /**\n * Reports whether a file exists on disk.\n *\n * @param path - Absolute path\n * @returns `true` when the file exists\n *\n * @remarks\n * Goes straight to `ts.sys`, bypassing the snapshot cache, so it reflects the filesystem as it stands now.\n *\n * @example\n * ```ts\n * host.fileExists('/project/src/index.ts'); // true\n * ```\n *\n * @since 2.0.0\n */\n\n fileExists(path: string): boolean {\n return ts.sys.fileExists(path);\n }\n\n /**\n * Reads file content through the snapshot cache.\n *\n * @param path - File path, relative or absolute\n * @param encoding - Encoding used when the file is read, defaulting to `utf-8`\n * @returns The file content, or `undefined` when the path holds no readable file\n *\n * @remarks\n * Served from the cache once the file has been read, so the encoding only takes effect on the first read of a path.\n *\n * @example\n * ```ts\n * host.readFile('src/index.ts'); // export const x = 10;\n * host.readFile('src/gone.ts'); // undefined\n * ```\n *\n * @see FilesModel.touch\n * @since 3.0.0\n */\n\n readFile(path: string, encoding?: BufferEncoding): string | undefined {\n return this.filesCache.touch(path, encoding).snapshot?.text;\n }\n\n /**\n * Lists the files under a directory that match the given criteria.\n *\n * @param path - Directory to start from\n * @param extensions - File extensions to accept\n * @param exclude - Glob patterns to skip\n * @param include - Glob patterns to keep\n * @param depth - Maximum recursion depth\n * @returns The matching file paths\n *\n * @example\n * ```ts\n * host.readDirectory('src', [ '.ts' ], [ 'node_modules' ], undefined, 2); // [ 'src/index.ts', ... ]\n * ```\n *\n * @since 2.0.0\n */\n\n readDirectory(path: string, extensions?: Array<string>, exclude?: Array<string>, include?: Array<string>, depth?: number): Array<string> {\n return ts.sys.readDirectory(path, extensions, exclude, include, depth);\n }\n\n /**\n * Returns the immediate subdirectories of a path.\n *\n * @param path - Directory to list\n * @returns The subdirectory names\n *\n * @example\n * ```ts\n * host.getDirectories('src'); // [ 'services', 'models' ]\n * ```\n *\n * @since 2.0.0\n */\n\n getDirectories(path: string): Array<string> {\n return ts.sys.getDirectories(path);\n }\n\n /**\n * Reports whether a directory exists.\n *\n * @param path - Absolute path\n * @returns `true` when the directory exists\n *\n * @example\n * ```ts\n * host.directoryExists('src/services'); // true\n * ```\n *\n * @since 2.0.0\n */\n\n directoryExists(path: string): boolean {\n return ts.sys.directoryExists(path);\n }\n\n /**\n * Returns the working directory that relative paths resolve against.\n *\n * @returns The absolute path of the current working directory\n *\n * @example\n * ```ts\n * host.getCurrentDirectory(); // '/project'\n * ```\n *\n * @since 2.0.0\n */\n\n getCurrentDirectory(): string {\n return ts.sys.getCurrentDirectory();\n }\n\n /**\n * Returns the resolved paths of every file tracked by this host.\n *\n * @returns A snapshot array of the tracked absolute paths\n *\n * @remarks\n * This is the program's file set as far as the language service is concerned.\n * A deleted file stays listed, so its removal surfaces as a diagnostic rather than as a silently shrinking program.\n *\n * @example\n * ```ts\n * host.getScriptFileNames(); // [ '/project/src/index.ts', '/project/src/utils.ts' ]\n * ```\n *\n * @see tracked\n * @since 2.0.0\n */\n\n getScriptFileNames(): Array<string> {\n return [ ...this.trackedFiles ];\n }\n\n /**\n * Returns the path of the default lib file matching the given options.\n *\n * @param options - Compiler options, of which `target` decides the lib\n * @returns Absolute path to the matching `lib.*.d.ts`\n *\n * @example\n * ```ts\n * host.getDefaultLibFileName({ target: ts.ScriptTarget.ES2020 }); // '.../lib.es2020.full.d.ts'\n * ```\n *\n * @since 2.0.0\n */\n\n getDefaultLibFileName(options: CompilerOptions): string {\n return ts.getDefaultLibFilePath(options);\n }\n\n /**\n * Returns the version identifier of a file and tracks it.\n *\n * @param path - File path, relative or absolute\n * @returns The version as a string, such as `'1'` or `'2'`\n *\n * @remarks\n * The language service reparses a file only when this string changes, so the value must stay stable while the file\n * does.\n * The read is served from the cache, and {@link refresh} is what moves the version forward.\n *\n * @example\n * ```ts\n * host.getScriptVersion('src/index.ts'); // '1'\n * host.refresh('src/index.ts'); // the file changed on disk\n * host.getScriptVersion('src/index.ts'); // '2' - the language service reparses it\n * ```\n *\n * @see track\n * @since 2.0.0\n */\n\n getScriptVersion(path: string): string {\n return this.filesCache.touch(this.track(path)).version.toString();\n }\n\n /**\n * Returns the script snapshot of a file.\n *\n * @param path - File path, relative or absolute\n * @returns The snapshot, or `undefined` when the path holds no readable file\n *\n * @remarks\n * Reads through the cache, loading from the disk at first sight only.\n * Unlike {@link getScriptVersion}, it leaves the tracked set alone - tracking is driven by version queries.\n *\n * @example\n * ```ts\n * const snapshot = host.getScriptSnapshot('src/index.ts');\n * snapshot?.getText(0, snapshot.getLength()); // export const x = 10;\n * ```\n *\n * @see getScriptVersion\n * @since 2.0.0\n */\n\n getScriptSnapshot(path: string): IScriptSnapshot | undefined {\n return this.filesCache.touch(path).snapshot;\n }\n\n /**\n * Resolves a path to the absolute form used as the tracking and cache key.\n *\n * @param path - File path, relative or absolute\n * @returns The resolved absolute path\n *\n * @remarks\n * Implements the optional `realpath` host hook with the same normalization {@link FilesModel} applies to its cache\n * keys, so the paths reported to TypeScript match the ones tracked here.\n *\n * @example\n * ```ts\n * host.realpath('src/index.ts'); // '/project/src/index.ts'\n * ```\n *\n * @see FilesModel.resolve\n * @since 3.0.0\n */\n\n realpath(path: string): string {\n return this.filesCache.resolve(path);\n }\n\n /**\n * Compiles exclude globs into a matcher over working-directory-relative paths.\n *\n * @param globs - Patterns whose matching paths are excluded, or `undefined` when the configuration has none\n * @returns A predicate reporting `true` for a matched relative path, or one that always reports `false`\n *\n * @remarks\n * The empty case is handled explicitly, since {@link createMatcher} reads an empty pattern list as matching\n * everything, which would exclude the whole project.\n *\n * @see createMatcher\n * @since 3.0.0\n */\n\n private compileExclude(globs?: Array<string>): (path: string) => boolean {\n return globs && globs.length > 0 ? createMatcher(globs) : (): boolean => false;\n }\n\n /**\n * Reports whether a path is excluded by the configuration, memorizing the verdict.\n *\n * @param path - File path as the caller holds it, relative or absolute\n * @returns `true` when the path matches the exclude globs\n *\n * @remarks\n * The path is resolved before the verdict is stored, so the same file reached by two spellings is matched once,\n * and every later lookup of either costs a map read.\n *\n * @see exclusions\n * @since 3.0.0\n */\n\n private isExcluded(path: string): boolean {\n const target = this.filesCache.resolve(path);\n let excluded = this.exclusions.get(target);\n if (excluded === undefined) this.exclusions.set(\n target, excluded = this.matches(relative(process.cwd(), target))\n );\n\n return excluded;\n }\n\n /**\n * Adds a path to the tracked set and returns its resolved key.\n *\n * @param path - File path, relative or absolute\n * @returns The resolved absolute path used as the tracking key\n *\n * @remarks\n * Centralizes the tracking shared by {@link refresh} and {@link getScriptVersion}.\n * A path is added the first time it is seen and never removed,\n * so a deletion leaves a still-listed entry that resolves to an empty snapshot.\n *\n * @see trackedFiles\n * @since 3.0.0\n */\n\n private track(path: string): string {\n const target = this.filesCache.resolve(path);\n this.trackedFiles.add(target);\n\n return target;\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Dirent } from 'fs';\nimport type { GlobOptionsInterface } from './interfaces/glob-component.interface';\n\n/**\n * Imports\n */\n\nimport { readdirSync } from 'fs';\nimport { join } from '@remotex-labs/xmap';\nimport { Char } from '@constants/char.constant';\nimport { FrameworkService } from '@services/framework.service';\nimport { RegexElement, RegexCloser } from '@constants/glob.constant';\n\n/**\n * Escapes a single character for literal use inside a regular expression.\n *\n * @param char - The character to escape\n * @returns The character prefixed with a backslash when it carries special meaning in a regular expression,\n * or the character unchanged otherwise\n *\n * @remarks\n * A backslash is prepended when `char` is one of the regex metacharacters `.+^$()|\\{}[]*?`.\n * Any other character is returned as-is.\n * Intended for building patterns from user-supplied glob fragments where each source character must match itself.\n *\n * @example\n * ```ts\n * lit('.'); // '\\\\.'\n * lit('a'); // 'a'\n * ```\n *\n * @since 3.0.0\n */\n\nexport function lit(char: string): string {\n return '.+^$()|\\\\{}[]*?'.includes(char) ? '\\\\' + char : char;\n}\n\n/**\n * Returns the UTF-16 code unit of a glob string at a given index.\n *\n * @param glob - The glob string to read from\n * @param index - The zero-based position of the character to read\n * @returns The code unit at `index`, or `NaN` when `index` is out of range\n *\n * @remarks\n * A thin wrapper over {@link String.charCodeAt} used while scanning a glob pattern character by character.\n * Comparing code units avoids allocating single-character substrings on the hot path.\n *\n * @example\n * ```ts\n * at('a*b', 1); // 42 - Char.Star\n * at('a*b', 9); // NaN - past the end\n * ```\n *\n * @see Char\n * @since 3.0.0\n */\n\nexport function at(glob: string, index: number): number {\n return glob.charCodeAt(index);\n}\n\n/**\n * Determines whether the `**` at a given index forms a globstar segment.\n *\n * @param glob - The glob string being scanned\n * @param index - The zero-based position of the first `*` of the candidate `**`\n * @returns `true` when the `**` occupies a whole path segment, `false` otherwise\n *\n * @remarks\n * A globstar is a `**` that spans an entire path segment,\n * so it must be bounded on both sides by a slash or by the start or end of the string.\n * The character before `index` must be the start of the string or a slash,\n * and the character after the `**` must be the end of the string or a slash.\n * A `**` embedded within a segment, such as in `a**b`, matches as two consecutive single stars rather than a globstar.\n * The caller is responsible for confirming that both characters at `index` and `index + 1` are `*`.\n *\n * @example\n * ```ts\n * isGlobstar('**', 0); // true - the whole string\n * isGlobstar('a/**', 2); // true - preceded by a slash, ends the string\n * isGlobstar('a**b', 1); // false - embedded in a segment\n * ```\n *\n * @see Char\n * @since 3.0.0\n */\n\nexport function isGlobstar(glob: string, index: number): boolean {\n return (index === 0 || at(glob, index - 1) === Char.Slash)\n && (index + 2 === glob.length || at(glob, index + 2) === Char.Slash);\n}\n\n/**\n * Wraps a regex fragment in a non-capturing group.\n *\n * @param body - The regex source to enclose\n * @returns The body wrapped as `(?:body)`\n *\n * @remarks\n * Groups a fragment so a following quantifier or alternation applies to the whole fragment rather than its last token.\n *\n * @example\n * ```ts\n * group('a|b'); // '(?:a|b)'\n * group('a|b') + '?'; // '(?:a|b)?' - the quantifier covers both alternatives\n * ```\n *\n * @since 3.0.0\n */\n\nexport function group(body: string): string {\n return `(?:${ body })`;\n}\n\n/**\n * Finds the index of the `]` that closes a character class.\n *\n * @param glob - The glob string being scanned\n * @param openIndex - The index of the opening `[`\n * @returns The index of the closing `]`, or the length of the string when the class is unterminated\n *\n * @remarks\n * Applies POSIX-style character-class rules while scanning.\n * A leading `!` or `^` negates the class and is skipped, and a `]` immediately after the opening bracket\n * (or after the negation) is treated as a literal member rather than a close.\n * A backslash escapes the next character, so an escaped `]` does not close the class.\n *\n * @example\n * ```ts\n * classEnd('[abc]def', 0); // 4\n * classEnd('[]abc]', 0); // 5 - the leading ] is a member\n * classEnd('[abc', 0); // 4 - unterminated, so the length\n * ```\n *\n * @see compileClass\n * @since 3.0.0\n */\n\nexport function classEnd(glob: string, openIndex: number): number {\n let scan = openIndex + 1;\n const lead = at(glob, scan);\n\n if (lead === Char.Bang || lead === Char.Caret) scan++;\n if (at(glob, scan) === Char.RBracket) scan++; // leading ] is literal\n\n while (scan < glob.length && at(glob, scan) !== Char.RBracket)\n scan += at(glob, scan) === Char.Backslash ? 2 : 1;\n\n return scan;\n}\n\n/**\n * Finds the index of the `)` that closes an extglob group.\n *\n * @param glob - The glob string being scanned\n * @param openIndex - The index of the opening `(`\n * @returns The index of the matching `)`, or `-1` when the group is unterminated\n *\n * @remarks\n * Tracks nesting depth so an inner `( ... )` does not end the outer group.\n * A backslash escapes the next character, and a `[ ... ]` character class is skipped via {@link classEnd},\n * so parentheses inside it are not counted.\n *\n * @example\n * ```ts\n * findClose('@(a|b)c', 1); // 5\n * findClose('@(a|(b))', 1); // 7 - the inner group does not end it\n * findClose('@(a', 1); // -1 - unterminated\n * ```\n *\n * @see classEnd\n * @since 3.0.0\n */\n\nexport function findClose(glob: string, openIndex: number): number {\n for (let cursor = openIndex, depth = 0; cursor < glob.length; cursor++) {\n const char = at(glob, cursor);\n\n if (char === Char.Backslash) cursor++;\n else if (char === Char.LParen) depth++;\n else if (char === Char.RParen && --depth === 0) return cursor;\n else if (char === Char.LBracket) cursor = classEnd(glob, cursor);\n }\n\n return -1;\n}\n\n/**\n * Finds the index of the `}` that closes an expandable brace group.\n *\n * @param glob - The glob string being scanned\n * @param openIndex - The index of the opening `{`\n * @returns The index of the matching `}` when the group contains a top-level comma, `-1` otherwise\n *\n * @remarks\n * A brace group is expandable only when it holds at least one top-level comma, so `{a,b}` closes but `{a}` does not.\n * Tracks nesting depth so an inner `{ ... }` does not end the outer group,\n * skips a `[ ... ]` character class via {@link classEnd}, and treats a backslash as escaping the next character.\n * Returning `-1` signals the caller to emit the `{` as a literal.\n *\n * @example\n * ```ts\n * braceClose('{a,b}c', 0); // 4\n * braceClose('{a,{b,c}}', 0); // 8 - the inner group does not end it\n * braceClose('{abc}', 0); // -1 - no top-level comma, so a literal\n * ```\n *\n * @see classEnd\n * @since 3.0.0\n */\n\nexport function braceClose(glob: string, openIndex: number): number {\n let comma = false;\n\n for (let cursor = openIndex + 1, depth = 0; cursor < glob.length; cursor++) {\n const char = at(glob, cursor);\n\n if (char === Char.Backslash) cursor++;\n else if (char === Char.LBrace) depth++;\n else if (char === Char.RBrace) {\n if (depth === 0) return comma ? cursor : -1; // expandable only with a comma\n depth--;\n }\n else if (char === Char.Comma && depth === 0) comma = true;\n else if (char === Char.LBracket) cursor = classEnd(glob, cursor);\n }\n\n return -1;\n}\n\n/**\n * Compiles a glob character class into its regex equivalent.\n *\n * @param glob - The glob string being scanned\n * @param openIndex - The index of the opening `[`\n * @returns A tuple of the compiled regex source and the index just past the class\n *\n * @remarks\n * Translates glob character-class syntax into a regex class.\n * A leading `!` or `^` becomes a negation that also excludes the path separator, emitted as `[^/`.\n * A `]` immediately after the opening (or after the negation) is escaped as a literal member,\n * and a `^` inside the class is escaped so it is not read as a negation.\n * An unterminated class is not a class at all - the function returns the literal `\\[` and advances past the `[`.\n *\n * @example\n * ```ts\n * compileClass('[a-z]x', 0); // [ '[a-z]', 5 ]\n * compileClass('[!a]', 0); // [ '[^/a]', 4 ] - negated, and the separator excluded with it\n * compileClass('[abc', 0); // [ '\\\\[', 1 ] - unterminated, so a literal bracket\n * ```\n *\n * @see classEnd\n * @since 3.0.0\n */\n\nexport function compileClass(glob: string, openIndex: number): [string, number] {\n const end = classEnd(glob, openIndex);\n if (end >= glob.length) return [ '\\\\[', openIndex + 1 ]; // unterminated → literal\n\n let cursor = openIndex + 1, out = '[';\n const lead = at(glob, cursor);\n\n if (lead === Char.Bang || lead === Char.Caret) { out += '^/'; cursor++; }\n if (at(glob, cursor) === Char.RBracket) { out += '\\\\]'; cursor++; }\n\n for (; cursor < end; cursor++) {\n if (at(glob, cursor) === Char.Backslash) out += '\\\\' + glob[++cursor];\n else if (at(glob, cursor) === Char.Caret) out += '\\\\^';\n else out += glob[cursor];\n }\n\n return [ out + ']', end + 1 ];\n}\n\n/**\n * Finds the index of the next path separator at or after a position.\n *\n * @param glob - The glob string being scanned\n * @param from - The zero-based position to start scanning from\n * @returns The index of the next unescaped `/`, or the length of the string when none remains\n *\n * @remarks\n * Marks the end of the current path segment.\n * A backslash escapes the next character, so an escaped `/` does not end the segment.\n *\n * @example\n * ```ts\n * segmentEnd('src/index.ts', 0); // 3\n * segmentEnd('index.ts', 0); // 8 - no separator left, so the length\n * ```\n *\n * @since 3.0.0\n */\n\nexport function segmentEnd(glob: string, from: number): number {\n for (let cursor = from; cursor < glob.length; cursor++) {\n if (at(glob, cursor) === Char.Slash) return cursor;\n if (at(glob, cursor) === Char.Backslash) cursor++;\n }\n\n return glob.length;\n}\n\n/**\n * Compiles a glob fragment into a regular-expression source.\n *\n * @param glob - The glob fragment to compile\n * @param isSegmentStart - Whether the fragment begins at the start of a path segment\n * @param alt - The code unit that separates alternatives, or `0` when the fragment is not an alternation body\n * @param options - Compilation options, of which only {@link GlobOptionsInterface.dot} is read, defaulting to `false`\n * @returns The regex source for the fragment, without the anchoring `^` and `$`\n *\n * @remarks\n * The core of the compiler, invoked recursively for the bodies of extglob, brace, and negation groups.\n * It walks the fragment one character at a time and emits the matching regex, handling wildcards (`*`, `**`, `?`),\n * character classes, brace expansion, extglob prefixes (`?( )`, `*( )`, `+( )`, `@( )`, `!( )`), and escapes.\n *\n * Segment-start tracking drives the leading-dot guard: at the start of a segment a wildcard must not match a dotfile,\n * so a {@link RegexElement.NotDot} guard is emitted.\n * `isSegmentStart` seeds this state for the fragment, and it is re-armed after every `/` and at each alternative.\n * When `options.dot` is `true`, the guard is suppressed everywhere, so wildcards match dotfiles as ordinary names,\n * and `**` descends into dot directories.\n *\n * The `alt` parameter marks the fragment as the body of an alternation.\n * When set to {@link Char.Pipe} or {@link Char.Comma}, an unescaped separator of that kind becomes a regex `|`,\n * and `**` is treated as two single stars rather than a globstar.\n * Any other occurrence of `|` or `,` is emitted literally.\n *\n * @example\n * ```ts\n * compileFragment('*.ts', true); // (?!\\.)[^/]*\\.ts\n * compileFragment('a,b', false, Char.Comma); // a|b\n * compileFragment('*.ts', true, 0, { dot: true }); // [^/]*\\.ts\n * ```\n *\n * @see globToRegExp\n * @see GlobOptionsInterface\n *\n * @since 3.0.0\n */\n\nexport function compileFragment(glob: string, isSegmentStart: boolean = false, alt: number = 0, options: GlobOptionsInterface = {}): string {\n const { dot = false } = options;\n\n let out = '';\n let index = 0;\n let wasStart = isSegmentStart;\n\n const guard = dot ? '' : RegexElement.NotDot;\n const DS = guard + RegexElement.NotSlash + '+';\n const GLOBSTAR = group(DS + '(?:/' + DS + ')*') + '?';\n\n while (index < glob.length) {\n const char = at(glob, index);\n const nChar = at(glob, index + 1);\n\n if (nChar === Char.LParen && (char === Char.Bang || RegexCloser[char])) {\n const close = findClose(glob, index + 1);\n\n if (char !== Char.Bang) { // ?*+@( ... )\n const end = close === -1 ? glob.length : close; // unclosed → group runs to the end\n const inner = compileFragment(glob.slice(index + 2, end), wasStart, Char.Pipe, options);\n\n out += RegexElement.Open + inner + RegexCloser[char];\n index = end + 1;\n continue;\n }\n\n if (close !== -1) {\n const inner = compileFragment(glob.slice(index + 2, close), wasStart, Char.Pipe, options);\n const tailEnd = segmentEnd(glob, close + 1);\n const tail = compileFragment(glob.slice(close + 1, tailEnd), false, 0, options);\n\n out += group(\n (wasStart ? guard : '') +\n `(?!${ group(inner) + tail + RegexElement.SegBreak })` +\n RegexElement.NotSlashLazy + tail\n );\n\n index = tailEnd;\n continue;\n }\n }\n\n switch (char) {\n case Char.Slash:\n out += RegexElement.Slash;\n index++;\n wasStart = true;\n break;\n\n case Char.Backslash:\n out += index + 1 < glob.length ? lit(glob[index + 1]) : '\\\\\\\\';\n index += 2;\n break;\n\n case Char.Question:\n out += wasStart && !dot ? RegexElement.NotDotSlash : RegexElement.NotSlash;\n index++;\n break;\n\n case Char.Star:\n if (nChar === Char.Star && alt !== Char.Pipe && (index > 0 || isSegmentStart) && isGlobstar(glob, index)) {\n const root = index === 0 && alt === 0 ? RegexElement.AbsRoot : '';\n if (at(glob, index + 2) === Char.Slash) {\n out += root + group(DS + RegexElement.Slash) + '*'; index += 3; wasStart = true;\n } else {\n out += root + GLOBSTAR; index += 2;\n }\n } else {\n out += (wasStart ? guard : '') + RegexElement.NotSlashRun;\n index++;\n }\n break;\n\n case Char.LBrace: {\n const close = braceClose(glob, index);\n\n if (close === -1) {\n out += '\\\\{'; index++;\n } else {\n out += group(compileFragment(glob.slice(index + 1, close), wasStart, Char.Comma, options));\n index = close + 1;\n }\n break;\n }\n\n case Char.LBracket: {\n const [ src, next ] = compileClass(glob, index);\n out += (wasStart && !dot && src !== '\\\\[' ? RegexElement.NotDot : '') + src;\n index = next;\n break;\n }\n\n case Char.Pipe:\n case Char.Comma:\n if (alt === char) { out += RegexElement.Alt; wasStart = isSegmentStart; }\n else out += lit(glob[index]);\n index++;\n break;\n\n default:\n out += lit(glob[index]); index++;\n }\n }\n\n return out;\n}\n\n/**\n * Compiles a glob pattern into an anchored regular expression.\n *\n * @param glob - The glob pattern to compile\n * @param options - Compilation options carrying the regex flags and the dotfile setting\n * @returns A {@link RegExp} anchored with `^` and `$` that matches exactly the paths described by the glob\n *\n * @remarks\n * The entry point of the compiler.\n * It compiles the pattern with {@link compileFragment} starting at a segment boundary, then wraps the result\n * in `^ ... $` so the expression matches a whole path rather than a substring.\n *\n * Supported glob syntax:\n * - `*` - matches any run of characters within a single path segment, never crossing a `/`.\n * - `?` - matches exactly one character within a segment.\n * - `**` - globstar, matching across segment boundaries, spanning any number of intermediate segments.\n * - `[abc]`, `[a-z]`, `[a-zA-Z0-9]` - a character class matching exactly one listed character or range.\n * Multiple ranges combine, and it never matches more than one character.\n * - `[!abc]`, `[^abc]` - a negated character class matching exactly one character not listed.\n * - `{a,b}`, `{a,{b,c}}` - brace alternation, matching any one of the comma-separated alternatives.\n * A brace group with no top-level comma, such as `{abc}`, is treated as the literal text `{abc}`.\n * - `@( ... )` - extglob group matching its `|`-separated alternatives exactly once.\n * - `?( ... )` - extglob group matching zero or one of its alternatives.\n * - `*( ... )` - extglob group matching zero or more of its alternatives.\n * - `+( ... )` - extglob group matching one or more of its alternatives.\n * - `!( ... )` - extglob negation matching anything the alternatives do not.\n * - `\\` - escapes the next character so it is matched literally, so `\\*.js` matches the literal name `*.js`.\n * - `/` - the literal path separator, which segment-relative wildcards never cross.\n *\n * Character classes and `?` always consume exactly one character.\n * To constrain a run of characters, follow the class with `*` (`[ab]*c` allows any run before `c`)\n * or repeat it with an extglob (`+([ab])c` requires every character before `c` to be `a` or `b`).\n *\n * The `!( ... )` negation is single-segment: its body never crosses a `/`, and the guarantee holds when\n * the negation is the last thing in its segment or is followed by a literal tail such as `.ts`.\n * It is not whole-pattern negation - a leading `!` not followed by `(` is matched as a literal `!`.\n *\n * Leading dots are guarded: at the start of a segment,\n * `*`, `?`, `[ ... ]`, and `**` do not match a name that begins with `.` unless the pattern spells the dot out.\n * So `*` matches `env` but not `.env`.\n * To include dotfiles, name the dot explicitly:\n * - `.*` - matches only dotfiles, such as `.env`.\n * - `{.,}*` - matches every name, dotfiles included.\n *\n * Passing {@link GlobOptionsInterface.dot} as `true` lifts the guard for the whole pattern,\n * so plain wildcards match dotfiles, and `**` descends into dot directories - `**\\/*` then matches `.git/config`.\n *\n * @example\n * <caption>Common patterns and what they match</caption>\n * ```text\n * *.{ts,js} x.ts, x.js\n * @(a|b) a, b\n * +(ab) ab, abab (not: '')\n * !(a).js ab.js, x.js (not: a.js)\n * !(*.spec).ts app.ts, index.ts (not: app.spec.ts)\n * !(*.spec|*.test).ts app.ts (not: app.spec.ts, app.test.ts)\n * ```\n *\n * @example\n * <caption>Every file except a spec, recursively - the two most useful forms</caption>\n * ```ts\n * globToRegExp('**\\/!(*.spec).{ts,js}'); // any .ts or .js file whose name does not end in .spec\n * globToRegExp('**\\/!(*.spec.ts)'); // any file at all except those ending in .spec.ts\n * ```\n *\n * @see compileFragment\n * @see GlobOptionsInterface\n *\n * @since 3.0.0\n */\n\nexport function globToRegExp(glob: string, options: GlobOptionsInterface = {}): RegExp {\n return new RegExp('^' + compileFragment(glob, true, 0, options) + '$', options.flags);\n}\n\n/**\n * Builds a predicate that tests a path against a set of include and exclude globs.\n *\n * @param globs - The glob patterns to match against, where a leading `!` marks an exclusion\n * @param options - Compilation options applied to every compiled pattern\n * @returns A predicate returning `true` when `path` is included by the set and excluded by none of it\n *\n * @remarks\n * Each glob is compiled once with {@link globToRegExp} and sorted into an include or exclude list.\n * A leading `!` marks the pattern as an exclusion and is stripped before compilation.\n * A repeated `!` toggles, so `!!pattern` is an inclusion again.\n * A `!` immediately followed by `(` is left in place - it is the extglob negation {@link globToRegExp} handles,\n * not a whole-pattern exclusion.\n *\n * The predicate accepts a path when it is matched by at least one include pattern and by no exclude pattern.\n * When the set contains no include patterns, every path is considered included,\n * so a set of only exclusions matches everything except what it excludes.\n *\n * @example\n * ```ts\n * const isSource = createMatcher([ '**\\/*.ts', '!**\\/*.spec.ts' ]);\n * isSource('src/app.ts'); // true\n * isSource('src/app.spec.ts'); // false - excluded\n * isSource('src/app.js'); // false - not included\n * ```\n *\n * @see globToRegExp\n * @see GlobOptionsInterface\n *\n * @since 3.0.0\n */\n\nexport function createMatcher(globs: Array<string>, options: GlobOptionsInterface = {}): (path: string) => boolean {\n const include: Array<RegExp> = [];\n const exclude: Array<RegExp> = [];\n\n for (let glob of globs) {\n let neg = false;\n while (at(glob, 0) === Char.Bang && at(glob, 1) !== Char.LParen) {\n neg = !neg;\n glob = glob.slice(1);\n }\n\n (neg ? exclude : include).push(globToRegExp(glob, options));\n }\n\n return (path) =>\n (include.length === 0 || include.some(r => r.test(path))) &&\n !exclude.some(r => r.test(path));\n}\n\n/**\n * Walks a directory tree and collects every file the globs match.\n *\n * @param base - The directory the walk starts from and the patterns are matched against\n * @param globs - The glob patterns to match, where a leading `!` marks an exclusion\n * @param options - Compilation options applied to every compiled pattern\n * @returns The matched files as paths relative to `base`, with forward slashes, in the order the walk reaches them\n *\n * @remarks\n * The base is resolved through the shared path cache,\n * and every path below it is built by appending a name to its directory's path.\n * A file therefore costs one string and one {@link createMatcher} test rather than a resolve of its own.\n * The walk is iterative, so a deep tree cannot overflow the stack,\n * and a directory that cannot be read is skipped rather than thrown from.\n * Unless `dot` is set, a name beginning with `.` is skipped before it is tested, which prunes whole trees such as `.git`.\n * A pattern that spells a leading dot, as `.github/**` or `**\\/.cache/*` does, disarms this and lets the walk descend.\n * Symbolic links are not followed, since a link never reports itself as a directory, which is what keeps a link cycle\n * from being walked.\n *\n * @example\n * ```ts\n * collectFiles(cwd(), [ 'src/**\\/*.ts', '!**\\/*.spec.ts' ]);\n * // [ 'src/index.ts', 'src/models/files.model.ts' ]\n * ```\n *\n * @see createMatcher\n * @see GlobOptionsInterface\n *\n * @since 3.0.0\n */\n\nexport function collectFiles(base: string, globs: Array<string>, options: GlobOptionsInterface = {}): Array<string> {\n const root = FrameworkService.resolve(base);\n const matcher = createMatcher(globs, options);\n const dotted = options.dot || globs.some(glob => at(glob, 0) === Char.Dot || glob.includes('/.'));\n\n const files: Array<string> = [];\n const stack: Array<string> = [ '' ];\n\n while (stack.length > 0) {\n const directory = stack.pop()!;\n\n let entries: Array<Dirent>;\n try {\n entries = readdirSync(directory ? join(root, directory) : root, { withFileTypes: true });\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n if (!dotted && at(entry.name, 0) === Char.Dot) continue;\n const path = directory ? `${ directory }/${ entry.name }` : entry.name;\n\n if (entry.isDirectory()) stack.push(path);\n else if (matcher(path)) files.push(path);\n }\n }\n\n return files;\n}\n","/**\n * Imports\n */\n\nimport { Char } from '@constants/char.constant';\n\n/**\n * Regular-expression fragments emitted while compiling a glob into a {@link RegExp} source.\n *\n * @remarks\n * Each member is a reusable snippet of regex syntax with a fixed meaning in the compiled output,\n * so the compiler can assemble a pattern by concatenating members rather than repeating string literals.\n * Declared as a `const enum` so references inline to their literal value at compile time.\n *\n * @example\n * ```ts\n * RegexElement.NotDot + RegexElement.NotSlashRun; // '(?!\\\\.)[^/]*' - the source for a leading `*`\n * ```\n *\n * @see RegexCloser\n * @since 3.0.0\n */\n\nexport const enum RegexElement {\n /**\n * The alternation separator `|`.\n *\n * @since 3.0.0\n */\n\n Alt = '|',\n\n /**\n * The opening of a non-capturing group `(?:`.\n *\n * @since 3.0.0\n */\n\n Open = '(?:',\n\n /**\n * The literal path separator `/`.\n *\n * @since 3.0.0\n */\n\n Slash = '/',\n\n /**\n * A zero-width guard `(?!\\.)` that forbids a leading dot at the start of a segment.\n *\n * @remarks\n * Prevents a wildcard from matching a dotfile unless the pattern names the dot explicitly.\n *\n * @since 3.0.0\n */\n\n NotDot = '(?!\\\\.)',\n\n /**\n * A single character class `[^/]` matching any one character except the path separator.\n *\n * @since 3.0.0\n */\n\n NotSlash = '[^/]',\n\n /**\n * A segment boundary `(?:$|/)` matching either the end of the string or a slash.\n *\n * @since 3.0.0\n */\n\n SegBreak = '(?:$|/)',\n\n /**\n * A greedy run `[^/]*` of characters that are not the path separator.\n *\n * @since 3.0.0\n */\n\n NotSlashRun = '[^/]*',\n\n /**\n * A single character class `[^./]` matching any one character except `.` or `/`.\n *\n * @remarks\n * Emitted for `?` at the start of a segment, where a leading dot must not match.\n *\n * @since 3.0.0\n */\n\n NotDotSlash = '[^./]',\n\n /**\n * A lazy run `[^/]*?` of characters that are not the path separator.\n *\n * @remarks\n * Used as the body of a negation so the negative lookahead governs how much the segment consumes.\n *\n * @since 3.0.0\n */\n\n NotSlashLazy = '[^/]*?',\n\n /**\n * An optional absolute-path root `(?:[A-Za-z]:)?/?` matching a Windows drive prefix and/or a leading slash.\n *\n * @remarks\n * Emitted before a leading globstar so a relative pattern such as `**\\/*.ts` also matches an absolute path\n * like `/a/b/c.ts` or `C:/a/b/c.ts`.\n * Both parts are optional, so a purely relative path still matches.\n * Path separators are assumed to be forward slashes, so normalize Windows backslashes before testing.\n *\n * @since 3.0.0\n */\n\n AbsRoot = '(?:[A-Za-z]:)?/?',\n}\n\n/**\n * Maps an extglob prefix character to the regex closer that ends its non-capturing group.\n *\n * @remarks\n * Keyed by the {@link Char} code unit that precedes a `(` in an extglob construct,\n * the value carries the group-closing parenthesis together with the quantifier that reproduces the prefix semantics.\n * - `@( ... )` matches the group exactly once.\n * - `+( ... )` matches the group one or more times.\n * - `*( ... )` matches the group zero or more times.\n * - `?( ... )` matches the group zero or one time.\n * The presence of a key also signals that the prefix opens an extglob group,\n * so the compiler tests membership before treating the character as extglob syntax.\n *\n * @example\n * ```ts\n * RegexCloser[Char.Plus]; // ')+' - so `+(ab)` compiles to `(?:ab)+`\n * RegexCloser[Char.Bang]; // undefined - `!(` is a negation, handled apart\n * ```\n *\n * @see Char\n * @see RegexElement\n *\n * @since 3.0.0\n */\n\nexport const RegexCloser: Record<number, string> = {\n [Char.At]: ')',\n [Char.Plus]: ')+',\n [Char.Star]: ')*',\n [Char.Question]: ')?'\n} as const;\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Argv } from 'yargs';\nimport type { BaseArgumentsInterface } from '@argv/interfaces/argv-module.interface';\nimport type { UserExtensionInterface, ArgumentsInterface } from '@argv/interfaces/argv-module.interface';\n\n/**\n * Imports\n */\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { Injectable } from '@remotex-labs/xinject';\nimport { ArgsDefaultOptions, ArgsUsageExamples } from '@argv/constants/argv.constant';\n\n/**\n * Parses the command line in the two passes startup needs.\n *\n * @remarks\n * A configuration file may add options of its own, so the full option set is not known when the process starts.\n * The passes resolve that: {@link parseConfigFile} reads the `--config` path alone, the file it names is loaded and\n * its options collected, and {@link enhancedParse} then parses the line again knowing everything.\n * The first pass leaves `--help` and `--version` switched off so a run cannot exit on a half-built option set,\n * showing help that omits the configuration's own flags.\n * Only the second turns them on, along with the strict mode that rejects what none of the options account for.\n * Registered as a singleton, so every stage parses against one instance.\n *\n * @example\n * ```ts\n * const argv = inject(ArgvModule);\n *\n * const { config } = argv.parseConfigFile(process.argv); // 'config.xbuild.ts'\n * const userOptions = (await loadConfig(config)).userArgv; // options the file adds\n * argv.enhancedParse(process.argv, userOptions).entryPoints; // [ 'src/index.ts' ]\n * ```\n *\n * @see ArgsDefaultOptions\n * @since 2.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class ArgvModule {\n /**\n * Reads the configuration file path before the rest of the options are known.\n *\n * @param argv - Command-line arguments to read\n * @returns The parsed arguments, always carrying a `config` path\n *\n * @remarks\n * Only `config` is declared, so everything else on the line falls through into the positional list rather than\n * failing - strict mode belongs to {@link enhancedParse}, which is the pass that knows the whole option set.\n * The path is never missing, the option carrying its own default, so a caller has nothing to fall back to.\n * The arguments are passed to yargs as given rather than through `hideBin`,\n * so the executable and script land in the positions and are ignored here, `config` being the only thing read.\n *\n * @example\n * ```ts\n * argv.parseConfigFile(process.argv).config; // 'config.xbuild.ts' - the default\n *\n * // xBuild --config build/prod.xbuild.ts src/index.ts\n * argv.parseConfigFile(process.argv).config; // 'build/prod.xbuild.ts'\n * ```\n *\n * @see enhancedParse\n * @since 2.0.0\n */\n\n parseConfigFile(argv: Array<string>): BaseArgumentsInterface & { config: string } {\n return yargs(argv)\n .help(false)\n .version(false)\n .options({\n config: ArgsDefaultOptions.config\n }).parseSync() as BaseArgumentsInterface & { config: string };\n }\n\n /**\n * Parses the whole command line, xBuild's options, and the configuration together.\n *\n * @param argv - Command-line arguments to parse, executable and script included\n * @param userExtensions - Options the configuration file adds to xBuild's own\n * @returns Every option the line carried, validated against the complete set\n *\n * @throws Error - Thrown by yargs on an unknown flag, a missing value, or a value outside an option's choices\n *\n * @remarks\n * The pass that can afford to be strict, both option sets being known by now: a misspelled flag fails here rather\n * than being collected and silently ignored.\n * Files named without a flag are taken as `entryPoints` through the default command, so the usual invocation\n * needs no flag at all.\n * Help lists the two sets under headings of their own, which is done inside an overridden `showHelp` rather than\n * up front - grouping costs nothing on a run that never asks for help.\n * `hideBin` drops the executable and script here, unlike the first pass, so the positions hold only what\n * the user typed.\n *\n * @example\n * ```ts\n * // xBuild src/app.ts --bundle --minify --env prod\n * const args = argv.enhancedParse(process.argv, { env: { type: 'string' } });\n *\n * args.entryPoints; // [ 'src/app.ts' ]\n * args.bundle; // true\n * args.env; // 'prod' - the configuration's own option\n * ```\n *\n * @see ArgsUsageExamples\n * @since 2.0.0\n */\n\n enhancedParse(argv: Array<string>, userExtensions: UserExtensionInterface = {}): ArgumentsInterface {\n const parser = yargs(hideBin(argv)).locale('en');\n const originalShowHelp = parser.showHelp;\n parser.showHelp = function (consoleFunction?: string | ((s: string) => void)): Argv<unknown> {\n this.group(Object.keys(ArgsDefaultOptions), 'xBuild Options:');\n this.group(Object.keys(userExtensions), 'user Options:');\n\n return originalShowHelp.call(this, consoleFunction as (s: string) => void);\n };\n\n parser\n .usage('Usage: xBuild [files..] [options]')\n .command('* [entryPoints..]', 'Specific files to build (supports glob patterns)', (yargs) => {\n return yargs.positional('entryPoints', {\n describe: 'Specific files to build (supports glob patterns)',\n type: 'string',\n array: true\n });\n })\n .options(userExtensions)\n .options(ArgsDefaultOptions)\n .epilogue('For more information, check the documentation https://remotex-labs.github.io/xBuild/')\n .help()\n .alias('help', 'h')\n .strict()\n .version();\n\n ArgsUsageExamples.forEach(([ command, description ]) => {\n parser.example(command, description);\n });\n\n return parser.parseSync();\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Options } from 'yargs';\n\n/**\n * Path the `--config` option falls back to.\n *\n * @remarks\n * Resolved against the working directory, so the file is picked up by name from wherever the build was started.\n * It is the default of the option itself rather than a fallback applied afterward,\n * which is what lets every parse pass report a path whether one was typed.\n *\n * @example\n * ```ts\n * ArgsConfigPath; // 'config.xbuild.ts'\n * ArgsDefaultOptions.config.default; // 'config.xbuild.ts' - the same value, reused\n * ```\n *\n * @since 3.0.0\n */\n\nexport const ArgsConfigPath = 'config.xbuild.ts' as const;\n\n/**\n * Every option xBuild itself accepts, in the form yargs declares them.\n *\n * @remarks\n * One table serving three purposes:\n * - it declares the options for the full parse,\n * - it supplies `config` on its own to the early pass that only needs the configuration path,\n * - and its keys name the flags help gathers under the xBuild heading.\n *\n * An option added here is therefore declared, parsed, and documented by that one edit.\n * Only `config` carries a default, so every other flag is absent from the parse result unless it was typed.\n * That is what lets configuration handling tell a flag that was left out from one that was passed as `false`.\n * `platform` and `format` restrict their values, so an unrecognized one fails during parsing rather than reaching the\n * build.\n *\n * @example\n * ```ts\n * ArgsDefaultOptions.minify.alias; // 'm'\n * ArgsDefaultOptions.format.choices; // [ 'cjs', 'esm', 'iife' ]\n * Object.keys(ArgsDefaultOptions); // the flags listed under 'xBuild Options:' in help\n * ```\n *\n * @see ArgsConfigPath\n * @since 3.0.0\n */\n\nexport const ArgsDefaultOptions: Record<string, Options> = {\n entryPoints: {\n describe: 'Source files to build (supports glob patterns)',\n type: 'string',\n array: true\n },\n typeCheck: {\n describe: 'Perform type checking without building output',\n alias: 'tc',\n type: 'boolean'\n },\n platform: {\n describe: 'Target platform for the build output',\n alias: 'p',\n type: 'string',\n choices: [ 'browser', 'node', 'neutral' ] as const\n },\n serve: {\n describe: 'Start server to the <folder>',\n alias: 's',\n type: 'string'\n },\n outdir: {\n describe: 'Directory for build output files',\n alias: 'o',\n type: 'string'\n },\n declaration: {\n describe: 'Generate TypeScript declaration files (.d.ts)',\n alias: 'de',\n type: 'boolean'\n },\n watch: {\n describe: 'Watch mode - rebuild on file changes',\n alias: 'w',\n type: 'boolean'\n },\n config: {\n describe: 'Path to build configuration file',\n alias: 'c',\n type: 'string',\n default: ArgsConfigPath\n },\n tsconfig: {\n describe: 'Path to TypeScript configuration file',\n alias: 'tsc',\n type: 'string'\n },\n minify: {\n describe: 'Minify the build output',\n alias: 'm',\n type: 'boolean'\n },\n bundle: {\n describe: 'Bundle dependencies into output files',\n alias: 'b',\n type: 'boolean'\n },\n types: {\n describe: 'Enable type checking during build process',\n alias: 'btc',\n type: 'boolean'\n },\n failOnError: {\n describe: 'Fail build when TypeScript errors are detected',\n alias: 'foe',\n type: 'boolean'\n },\n format: {\n describe: 'Output module format',\n alias: 'f',\n type: 'string',\n choices: [ 'cjs', 'esm', 'iife' ]\n },\n verbose: {\n describe: 'Verbose error stack traces',\n alias: 'v',\n type: 'boolean'\n },\n build: {\n describe: 'Select an build configuration variant by names (as defined in your config file)',\n alias: 'xb',\n type: 'string',\n array: true\n },\n clean: {\n describe: 'Clean build artifacts',\n type: 'boolean',\n default: false\n }\n} as const;\n\n/**\n * Command and description pairs shown in the examples section of the help output.\n *\n * @remarks\n * Registered one by one on the parser, so the order here is the order they are printed in.\n * They document the combinations worth reaching for rather than every flag,\n * the option list above already covers each flag on its own.\n *\n * @example\n * ```ts\n * ArgsUsageExamples[0]; // [ 'xBuild src/index.ts', 'Build a single file with default settings' ]\n * ```\n *\n * @see ArgsDefaultOptions\n * @since 3.0.0\n */\n\nexport const ArgsUsageExamples = [\n [ 'xBuild src/index.ts', 'Build a single file with default settings' ],\n [ 'xBuild src/**/*.ts --bundle --minify', 'Bundle and minify all TypeScript files' ],\n [ 'xBuild src/app.ts -s', 'Development mode with watch and dev server' ],\n [ 'xBuild src/app.ts -s dist', 'Development mode with watch and dev server from dist folder' ],\n [ 'xBuild src/lib.ts --format esm --declaration', 'Build ESM library with type definitions' ],\n [ 'xBuild src/server.ts --platform node --outdir dist', 'Build Node.js application to dist folder' ],\n [ 'xBuild --typeCheck', 'Type check only without generating output' ],\n [ 'xBuild --config custom.xbuild.ts', 'Use custom configuration file' ]\n] as const;\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { IncomingMessage, ServerResponse } from 'http';\nimport type { ServerAddressInterface, ServerConfigurationInterface, ServerEventsType } from '@server/interfaces/server.interface';\n\n/**\n * Imports\n */\n\nimport * as http from 'http';\nimport * as https from 'https';\nimport { extname } from 'path';\nimport { readFileSync } from 'fs';\nimport html from './html/server.html';\nimport { join } from '@remotex-labs/xmap';\nimport { inject } from '@remotex-labs/xinject';\nimport { Subject } from '@remotex-labs/xobservable';\nimport { readdir, stat, readFile } from 'fs/promises';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * Serves one directory over HTTP or HTTPS, files and listings alike.\n *\n * @remarks\n * Meant for looking at build output while developing:\n * a request maps to a path under the root, a file is sent with a content type guessed from its extension,\n * and a directory is rendered as a browsable listing.\n * A configuration can take a request over before any of that happens,\n * which is the hook to reach for when the output needs an API beside it or a single-page fallback.\n * Nothing here writes to a terminal: what it does is reported on a stream, so a run decides what to say about it.\n * Constructed rather than injected, so a build can run several of them over different roots at once.\n *\n * @example\n * ```ts\n * const server = new ServerModule({ port: 0, verbose: true }, 'dist');\n *\n * await server.start(); // resolves once listening, after onStart has run\n * server.config.port; // 54321 - the port the system picked, written back\n * await server.stop();\n * ```\n *\n * @see ServerConfigurationInterface\n * @since 2.0.0\n */\n\nexport class ServerModule {\n /**\n * Node server currently listening, absent until {@link start} and again after {@link stop}.\n *\n * @remarks\n * Holds either an HTTP or an HTTPS server,\n * since the HTTPS type extends the HTTP one and the two are interchangeable here.\n * Its presence is what {@link stop} treats as whether anything is running.\n *\n * @since 2.0.0\n */\n\n private server?: http.Server;\n\n /**\n * The stream everything this server does is reported on.\n *\n * @remarks\n * The server says what happened and writes none of it,\n * so a run decides for itself what reaches a terminal, and one that wants none of it subscribes to nothing.\n * Kept private and reached through {@link pipe} and {@link subscribe},\n * which is what keeps a reader from reporting an event of its own.\n *\n * @see ServerEventsType\n * @since 3.0.0\n */\n\n private readonly events$ = new Subject<ServerEventsType>();\n\n /**\n * Absolute directory every request is resolved inside.\n *\n * @remarks\n * Resolved once in the constructor, so a later change to the working directory cannot move what is being served.\n *\n * @since 2.0.0\n */\n\n private readonly rootDir: string;\n\n /**\n * Framework service, consulted for the directory the bundled certificates ship in.\n *\n * @remarks\n * Only reached when HTTPS is started without a key and certificate of its own.\n *\n * @see FrameworkService\n * @since 2.0.0\n */\n\n private readonly framework = inject(FrameworkService);\n\n /**\n * Creates a server over one directory.\n *\n * @param config - How to listen and what to do with requests\n * @param dir - Directory to serve, resolved to an absolute path immediately\n *\n * @remarks\n * The configuration is kept by reference rather than copied: the host and port defaults land on it here,\n * and the port the system assigns lands on it once listening.\n * The object the caller passed is therefore also how the caller learns what was bound.\n * A port of `0`, which is also the default, leaves the choice to the operating system.\n *\n * @example\n * ```ts\n * const config = { port: 8080, https: true, onRequest: (req, res, next) => next() };\n * const server = new ServerModule(config, './public');\n *\n * config.host; // 'localhost' - defaulted here, on the caller's own object\n * ```\n *\n * @see ServerConfigurationInterface\n * @since 2.0.0\n */\n\n constructor(readonly config: ServerConfigurationInterface, dir: string) {\n this.rootDir = FrameworkService.resolve(dir);\n this.config.port ||= 0;\n this.config.host ||= 'localhost';\n }\n\n /**\n * The event stream's `pipe`, bound to the stream.\n *\n * @remarks\n * Hands out the operator chain without handing out the subject,\n * so a reader composes on what the server reports and cannot report anything itself.\n *\n * @example\n * ```ts\n * server.pipe(filter(event => event.type === 'request')).subscribe(report);\n * ```\n *\n * @see subscribe\n * @since 3.0.0\n */\n\n get pipe(): typeof this.events$.pipe {\n return this.events$.pipe.bind(this.events$);\n }\n\n /**\n * The event stream's `subscribe`, bound to the stream.\n *\n * @remarks\n * How a run learns what the server is doing, since the server itself writes nothing.\n * Answers with the handle that ends the subscription, as the stream's own `subscribe` does.\n *\n * @example\n * ```ts\n * const unsubscribe = server.subscribe(event => event.type); // 'start', then 'request'\n * unsubscribe();\n * ```\n *\n * @see pipe\n * @since 3.0.0\n */\n\n get subscribe(): typeof this.events$.subscribe {\n return this.events$.subscribe.bind(this.events$);\n }\n\n /**\n * Starts listening over HTTPS when the configuration asks for it and over HTTP otherwise.\n *\n * @returns A promise settling once the server is listening\n *\n * @remarks\n * The `onStart` hook runs from the listen callback,\n * so it has already been called - and the assigned port already written back - by the time this resolves.\n * Nothing guards against starting twice:\n * a second call replaces the reference and leaves the first server listening with no way left to close it,\n * so reach for {@link restart} rather than starting again.\n *\n * @example\n * ```ts\n * const server = new ServerModule({ port: 3000, onStart: ({ url }) => console.log(url) }, 'dist');\n * await server.start(); // logs 'http://localhost:3000'\n * ```\n *\n * @see stop\n * @see restart\n *\n * @since 2.0.0\n */\n\n async start(): Promise<void> {\n if (this.config.https)\n return await this.startHttpsServer();\n\n await this.startHttpServer();\n }\n\n /**\n * Closes the server and waits for it to finish.\n *\n * @returns A promise settling once every connection has ended\n *\n * @throws Error - Reported by Node when the server was already closed underneath\n *\n * @remarks\n * Closing refuses new connections and waits on the ones in flight,\n * so a request already in progress delays this rather than ending mid-flight.\n * Stopping when nothing is running is not an error - it reports as much and returns.\n *\n * @example\n * ```ts\n * await server.stop(); // 'Server stopped.'\n * await server.stop(); // 'No server is currently running.'\n * ```\n *\n * @see start\n * @since 2.0.0\n */\n\n async stop(): Promise<void> {\n if (!this.server) return this.events$.next({ type: 'stop', running: false });\n\n await new Promise<void>((resolve, reject) => {\n this.server!.close(err => {\n if (err) reject(err);\n else resolve();\n });\n });\n\n this.server = undefined;\n this.events$.next({ type: 'stop', running: true });\n }\n\n /**\n * Stops the server and starts it again.\n *\n * @returns A promise settling once the new server is listening\n *\n * @remarks\n * Reads the configuration afresh on the way back up, so an edit made while it was running takes effect.\n * A port left at `0` is no longer `0` by then, since the previous run wrote the assigned one back,\n * so a restart keeps the port it was given rather than asking for another.\n *\n * @example\n * ```ts\n * server.config.verbose = true;\n * await server.restart(); // 'Restarting server...' then listening again, now logging requests\n * ```\n *\n * @see stop\n * @see start\n *\n * @since 2.0.0\n */\n\n async restart(): Promise<void> {\n await this.stop();\n await this.start();\n }\n\n /**\n * Writes the port the system assigned back onto the configuration.\n *\n * @remarks\n * Only a configured `0` is replaced, since `0` is the value that leaves the choice to the operating system.\n * A port asked for by number is already what was bound.\n * Called from the listen callback, before `onStart`, so the hook and every later reader see the real port.\n *\n * @since 2.0.0\n */\n\n private setActualPort(): void {\n if (this.config.port === 0) {\n const address = this.server!.address();\n if(address && typeof address === 'object' && address.port)\n this.config.port = address.port;\n }\n }\n\n /**\n * Creates and starts the plain HTTP server.\n *\n * @returns A promise settling once the server is listening\n *\n * @remarks\n * Every request goes through {@link handleRequest},\n * which is handed the default handling as a callback,\n * so a configuration hook can decide whether to run it.\n *\n * @since 2.0.0\n */\n\n private startHttpServer(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.server = http.createServer((req, res) => {\n this.handleRequest(req, res, () => this.defaultResponse(req, res));\n });\n\n this.server.listen(this.config.port, this.config.host, () => {\n this.setActualPort();\n const address: ServerAddressInterface = {\n host: this.config.host!,\n port: this.config.port!,\n url: `http://${ this.config.host }:${ this.config.port }`\n };\n\n this.config.onStart?.(address);\n this.events$.next({ ...address, type: 'start' });\n resolve();\n });\n });\n }\n\n /**\n * Creates and starts the HTTPS server.\n *\n * @returns A promise settling once the server is listening\n *\n * @throws Error - Raised when a key or certificate cannot be read\n *\n * @remarks\n * A configuration naming neither key nor certificate falls back to the pair shipped with the framework,\n * so HTTPS can be switched on without producing one first.\n * That pair is self-signed, so a browser will warn about it, which is what a development server can live with.\n * Both files are read synchronously, before anything is listening,\n * so a missing one fails the start rather than the first request.\n *\n * @since 2.0.0\n */\n\n private startHttpsServer(): Promise<void> {\n return new Promise((resolve) => {\n const options = {\n key: readFileSync(this.config.key ?? join(this.framework.frameworkRoot, '..', 'certs', 'server.key')),\n cert: readFileSync(this.config.cert ?? join(this.framework.frameworkRoot, '..', 'certs', 'server.crt'))\n };\n\n this.server = https.createServer(options, (req, res) => {\n this.handleRequest(req, res, () => this.defaultResponse(req, res));\n });\n\n this.server.listen(this.config.port, this.config.host, () => {\n this.setActualPort();\n const address: ServerAddressInterface = {\n host: this.config.host!,\n port: this.config.port!,\n url: `https://${ this.config.host }:${ this.config.port }`\n };\n\n this.config.onStart?.(address);\n this.events$.next({ ...address, type: 'start' });\n resolve();\n });\n });\n }\n\n /**\n * Passes a request to the configuration's hook or to the default handling when there is none.\n *\n * @param req - Request as it arrived\n * @param res - Response to write to\n * @param defaultHandler - The static-file handling, for the hook to call or to skip\n *\n * @remarks\n * A hook that never calls the handler owns the response entirely,\n * which is what makes an API route or a single-page fallback possible.\n * Only what throws synchronously reaches the error response here:\n * the default handling is asynchronous and catches its own failures,\n * and a hook that rejects a promise of its own is beyond this.\n *\n * @see sendError\n * @since 2.0.0\n */\n\n private handleRequest(req: IncomingMessage, res: ServerResponse, defaultHandler: () => void): void {\n try {\n this.events$.next({ type: 'request', url: req.url ?? '' });\n\n if (this.config.onRequest) {\n this.config.onRequest(req, res, defaultHandler);\n } else {\n defaultHandler();\n }\n } catch (error) {\n this.sendError(res, <Error> error);\n }\n }\n\n /**\n * Maps a file extension to the content type it is served as.\n *\n * @param ext - Extension without its dot\n * @returns The matching content type, or the binary fallback for an extension not listed\n *\n * @remarks\n * Covers what a build emits rather than the web at large.\n * TypeScript is served as plain text, so a browser shows a source file instead of downloading it,\n * and an unlisted extension downloads under the binary fallback rather than under a guess.\n *\n * @since 2.0.0\n */\n\n private getContentType(ext: string): string {\n const contentTypes: Record<string, string> = {\n html: 'text/html',\n css: 'text/css',\n js: 'application/javascript',\n cjs: 'application/javascript',\n mjs: 'application/javascript',\n ts: 'text/plain',\n map: 'application/json',\n json: 'application/json',\n png: 'image/png',\n jpg: 'image/jpeg',\n gif: 'image/gif',\n txt: 'text/plain'\n };\n\n return contentTypes[ext] || 'application/octet-stream';\n }\n\n /**\n * Resolves a request to a path under the root and serves whatever is there.\n *\n * @param req - Request as it arrived\n * @param res - Response to write to\n *\n * @remarks\n * The request path is joined onto the root and the result checked for the root prefix,\n * so a path climbing out with `..` is refused with a 403.\n * The check is by prefix rather than true containment,\n * so a sibling directory whose name starts with the root's own would pass it.\n * A directory is listed and a file is sent.\n * Anything else on disk - a socket or a device - matches neither, and the request ends unanswered.\n * A path that cannot be reached at all is reported as missing,\n * and a failed `favicon.ico` is passed over in the log, since browsers ask for one unprompted on every visit.\n *\n * @see handleFile\n * @see handleDirectory\n *\n * @since 2.0.0\n */\n\n private async defaultResponse(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const requestPath = req.url === '/' ? '' : req.url?.replace(/^\\/+/, '') || '';\n const fullPath = join(this.rootDir, requestPath);\n\n if (!fullPath.startsWith(this.rootDir)) {\n res.statusCode = 403;\n res.end();\n\n return;\n }\n\n try {\n const stats = await stat(fullPath);\n\n if (stats.isDirectory()) {\n await this.handleDirectory(fullPath, requestPath, res);\n } else if (stats.isFile()) {\n await this.handleFile(fullPath, res);\n }\n } catch (error) {\n this.events$.next({ type: 'error', error: <Error> error, url: req.url });\n this.sendNotFound(res);\n }\n }\n\n /**\n * Renders a directory as a browsable listing.\n *\n * @param fullPath - Absolute path of the directory to list\n * @param requestPath - The same directory as the request spelled it, relative to the root\n * @param res - Response to write to\n *\n * @remarks\n * Entries are told apart by whether they have an extension,\n * so a directory carrying a dot in its name is drawn as a file,\n * since a listing is navigation rather than a report.\n * The request path is also split into a trail of links, one per directory it names,\n * which is what lets a visitor climb back out.\n * Names are put into the template as they are, so a filename containing markup reaches the page intact.\n *\n * @since 2.0.0\n */\n\n private async handleDirectory(fullPath: string, requestPath: string, res: ServerResponse): Promise<void> {\n const files = await readdir(fullPath);\n let fileList = files.map(file => {\n const fullPath = join(requestPath, file);\n const ext = extname(file).slice(1) || 'folder';\n\n if(ext === 'folder') {\n return `\n <a href=\"/${ fullPath }\" class=\"folder-row\">\n <div class=\"icon\"><i class=\"fa-solid fa-folder\"></i></div>\n <div class=\"meta\"><div class=\"name\">${ file }</div><div class=\"sub\">Folder</div></div>\n </a>\n `;\n }\n\n return `\n <a href=\"/${ fullPath }\" class=\"file-row\">\n <div class=\"icon\"><i class=\"fa-solid fa-file-code\"></i></div>\n <div class=\"meta\"><div class=\"name\">${ file }</div><div class=\"sub\">${ ext }</div></div>\n </a>\n `;\n }).join('');\n\n if(!fileList) {\n fileList = '<div class=\"empty\">No files or folders here.</div>';\n } else {\n fileList = `<div class=\"list\">${ fileList }</div>`;\n }\n\n let activePath = '/';\n const segments = requestPath.split('/').map(path => {\n activePath += `${ path }/`;\n\n return `<li><a href=\"${ activePath }\">${ path }</a></li>`;\n }).join('');\n\n const htmlResult = html.replace('${ fileList }', fileList)\n .replace('${ paths }', '<li><a href=\"/\">root</a></li>' + segments)\n .replace('${ up }', '/' + requestPath.split('/').slice(0, -1).join('/'));\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(htmlResult);\n }\n\n /**\n * Sends one file.\n *\n * @param fullPath - Absolute path of the file to send\n * @param res - Response to write to\n *\n * @remarks\n * Read whole before anything is written,\n * so the response carries no length and a large file is held in memory rather than streamed,\n * which a development server over its own build output can afford.\n * A file with no extension is treated as text.\n *\n * @see getContentType\n * @since 2.0.0\n */\n\n private async handleFile(fullPath: string, res: ServerResponse): Promise<void> {\n const ext = extname(fullPath).slice(1) || 'txt';\n const contentType = this.getContentType(ext);\n\n const data = await readFile(fullPath);\n res.writeHead(200, { 'Content-Type': contentType });\n res.end(data);\n }\n\n /**\n * Answers a request that reached nothing.\n *\n * @param res - Response to write to\n *\n * @remarks\n * Plain text rather than the listing template, since the answer is for whatever asked rather than for a reader.\n *\n * @since 2.0.0\n */\n\n private sendNotFound(res: ServerResponse): void {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n }\n\n /**\n * Answers a request that failed and reports why.\n *\n * @param res - Response to write to\n * @param error - The failure to report\n *\n * @remarks\n * The reason is logged rather than sent,\n * so a stack trace reaches the developer running the server and not whoever is connected to it.\n *\n * @since 2.0.0\n */\n\n private sendError(res: ServerResponse, error: Error): void {\n this.events$.next({ type: 'error', error });\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end('Internal Server Error');\n }\n}\n","<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/><title>Dark File Browser — FTP-like</title><link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css\" integrity=\"sha512-2SwdPD6INVrV/lHTZbO2nodKhrnDdJK9/kg2XD1r9uGqPo1cUbujc+IYdlYdEErWNu69gVcYgdxlmVmzTWnetw==\" crossorigin=\"anonymous\" referrerpolicy=\"no-referrer\" /><style>:root{--bg:#0b0f14;--panel:#0f1720;--muted:#9aa4b2;--accent:#E5C07B;--glass:rgba(255,255,255,0.03);--card:#0c1116;--radius:12px;--gap:12px;--shadow:0 6px 18px rgba(0,0,0,0.4);--file-icon-size:40px;font-family:Inter,ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial}*{box-sizing:border-box;font-style:normal !important}html,body{height:100%;margin:0;font-size:14px;color:#dce7ef;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:radial-gradient(1200px 600px at 10% 10%,rgba(110,231,183,0.04),transparent 8%),linear-gradient(180deg,rgba(255,255,255,0.01),transparent 20%),var(--bg);padding:28px;display:flex;gap:20px;align-items:flex-start;justify-content:center}.app{width:1100px;max-width:98vw;display:flex;gap:18px;padding:18px;border-radius:16px;box-shadow:var(--shadow);border:1px solid rgba(255,255,255,0.03);background:linear-gradient(180deg,rgba(255,255,255,0.02),rgba(255,255,255,0));overflow:hidden}.sidebar{width:260px;background:linear-gradient(180deg,rgba(255,255,255,0.01),transparent);border-radius:var(--radius);padding:14px}.brand{display:flex;gap:12px;align-items:center;margin-bottom:10px}.logo{width:46px;height:46px;border-radius:10px;background:linear-gradient(135deg,#b65b9f 0%,#804b8f 100%);display:flex;align-items:center;justify-content:center;font-weight:700}.brand h1{font-size:16px;margin:0}.muted{color:var(--muted);font-size:13px}.search{margin:12px 0}.search input{width:100%;padding:10px 12px;border-radius:10px;border:1px solid rgba(255,255,255,0.03);background:var(--glass);color:inherit}.quick-list{margin-top:12px}.quick-list a{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;background:transparent;color:var(--muted);text-decoration:none;cursor:pointer;transition:color 0.15s ease}.quick-list a:hover{color:var(--accent)}.main{flex:1;display:flex;flex-direction:column}.topbar{display:flex;align-items:center;gap:12px;padding-bottom:12px}.breadcrumbs{list-style:none;display:flex;gap:8px;align-items:center;background:var(--glass);padding:8px 12px;border-radius:var(--radius);margin:0}.breadcrumbs li{display:flex;align-items:center}.breadcrumbs li:not(:last-child)::after{content:'>';margin-left:8px;color:var(--muted)}.breadcrumbs a{color:var(--muted);text-decoration:none;transition:color 0.15s ease}.breadcrumbs a:hover{color:var(--accent)}.list{margin-top:14px;display:grid;grid-template-columns:1fr;gap:10px}.list a{display:flex;text-decoration:none;color:inherit}.folder-row,.file-row{display:flex;gap:12px;align-items:center;padding:10px;border-radius:10px;background:linear-gradient(180deg,rgba(255,255,255,0.01),transparent);border:1px solid rgba(255,255,255,0.02);transition:color 0.25s ease}.icon{width:var(--file-icon-size);height:var(--file-icon-size);border-radius:10px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,0.02);flex-shrink:0;transition:background 0.25s ease,color 0.25s ease}.folder-row:hover,.file-row:hover{color:var(--accent)}.folder-row:hover .icon{background:rgba(152,195,121,0.2)}.file-row:hover .icon{background:rgba(224,108,117,0.2)}.folder-row:hover .icon i{color:#98C379}.file-row:hover .icon i{color:#e09c6c}.meta{display:flex;flex-direction:column}.name{font-weight:600}.sub{color:var(--muted);font-size:13px}.empty{padding:40px;text-align:center;color:var(--muted)}@media (max-width:880px){.app{flex-direction:column;padding:12px}.sidebar,.main{width:100%}}</style></head><body><div class=\"app\"><aside class=\"sidebar\"><div class=\"brand\"><div class=\"logo\">F</div><div><h1>xBuildFTP</h1><div class=\"muted\">Browse & serve files</div></div></div><div class=\"search\"><input placeholder=\"Search files & folders...\"/></div><div class=\"quick-list\"><a href=\"/\">🏠 Home</a><a href=\"${ up }\">⬆️ Up</a></div></aside><main class=\"main\"><div class=\"topbar\"><div class=\"topbar\"><ul class=\"breadcrumbs\"> ${ paths } </ul></div></div> ${ fileList } </main></div></body><script> const searchInput = document.querySelector('.search input'); const listItems = document.querySelectorAll('.list > .folder-row, .list > .file-row'); const emptyMessage = document.querySelector('.empty'); searchInput.addEventListener('input', () => { const query = searchInput.value.toLowerCase(); let anyVisible = false; listItems.forEach(item => { const name = item.querySelector('.name').textContent.toLowerCase(); if (name.includes(query)) { item.style.display = 'flex'; anyVisible = true; } else { item.style.display = 'none'; } }); emptyMessage.style.display = anyVisible ? 'none' : 'block'; }); </script></html>","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Message } from 'esbuild';\nimport type { DeepPartialType } from '@interfaces/types.interface';\nimport type { ConfigurationInterface } from '@interfaces/configuration.interface';\nimport type { BuildResultInterface, LifecycleEventsType, LifecycleLogsType } from '@interfaces/lifecycle.interface';\n\n/**\n * Imports\n */\n\nimport { inject } from '@remotex-labs/xinject';\nimport { xBuildError } from '@errors/xbuild.error';\nimport { Subject } from '@remotex-labs/xobservable';\nimport { VariantService } from '@services/variant.service';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { TypescriptService } from '@typescript/services/typescript.service';\n\n/**\n * Runs a whole configuration - every variant it declares, in the order their dependencies allow.\n *\n * @remarks\n * Owns the configuration for a run and the event stream the variants report on,\n * while each variant owns the build it runs.\n * A variant is constructed for every entry the configuration declares and reused from then on,\n * so re-reading an edited configuration adds what it gained and leaves the rest running.\n *\n * @example\n * ```ts\n * const build = new BuildService(config, { watch: true });\n * build.subscribe(event => event.type); // 'start', then 'end'\n *\n * const results = await build.build();\n * results.length; // 2 - one per variant\n * ```\n *\n * @see VariantService\n * @see ConfigurationInterface\n *\n * @since 3.0.0\n */\n\nexport class BuildService {\n /**\n * The stream every variant reports its start and end on.\n *\n * @remarks\n * Handed to each variant as it is constructed, so one stream carries the whole run\n * rather than a reader subscribing to each variant in turn.\n * Kept private and reached through `pipe` and `subscribe`,\n * which is what keeps a reader from pushing an event of its own onto it.\n *\n * @see LifecycleEventsType\n * @since 3.0.0\n */\n\n private readonly events$ = new Subject<LifecycleEventsType>();\n\n /**\n * The configuration service this run reads and writes through.\n *\n * @remarks\n * The injected instance rather than one of its own, and the same instance every variant selects from,\n * so a change written here reaches the variants without being handed to them.\n *\n * @see ConfigurationService\n * @since 3.0.0\n */\n\n private readonly config$ = inject(ConfigurationService);\n\n /**\n * Applies a configuration and constructs a variant for every entry it declares.\n *\n * @param config - Configuration to run, merged over whatever the service already holds\n * @param argv - Parsed command line the build was started with, empty when the caller passes none\n *\n * @remarks\n * The configuration is patched rather than put in place of what is there,\n * so the built-in defaults survive underneath what a configuration file states.\n * The subscription that follows is called at once with the merged configuration,\n * which is what constructs the variants before the constructor returns,\n * and it keeps them current with every later change.\n *\n * @example\n * ```ts\n * const build = new BuildService({ logLevel: 'warning', variants: { esm } }, { watch: true });\n * ```\n *\n * @see ConfigurationService.patch\n * @since 3.0.0\n */\n\n constructor(config: ConfigurationInterface, private argv: Record<string, unknown> = {}) {\n this.config$.patch(config);\n this.config$.subscribe(this.parseVariants.bind(this));\n }\n\n /**\n * The event stream's `pipe`, bound to the stream.\n *\n * @remarks\n * Hands out the operator chain without handing out the subject,\n * so a reader composes on the run's events and cannot report one of its own.\n *\n * @example\n * ```ts\n * const ended = build.pipe(filter(event => event.type === 'end'));\n * ended.subscribe(report);\n * ```\n *\n * @see BuildService.subscribe\n * @since 3.0.0\n */\n\n get pipe(): typeof this.events$.pipe {\n return this.events$.pipe.bind(this.events$);\n }\n\n /**\n * The event stream's `subscribe`, bound to the stream.\n *\n * @remarks\n * The plain way to watch a run, for a reader wanting every event rather than a filtered view.\n * Answers with the handle that ends the subscription, as the stream's own `subscribe` does.\n *\n * @example\n * ```ts\n * const unsubscribe = build.subscribe(event => event.type); // 'start', then 'end'\n * unsubscribe();\n * ```\n *\n * @see BuildService.pipe\n * @since 3.0.0\n */\n\n get subscribe(): typeof this.events$.subscribe {\n return this.events$.subscribe.bind(this.events$);\n }\n\n /**\n * Starts the configuration again from the one this service was constructed with.\n *\n * @param config - Configuration to apply over the initial one\n *\n * @remarks\n * Reloads rather than patches, so whatever accumulated since construction is dropped,\n * and only the initial configuration survives underneath.\n * That is what re-reading an edited file wants, since patching a list would extend it rather than replace it.\n * Assigning is also what ends a variant,\n * since one the new configuration no longer declares disposes of itself as the change reaches it.\n *\n * @example\n * ```ts\n * build.configuration = { common: { esbuild: { minify: false } } };\n * ```\n *\n * @see ConfigurationService.reload\n * @since 3.0.0\n */\n\n set configuration(config: DeepPartialType<ConfigurationInterface>) {\n this.config$.reload(config);\n }\n\n /**\n * Builds the variants named, or every variant the configuration declares, in the order `dependOn` asks for.\n *\n * @param names - Variants to build, building every variant the configuration declares when omitted\n * @returns One result per variant asked for, in the order they were named\n * @throws xBuildError - When a `dependOn` chain closes on itself, or names a variant that does not exist\n *\n * @remarks\n * Naming variants builds those and whatever they wait for, leaving everything else alone.\n * A name no variant answers to is passed over rather than reported as an error,\n * so a list naming nothing this configuration declares builds nothing at all.\n * A dependency built along the way reports on the event stream like any other build\n * while staying out of the results, which carry the variants that were asked for.\n * The whole graph is wired before any variant runs, and every variant waits on the same gate,\n * so a chain that turns out to be broken builds nothing at all rather than part of the output.\n * A variant that several others depend on is built once and its result shared,\n * since the graph is walked through a cache keyed by name.\n * A build that fails does not reject here - its errors arrive on its own result.\n * A dependency counts as failed where it produced no output, whether it threw or only reported errors.\n * The variant waiting on it is skipped rather than built,\n * and the result {@link skipped} shapes carries no output either, so its own dependents skip in turn.\n *\n * @example\n * ```ts\n * const results = await build.build();\n * results.length; // 2 - the types variant first, then the bundle that depends on it\n *\n * const [ app ] = await build.build([ 'app' ]); // types builds too, since app waits for it\n * await build.build([ 'umd' ]); // [] - no variant answers to the name\n * ```\n *\n * @see BuildResultInterface\n * @since 3.0.0\n */\n\n async build(names?: Array<string>): Promise<Array<BuildResultInterface>> {\n const variants = new Map(Array.from(VariantService.get(), variant => [ variant.name, variant ] as const));\n const cache = new Map<string, Promise<BuildResultInterface>>();\n const start = Promise.withResolvers<void>();\n\n const run = (name: string, path: Array<string> = []): Promise<BuildResultInterface> => {\n if (path.includes(name))\n throw new xBuildError(`Circular dependency detected: ${ [ ...path, name ].join(' → ') }`);\n if (!variants.has(name))\n throw new xBuildError(`Variant \"${ path.at(-1) }\" depends on \"${ name }\", which is not a variant`);\n\n if (!cache.has(name)) {\n const dependOn = this.getDependOn(name);\n\n cache.set(name, Promise\n .all([ start.promise, ...dependOn.map(dependency => run(dependency, [ ...path, name ])) ])\n .then(([ , ...results ]) => {\n const failed = dependOn.filter((_, index) => Object.keys(results[index]?.metafile?.outputs ?? {}).length < 1);\n if (failed.length) return this.skipped(name, failed);\n\n return variants.get(name)!.build();\n })\n );\n }\n\n return cache.get(name)!;\n };\n\n const results = Array.from(names?.filter(name => variants.has(name)) ?? variants.keys(), name => run(name));\n start.resolve();\n\n return Promise.all(results);\n }\n\n /**\n * Type-checks the variants named, or every variant the configuration declares, without building any of them.\n *\n * @param names - Variants to check, checking every variant the configuration declares when omitted\n * @returns The messages each variant's check reported, keyed by the variant's name\n *\n * @remarks\n * The variants are checked one at a time rather than together,\n * since every variant carries a TypeScript program of its own.\n * Each variant answers with the buckets a build would file its messages under,\n * so a diagnostic reads at the level the configuration gives it rather than in the compiler's own shape.\n * A variant that checks clean is present with its buckets empty rather than left out,\n * so a reader tells a clean variant from one that was never checked.\n * Only the variants named are checked, dependencies among them or not,\n * since a variant is checked against the files its own build reaches,\n * and what another variant reaches is that variant's own to report.\n * A name is matched against the variants rather than looked up,\n * so one no variant answers to is passed over,\n * and a list naming nothing this configuration declares checks nothing at all.\n *\n * @example\n * ```ts\n * const { esm } = await build.typeChack();\n * esm.error.length; // 0 - nothing to report\n *\n * await build.typeChack([ 'esm' ]); // { esm: { ... } } - cjs is left alone\n * await build.typeChack([ 'umd' ]); // {} - no variant answers to the name\n * ```\n *\n * @see LifecycleLogsType\n * @since 3.0.0\n */\n\n async typeChack(names?: Array<string>): Promise<Record<string, LifecycleLogsType>> {\n const result: Record<string, LifecycleLogsType> = {};\n\n for (const variant of VariantService.get()) {\n if (!names || names.includes(variant.name)) result[variant.name] = await variant.check();\n }\n\n return result;\n }\n\n /**\n * Re-reads the TypeScript configuration from disk.\n *\n * @remarks\n * Reparses the configuration so a later check or build reads it as it now stands,\n * which is what a watch cycle needs after an edit to `tsconfig.json`.\n * The list of files reparsed is dropped rather than passed on, so a caller learns only that the reparse ran.\n * Nothing here waits on anything, so the promise settles at once.\n *\n * @example\n * ```ts\n * await build.reload(); // the TypeScript configuration is read again\n * ```\n *\n * @see TypescriptService.reload\n * @since 3.0.0\n */\n\n async reload(): Promise<void> {\n TypescriptService.reload();\n }\n\n /**\n * Constructs a variant for every entry the configuration declares.\n *\n * @param config - Configuration as it now stands\n * @throws xBuildError - When there is no configuration to read variants from\n *\n * @remarks\n * A name that already has a variant is passed over,\n * so re-reading a configuration adds what it gained\n * and leaves the variants it kept running rather than replacing them.\n * Nothing is removed here,\n * since a variant the configuration stopped declaring watches its own entry and disposes of itself.\n *\n * @see VariantService\n * @since 3.0.0\n */\n\n private parseVariants(config: ConfigurationInterface): void {\n if (!config)\n throw new xBuildError('Variants are not defined in the configuration');\n\n for (const name of Object.keys(config.variants ?? [])) {\n if (VariantService.has(name)) continue;\n new VariantService(name, this.events$, this.argv);\n }\n }\n\n /**\n * Shapes the result of a variant that was skipped rather than run and reports it as an end.\n *\n * @param name - Variant that was not built\n * @param dependencies - Names of the dependencies that failed, in the order the variant declared them\n * @returns A result carrying one error naming them, and nothing at any other level\n *\n * @remarks\n * Shaped as a build result rather than as a thrown error,\n * so a skipped variant reads like a failed one to whatever reports the run.\n * It carries no metafile, which is what makes its own dependents skip in turn,\n * since a dependency that produced no output is what the graph reads as a failure.\n * Nothing was compiled, so every bucket but `errors` comes back empty.\n * The result is built from the buckets the context carries rather than from a second literal,\n * so a level cannot be named in one and missing from the other,\n * and a reader of the event and a reader of the result are looking at the same messages.\n * The same result goes out on the event stream as an end,\n * since a variant that never ran reports no end of its own.\n * A reader would otherwise see the run finish, with one variant missing from the count.\n * The context is assembled here rather than taken from a build,\n * so its options are the ones the configuration states, and its duration is zero.\n *\n * @example\n * ```ts\n * const { errors } = this.skipped('app', [ 'types' ]);\n * errors[0].text; // 'Variant \"app\" was not built, because \"types\" failed'\n * ```\n *\n * @see BuildResultInterface\n * @since 3.0.0\n */\n\n private skipped(name: string, dependencies: Array<string>): BuildResultInterface {\n const failed = dependencies.map(dependency => `\"${ dependency }\"`).join(', ');\n const errors: Array<Message> = [\n {\n id: 'dependency-failed',\n text: `Variant \"${ name }\" was not built, because ${ failed } failed`,\n notes: [],\n detail: undefined,\n location: null,\n pluginName: name\n }\n ];\n\n const variant = this.config$.getValue().variants?.[name];\n const logs: LifecycleLogsType = { info: [], verbose: [], error: errors, warning: [] };\n const buildResult = <BuildResultInterface> <unknown> {\n info: logs.info, verbose: logs.verbose, errors: logs.error, warnings: logs.warning\n };\n\n this.events$.next({\n type: 'end',\n duration: 0,\n context: {\n argv: this.argv,\n logs,\n options: variant?.esbuild ?? {},\n overrides: variant?.logOverride ?? {},\n variantName: name,\n stage: {\n startTime: new Date(),\n dropped: new Set<string>(),\n reachableFiles: new Set<string>()\n }\n },\n buildResult\n });\n\n return buildResult;\n }\n\n /**\n * Returns the variants one variant waits for.\n *\n * @param name - Variant whose dependencies are wanted\n * @returns The names it depends on, empty when it depends on none\n *\n * @remarks\n * Read from the configuration as it stands rather than from a copy taken when the run began.\n * A single name is flattened into a list, so both forms `dependOn` accepts read the same way here.\n *\n * @see VariantConfigurationInterface\n * @since 3.0.0\n */\n\n private getDependOn(name: string): Array<string> {\n return [ this.config$.getValue().variants?.[name]?.dependOn ?? [] ].flat();\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xBuildBaseError } from '@errors/base.error';\n\n/**\n * A general framework error, resolved against its sources as it is constructed.\n *\n * @remarks\n * Throw this when the failure needs no error type of its own.\n * Extend {@link xBuildBaseError} instead when callers have to branch on the type,\n * or when the error has to carry extra fields.\n * Framework frames stay eligible for the code window by default, since a failure raised here is usually raised\n * inside the build itself and the snippet would otherwise be dropped.\n *\n * @example\n * ```ts\n * throw new xBuildError('tsconfig.json was not found');\n * // xBuildBaseError: tsconfig.json was not found\n * //\n * // Enhanced Stack Trace:\n * // at run src/bash.ts:41:11\n * ```\n *\n * @see xBuildBaseError\n * @see StackTraceInterface\n *\n * @since 1.0.0\n */\n\nexport class xBuildError extends xBuildBaseError {\n\n /**\n * Creates the error and resolves its stack right away.\n *\n * @param message - Message describing what went wrong\n * @param options - Frame selection and code window size, keeping framework frames by default\n *\n * @remarks\n * Resolution happens here rather than on first print, so the frames describe the throw site even when the error\n * travels before anything renders it.\n *\n * @example\n * ```ts\n * new xBuildError('entry point missing').metadata?.formatCode; // the highlighted throw site\n * new xBuildError('entry point missing', { linesBefore: 1, linesAfter: 1 }); // a tighter code window\n * ```\n *\n * @see StackTraceInterface\n * @see xBuildBaseError.reformatStack\n *\n * @since 1.0.0\n */\n\n constructor(message: string, options: StackTraceInterface = { withFrameworkFrames: true }) {\n super(message);\n this.reformatStack(this, options);\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { PartialMessage, Loader } from 'esbuild';\nimport type { OnResolveArgs, OnResolveResult } from 'esbuild';\nimport type { OnStartResult, OnLoadArgs, OnLoadResult } from 'esbuild';\nimport type { DiagnosticInterface } from '@typescript/typescript.module';\nimport type { Subject, UnsubscribeType } from '@remotex-labs/xobservable';\nimport type { BuildOptions, Plugin, PluginBuild, BuildResult } from 'esbuild';\nimport type { LifecycleContextInterface } from '@interfaces/lifecycle.interface';\nimport type { LogLevelType } from '@providers/interfaces/log-provider.interface';\nimport type { VariantConfigurationInterface } from '@interfaces/configuration.interface';\nimport type { BuildResultType } from '@services/interfaces/transpiler-service.interface';\nimport type { CallType, HandleType } from '@services/interfaces/variant-service.interface';\nimport type { LifecycleEventsType, BuildResultInterface } from '@interfaces/lifecycle.interface';\nimport type { LifecyclePluginInterface, LifecycleLogsType } from '@interfaces/lifecycle.interface';\nimport type { VariantSubscriptionInterface } from '@services/interfaces/variant-service.interface';\n\n/**\n * Imports\n */\n\nimport { parseSync } from 'oxc-parser';\nimport { relative } from '@remotex-labs/xmap';\nimport { inject } from '@remotex-labs/xinject';\nimport { FilesModel } from '@models/files.model';\nimport { xBuildError } from '@errors/xbuild.error';\nimport { collectLogs } from '@providers/log.provider';\nimport { Typescript } from '@typescript/typescript.module';\nimport { analyzeMacros } from '@directives/analyze.directive';\nimport { transformMacros } from '@directives/macros.directive';\nimport { resolveSource } from '@components/transformer.component';\nimport { deepMerge, stringify } from '@components/object.component';\nimport { ConfigurationService } from '@services/configuration.service';\nimport { extractEntryPoints } from '@components/entry-points.component';\nimport { TextBlocks, DiagnosticLevels } from '@constants/variant.constant';\nimport { errorToMessage, isEsbuildError } from '@providers/message.provider';\nimport { buildFiles, analyzeDependencies } from '@services/transpiler.service';\n\n/**\n * Runs one named variant of a build, from the configuration it watches to the result it reports.\n *\n * @remarks\n * One instance per entry in `variants`, kept in a static registry under that name and reused by every build,\n * so a watch cycle rebuilds through the same variant rather than replacing it each time.\n * The instance follows the configuration it was named in:\n * it re-reads its settings whenever they change and disposes of itself once the configuration drops its entry.\n * A build runs as a single esbuild plugin, which is what gives the configured hooks their place in the run.\n *\n * @example\n * ```ts\n * const variant = new VariantService('esm', events$, { watch: true });\n * const result = await variant.build();\n *\n * result.errors.length; // 0\n * variant.dispose();\n * ```\n *\n * @see LifecyclePluginInterface\n * @see VariantConfigurationInterface\n *\n * @since 3.0.0\n */\n\nexport class VariantService {\n /**\n * The file model every variant reads its sources through.\n *\n * @remarks\n * Held on the class rather than the instance, so one cache of snapshots serves every variant,\n * which is what keeps two variants of the same project from reading the same file twice.\n *\n * @since 3.0.0\n */\n\n private static readonly filesModel: FilesModel = inject(FilesModel);\n\n /**\n * The live variants, keyed by the name each was constructed under.\n *\n * @remarks\n * What {@link VariantService.has} and {@link VariantService.get} read,\n * and what {@link VariantService.dispose} removes an entry from,\n * so a name a disposed variant held is free for a later configuration to claim.\n *\n * @since 3.0.0\n */\n\n private static readonly instances = new Map<string, VariantService>();\n\n /**\n * The handle that ends this variant's configuration subscription.\n *\n * @remarks\n * Called as the variant is disposed,\n * so one the configuration has dropped stops reacting to a configuration it no longer belongs to.\n *\n * @since 3.0.0\n */\n\n private readonly configUnsubscribe: UnsubscribeType;\n\n /**\n * The hook sets these variant dispatches to, in the order they run.\n *\n * @remarks\n * Rebuilt on every configuration change as the declared plugins followed by the variant's own `lifecycle` set,\n * so a shared plugin runs ahead of the hooks a variant adds for itself.\n * The `lifecycle` set is given the variant's name, which is what lets its messages be credited as a plugin's.\n *\n * @since 3.0.0\n */\n\n private hooks: Array<LifecyclePluginInterface> = [];\n\n /**\n * Whether this variant has been torn down.\n *\n * @remarks\n * Guards {@link VariantService.build},\n * so a variant the configuration dropped reports rather than building against settings that are gone.\n *\n * @since 3.0.0\n */\n\n private isDisposed = false;\n\n /**\n * The TypeScript module this variant checks and emits through.\n *\n * @remarks\n * Replaced whenever the configuration changes, since a different `tsconfig` needs a program of its own,\n * and the one it replaces is disposed of only after the swap.\n * Populated by the subscription the constructor opens rather than by the constructor itself.\n *\n * @since 3.0.0\n */\n\n private typescriptModule!: Typescript;\n\n /**\n * The merged settings this variant builds under.\n *\n * @remarks\n * The common block with the variant merged over it, so a read here needs no further merging.\n * Populated by the subscription the constructor opens rather than by the constructor itself.\n *\n * @see VariantConfigurationInterface\n * @since 3.0.0\n */\n\n private buildConfig!: VariantConfigurationInterface;\n\n /**\n * Registers a variant under its name and starts following the configuration.\n *\n * @param name - Name the configuration declares this variant under, readable afterward\n * @param events$ - Subject the variant reports its start and end on\n * @param argv - Parsed command line the build was started with, empty when the caller passes none\n *\n * @remarks\n * The variant is usable as soon as it is constructed, since the subscription it opens delivers the settings\n * before the constructor returns.\n * An error in the subscription reports is rethrown rather than collected\n * because a variant that cannot read its configuration has nothing to build.\n *\n * @example\n * ```ts\n * const variant = new VariantService('esm', events$, { watch: true });\n * variant.name; // 'esm'\n * ```\n *\n * @since 3.0.0\n */\n\n constructor(readonly name: string, private events$: Subject<LifecycleEventsType>, private argv: Record<string, unknown> = {}) {\n VariantService.instances.set(name, this);\n this.configUnsubscribe = inject(ConfigurationService).select(config => ({\n common: config.common,\n variant: config.variants?.[this.name]\n })).subscribe(this.handleConfigChange.bind(this), error => {\n throw error;\n });\n }\n\n /**\n * Reports whether a variant is already registered under a name.\n *\n * @param name - Name to look for\n * @returns `true` when a live variant holds that name\n *\n * @remarks\n * What keeps a second variant from being constructed for a name that already has one,\n * so re-reading a configuration adds the entries it gained without disturbing the ones it kept.\n *\n * @example\n * ```ts\n * VariantService.has('esm'); // true\n * VariantService.has('umd'); // false - never constructed, or disposed since\n * ```\n *\n * @since 3.0.0\n */\n\n static has(name: string): boolean {\n return VariantService.instances.has(name);\n }\n\n /**\n * Returns every variant currently registered.\n *\n * @returns An iterator over the live variants, in the order they were constructed\n *\n * @remarks\n * Walks the registry itself rather than a copy of it,\n * so a variant that disposes of itself part way through a walk is not visited afterward.\n *\n * @example\n * ```ts\n * for (const variant of VariantService.get()) variant.name; // 'esm', then 'cjs'\n * ```\n *\n * @since 3.0.0\n */\n\n static get(): MapIterator<VariantService> {\n return VariantService.instances.values();\n }\n\n /**\n * Type-checks the variant's sources without building them.\n *\n * @returns The diagnostics as build messages, filed under the level each was reported at\n *\n * @remarks\n * A dependency scan of the variant's entry points settles which files the check covers,\n * so it reports against what this variant builds rather than against every file the project holds.\n * The scan runs with the plugins stripped, which keeps it out of the variant's own hooks.\n * The diagnostics come back as messages rather than in the compiler's own shape,\n * so the override table a build reads decides the level each one is filed under.\n * An error stays an error whatever `types.failOnError` says, since nothing is being emitted for it to stop.\n * Nothing is built here, so the messages belong to no result and a run wanting them on one build instead.\n *\n * @example\n * ```ts\n * const logs = await variant.check();\n * logs.error.length; // 2\n * logs.warning.length; // 0\n * ```\n *\n * @see LifecycleLogsType\n * @since 3.0.0\n */\n\n async check(): Promise<LifecycleLogsType> {\n const { metafile } = await analyzeDependencies({ ...this.buildConfig.esbuild, plugins: undefined });\n\n const logs: LifecycleLogsType = { info: [], verbose: [], error: [], warning: [] };\n this.diagnostics(this.typescriptModule.check(new Set(Object.keys(metafile.inputs))), logs);\n\n return logs;\n }\n\n /**\n * Runs one build of this variant.\n *\n * @returns The finished build, carrying every message the run reported at every level\n * @throws xBuildError - When the variant has already been disposed\n *\n * @remarks\n * esbuild runs at `silent` with no log limit, so every message reaches the result through the plugin\n * instead of the console, and nothing is dropped for being the hundredth of its kind.\n * A build that fails resolves to an empty esbuild result rather than rejecting,\n * since what went wrong is already in the logs the plugin collected.\n *\n * @example\n * ```ts\n * const result = await variant.build();\n * result.errors.length; // 0\n * result.warnings.length; // 2\n * ```\n *\n * @see BuildResultInterface\n * @since 3.0.0\n */\n\n async build(): Promise<BuildResultInterface> {\n if (this.isDisposed) throw new xBuildError(`Variant ${ this.name } is disposed`);\n\n const logs: LifecycleLogsType = { info: [], verbose: [], error: [], warning: [] };\n const result = await buildFiles({\n ...this.buildConfig.esbuild,\n plugins: [ this.lifecycle(logs) ],\n logLimit: 0,\n logLevel: 'silent'\n }).catch(() => <BuildResult> {});\n\n return this.toResult(result, logs);\n }\n\n /**\n * Tears the variant down and frees its name.\n *\n * @remarks\n * Ends the configuration subscription, disposes the TypeScript module, and drops the variant from the registry,\n * so the name is free for a later configuration to claim.\n * The instance stays marked as disposed, which is what makes a later build report rather than run.\n *\n * @example\n * ```ts\n * variant.dispose();\n * VariantService.has('esm'); // false\n * await variant.build(); // throws - the variant is disposed\n * ```\n *\n * @since 3.0.0\n */\n\n dispose(): void {\n this.isDisposed = true;\n this.configUnsubscribe?.();\n this.typescriptModule?.dispose?.();\n VariantService.instances.delete(this.name);\n }\n\n /**\n * Disposes the variant at the end of a `using` block.\n *\n * @remarks\n * Defers to {@link VariantService.dispose}, so a variant held by a `using` declaration is torn down\n * when the block ends rather than waiting for a caller to remember.\n *\n * @example\n * ```ts\n * using variant = new VariantService('esm', events$);\n * await variant.build(); // disposed as the block ends\n * ```\n *\n * @see VariantService.dispose\n * @since 3.0.0\n */\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n /**\n * Files a batch of messages under a level, credited to a plugin.\n *\n * @param logs - Buckets the messages are appended to\n * @param messages - Messages to file, absent where the stage produced none\n * @param level - Level a message takes when no override claims it\n * @param name - Plugin to credit the messages to, left as reported when omitted\n *\n * @remarks\n * An absent or empty batch is skipped, so nothing walks a list with nothing in it.\n * The variant's own override table is what decides each message's level,\n * which is how a configuration re-levels or silences one without the stage knowing.\n *\n * @since 3.0.0\n */\n\n private collect(logs: LifecycleLogsType, messages: Array<PartialMessage> | undefined, level: LogLevelType, name?: string): void {\n if (messages?.length) collectLogs(logs, this.buildConfig.logOverride!, messages, level, name);\n }\n\n /**\n * Records a thrown value as an error on the build.\n *\n * @param logs - Buckets the error is appended to\n * @param error - Value that was thrown, of any shape\n * @param name - Plugin to credit the error to, the variant itself by default\n *\n * @remarks\n * A value that is not an `Error` is wrapped in one first, so the message carries a text either way.\n * The error goes straight to the bucket rather than through the override table,\n * since a failure a stage could not handle is not something a configuration silences.\n *\n * @since 3.0.0\n */\n\n private fail(logs: LifecycleLogsType, error: unknown, name: string = this.name): void {\n logs.error.push(errorToMessage(error instanceof Error ? error : new Error(String(error)), '', name));\n }\n\n /**\n * Widens an esbuild result with the levels esbuild does not report on one.\n *\n * @param result - Result esbuild returned, empty when the build threw\n * @param logs - Messages the run collected, at every level\n * @returns The same result, carrying the quieter levels beside the two esbuild reports\n *\n * @remarks\n * Assigns onto the result rather than copying it, so the returned object is the one esbuild produced.\n * The error and warning buckets replace esbuild's own instead of joining them,\n * because the logs already hold those messages along with whatever the hooks added.\n *\n * @see BuildResultInterface\n * @since 3.0.0\n */\n\n private toResult(result: BuildResult, logs: LifecycleLogsType): BuildResultInterface {\n return Object.assign(<BuildResultType> result, {\n info: logs.info,\n errors: logs.error,\n verbose: logs.verbose,\n warnings: logs.warning\n }) as BuildResultInterface;\n }\n\n /**\n * Runs one call against every hook in order and collects what each reports.\n *\n * @typeParam T - Result the call produces for a hook that answers\n *\n * @param logs - Buckets each hook's messages are filed under\n * @param call - Invocation to run against a hook, returning its result or nothing\n * @param handle - Decides whether a result ends the walk, never ending it by default\n * @returns The result that ended the walk, or `undefined` when no result ended it\n *\n * @remarks\n * Each hook's errors and warnings are filed under that hook's own name,\n * so a message reads as the plugin that raised it rather than as the variant.\n * A hook that throws is recorded against its name, and the walk carries on,\n * which keeps one broken plugin from taking the rest of the stage with it.\n * A hook returning nothing is passed over without its result being inspected.\n *\n * @see LifecyclePluginInterface\n * @since 3.0.0\n */\n\n private async dispatch<T>(logs: LifecycleLogsType, call: CallType, handle: HandleType<T> = () => false): Promise<T | undefined> {\n for (const hook of this.hooks) {\n try {\n const result = <T & OnStartResult | undefined> await call(hook);\n if (!result) continue;\n\n this.collect(logs, result.errors, 'error', hook.name);\n this.collect(logs, result.warnings, 'warning', hook.name);\n if (handle(result)) return result;\n } catch (error) {\n this.fail(logs, error, hook.name);\n }\n }\n }\n\n /**\n * Emits the declaration files for this build.\n *\n * @param context - Context of the build being emitted for, read for its resolved options\n *\n * @remarks\n * Written to the directory `declaration` names, falling back to the build's own `outdir` when it names none.\n * A bundled build emits through `emitBundle` so each entry point becomes one declaration,\n * while an unbundled one emits file by file.\n *\n * @see DeclarationOptionsInterface\n * @since 3.0.0\n */\n\n private async declarations(context: LifecycleContextInterface): Promise<void> {\n const { declaration } = this.buildConfig;\n const entryPoints = <Record<string, string>> context.options.entryPoints;\n const outdir = (typeof declaration === 'object' ? declaration.outDir : undefined) ?? context.options.outdir;\n\n if (context.options.bundle) await this.typescriptModule.emitBundle(entryPoints, outdir);\n else await this.typescriptModule.emit(entryPoints, outdir);\n }\n\n /**\n * Re-reads the variant's settings whenever the configuration changes.\n *\n * @param change - The common block and this variant's entry, as the configuration now stands\n *\n * @remarks\n * A change carrying no entry for this variant means the configuration dropped it,\n * so the variant disposes of itself instead of rebuilding its settings.\n * The common block is merged under the variant, entry points are resolved,\n * and the TypeScript module is swapped before the one it replaces is disposed of,\n * so a failure part-way through does not leave the variant without a module.\n * The hook list is rebuilt with the declared plugins ahead of the variant's own `lifecycle` set.\n *\n * @see VariantSubscriptionInterface\n * @since 3.0.0\n */\n\n private handleConfigChange({ common, variant }: VariantSubscriptionInterface): void {\n if (!variant) return this.dispose();\n\n const previous = this.typescriptModule;\n const config = deepMerge(<VariantConfigurationInterface> {}, common ?? {}, variant);\n\n this.typescriptModule = inject(Typescript, config.esbuild.tsconfig);\n config.esbuild.entryPoints = extractEntryPoints(config.esbuild.entryPoints);\n config.logOverride ??= {};\n previous?.dispose();\n\n this.buildConfig = config;\n this.hooks = [ ...config.plugins ?? [], { name: this.name, ...config.lifecycle }];\n }\n\n /**\n * Writes one text block into the esbuild options.\n *\n * @param options - Options the block is written onto, modified in place\n * @param type - Block to write, one of `banner`, `footer`, or `define`\n *\n * @remarks\n * A value written as a function is called with the variant's name and the arguments the build was started with,\n * so an injected value can carry something the configuration file cannot know.\n * A value resolving to `null` or `undefined` is left out rather than written as text,\n * which is how a definition can decline to apply to a given variant.\n *\n * @see TextBlocks\n * @since 3.0.0\n */\n\n private injectTextBlock(options: BuildOptions, type: 'banner' | 'footer' | 'define'): void {\n const source = this.buildConfig[type];\n if (!source) return;\n\n const target = options[type] ??= {};\n for (const [ key, value ] of Object.entries(source)) {\n const content = typeof value === 'function' ? value(this.name, this.argv) : value;\n if (content !== undefined && content !== null) target[key] = stringify(content);\n }\n }\n\n /**\n * Files a batch of TypeScript diagnostics as messages.\n *\n * @param diagnostics - Diagnostics to file, as the TypeScript module reported them\n * @param logs - Buckets the messages are filed under\n * @param failOnError - Whether an error keeps its level, filed as a warning instead when `false`\n *\n * @remarks\n * Each diagnostic carries its code as `TS<code>`, so an override claims one by that id,\n * spelled the way the compiler itself spells it rather than in a shape of this package's own.\n * The code, category, and text also travel whole on the message's `detail`,\n * so a reporter reads the diagnostic itself rather than parsing it back out of the message text.\n * The level comes from the diagnostic's category, and a category the table does not reach is filed as `verbose`.\n * A build passes `types.failOnError` in, while a check leaves it alone,\n * since nothing is being emitted there for an error to stop.\n * Nothing here runs the check, so which files it covered is the caller's to decide.\n *\n * @see DiagnosticLevels\n * @see DiagnosticInterface\n * @see TypeCheckOptionsInterface\n *\n * @since 3.0.0\n */\n\n private diagnostics(diagnostics: Array<DiagnosticInterface>, logs: LifecycleLogsType, failOnError: boolean = true): void {\n for (const { category, code, message: text, file, line, column } of diagnostics) {\n const message: PartialMessage = { text };\n if (code !== undefined) message.id = `TS${ code }`;\n if (file) message.location = { file, line, column };\n\n const level = <LogLevelType> (DiagnosticLevels[category] ?? 'verbose');\n message.detail = { code, category, message: text };\n\n this.collect(logs, [ message ], level === 'error' && !failOnError ? 'warning' : level, 'typescript');\n }\n }\n\n /**\n * Runs the start stage of a build.\n *\n * @param context - Context shared by every hook of this build\n * @param esbuild - The esbuild module driving the build, handed to each start hook\n * @returns The errors collected so far, which is what fails the build when any were\n *\n * @remarks\n * The start hooks run first, and the sources are type-checked only where nothing has failed yet,\n * since diagnostics against a build that already broke report noise rather than a cause.\n * The check covers the files the setup stage recorded on the stage,\n * so a build reports against its own inputs without scanning for them a second time.\n * `types.failOnError` decides whether a type error fails the build or is filed as a warning beside it.\n * The error bucket comes back rather than the hooks' own results,\n * so esbuild stops on anything the stage collected, whichever hook raised it.\n *\n * @see StartContextInterface\n * @since 3.0.0\n */\n\n private async start(context: LifecycleContextInterface, esbuild: PluginBuild['esbuild']): Promise<OnStartResult> {\n const { logs } = context;\n await this.dispatch(logs, hook => hook.onStart?.({ context, esbuild }));\n if (this.buildConfig.types && logs.error.length < 1) {\n const types = this.buildConfig.types;\n const failOnError = typeof types === 'object' ? types.failOnError : true;\n this.diagnostics(this.typescriptModule.check(context.stage.reachableFiles), context.logs, failOnError);\n }\n\n return { errors: logs.error };\n }\n\n /**\n * Resolves one import through the hooks.\n *\n * @param context - Context shared by every hook of this build\n * @param args - The import being resolved, as esbuild described it\n * @returns The first result a hook returned, or the errors collected so far when none claimed the path\n *\n * @remarks\n * The first hook to return anything settles the path, and the rest are not consulted,\n * which is how esbuild itself behaves across plugins.\n * Where no hook claims the import, esbuild is left to resolve it.\n *\n * @see ResolveContextInterface\n * @since 3.0.0\n */\n\n private async resolve(context: LifecycleContextInterface, args: OnResolveArgs): Promise<OnResolveResult | undefined | null> {\n const result = await this.dispatch<OnResolveResult>(\n context.logs, hook => hook.onResolve?.({ context, args }), () => true\n );\n\n return result ?? { errors: context.logs.error };\n }\n\n /**\n * Loads one file and runs it through the hooks.\n *\n * @param context - Context shared by every hook of this build\n * @param args - The file esbuild is loading, as it described it\n * @returns The contents and loader the chain settled on, with the messages left to the variant's own logs\n *\n * @remarks\n * The file is read from the shared model, then rewritten so its imports resolve where the build is unbundled,\n * and its macros are transformed either way.\n * A failure in any of that is recorded, and the file still goes on to the hooks.\n * Each hook is handed what the one before it returned, so the list reads as a chain rather than a race,\n * and every hook is consulted rather than the first that answers.\n * The result carries no messages of its own, since the stage filed them under the variant's levels already.\n *\n * @see LoadContextInterface\n * @since 3.0.0\n */\n\n private async load(context: LifecycleContextInterface, args: OnLoadArgs): Promise<OnLoadResult | undefined | null> {\n const path = VariantService.filesModel.resolve(args.path);\n\n let loader: Loader = 'default';\n let contents = VariantService.filesModel.touch(path).snapshot?.text ?? '';\n\n try {\n const parsed = parseSync(path, contents, { sourceType: 'module' });\n contents = await transformMacros(parsed, path, contents, context);\n\n if (!context.options.bundle) {\n const parsed = parseSync(path, contents, { sourceType: 'module' });\n contents = resolveSource(parsed, path, contents, this.typescriptModule);\n }\n } catch (error) {\n this.fail(context.logs, error);\n }\n\n let merged: OnLoadResult = {};\n await this.dispatch<OnLoadResult>(context.logs,\n hook => hook.onLoad?.({ context, contents, loader, args }),\n result => {\n merged = { ...merged, ...result };\n loader = result.loader ?? loader;\n\n if (result.contents !== undefined)\n contents = typeof result.contents === 'string' ? result.contents : Buffer.from(result.contents).toString();\n\n return false;\n }\n );\n\n return { ...merged, contents, loader, errors: [], warnings: [] };\n }\n\n /**\n * Closes a build out and reports it.\n *\n * @param context - Context shared by every hook of this build\n * @param buildResult - The result esbuild produced for the run\n *\n * @remarks\n * Only the messages esbuild raised itself are collected here,\n * since one carrying a plugin name was already filed when its hook returned it.\n * Declarations are emitted only where nothing failed, so a broken build does not leave stale types behind.\n * `onSuccess` runs ahead of `onEnd` and only on a result with no errors,\n * after which the end event is reported whatever the outcome.\n *\n * @see EndContextInterface\n * @since 3.0.0\n */\n\n private async end(context: LifecycleContextInterface, buildResult: BuildResult): Promise<void> {\n this.collect(context.logs, buildResult.errors.filter(message => !message.pluginName), 'error');\n this.collect(context.logs, buildResult.warnings.filter(message => !message.pluginName), 'warning');\n\n const event = {\n context,\n duration: Date.now() - context.stage.startTime.getTime(),\n buildResult: this.toResult(buildResult, context.logs)\n };\n\n if (context.logs.error.length < 1) {\n try {\n if (this.buildConfig.declaration) await this.declarations(context);\n } catch (error) {\n errorToMessage(error as Error, '', this.name);\n }\n }\n\n await this.dispatch(context.logs, async hook => {\n if (event.buildResult.errors.length < 1) await hook.onSuccess?.(event);\n await hook.onEnd?.(event);\n });\n\n this.events$.next({ ...event, type: 'end' });\n }\n\n /**\n * Prepares the build's options before esbuild reads them.\n *\n * @param context - Context shared by every hook of this build\n * @param build - The esbuild plugin build whose initial options are being shaped\n *\n * @remarks\n * Injects the text blocks, records the files the build reaches on the stage,\n * and replaces the entry points with the dependency map where the build is unbundled.\n * The macro scan reads that same set,\n * so the bindings the run is to drop come from every input the build reaches rather than from the entry points.\n * A failure anywhere in that is recorded against the variant rather than thrown,\n * so a scan that cannot run reports itself and leaves the build to fail on the errors it filed.\n * The setup hooks run last, so a plugin changing an option overrides what this stage settled.\n *\n * @see analyzeMacros\n * @since 3.0.0\n */\n\n private async setup(context: LifecycleContextInterface, build: PluginBuild): Promise<void> {\n const options = build.initialOptions;\n\n try {\n for (const block of TextBlocks) this.injectTextBlock(options, block);\n\n const files = await this.buildDependencyMap();\n context.stage.reachableFiles = new Set(Object.values(files));\n if (!options.bundle) options.entryPoints = files;\n context.stage.dropped = analyzeMacros(context.stage.reachableFiles, options.define ?? {});\n } catch (error) {\n if(isEsbuildError(error) && error.errors) {\n context.logs.error.push(...error.errors);\n } else {\n this.fail(context.logs, error, '');\n }\n }\n\n await this.dispatch(context.logs, hook => hook.onSetup?.(context));\n }\n\n /**\n * Maps every input the build reaches to the output name it takes.\n *\n * @returns The inputs, keyed by their path below the root directory with the extension dropped\n *\n * @remarks\n * The scan runs with the plugins stripped, so it does not re-enter this variant's own hooks\n * and cannot recurse into the build it is preparing.\n * Each path is made relative to the root directory and loses its extension,\n * which is what gives an unbundled build one output per input rather than one bundle.\n *\n * @since 3.0.0\n */\n\n private async buildDependencyMap(): Promise<Record<string, string>> {\n const rootDir = this.typescriptModule.config.options.rootDir!;\n const { metafile } = await analyzeDependencies({ ...this.buildConfig.esbuild, plugins: undefined });\n\n return Object.fromEntries(Object.keys(metafile.inputs).map(file => {\n const path = relative(rootDir, VariantService.filesModel.resolve(file));\n const dot = path.lastIndexOf('.');\n\n return [ dot > 0 ? path.slice(0, dot) : path, file ];\n }));\n }\n\n /**\n * Builds the esbuild plugin this variant runs as.\n *\n * @param logs - Buckets every stage of the run files its messages under\n * @returns The plugin, named after the variant\n *\n * @remarks\n * The context is created once per build and handed to every stage,\n * which is what makes `stage` a place one hook leaves a value for a later one.\n * Its two sets start empty, and setup fills them before the first hook reads one.\n * The four esbuild callbacks are registered before setup runs,\n * so a hook changing an option during setup is still ahead of the first file being read.\n * The plugin carries the variant's name, so message esbuild attributes to it read as the variant.\n *\n * @see LifecycleContextInterface\n * @since 3.0.0\n */\n\n private lifecycle(logs: LifecycleLogsType): Plugin {\n return {\n name: this.name,\n setup: async (build: PluginBuild): Promise<void> => {\n const context: LifecycleContextInterface = {\n logs,\n argv: this.argv,\n options: build.initialOptions,\n overrides: this.buildConfig.logOverride!,\n variantName: this.name,\n stage: {\n startTime: new Date(),\n dropped: new Set<string>(),\n reachableFiles: new Set<string>()\n }\n };\n\n build.onEnd(this.end.bind(this, context));\n build.onStart(this.start.bind(this, context, build.esbuild));\n build.onLoad({ filter: /.*/ }, this.load.bind(this, context));\n build.onResolve({ filter: /.*/ }, this.resolve.bind(this, context));\n await this.setup(context, build);\n\n this.events$.next({ context, esbuild: build.esbuild, type: 'start' });\n }\n };\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Message, PartialMessage } from 'esbuild';\nimport type { LifecycleLogsType } from '@interfaces/lifecycle.interface';\nimport type { LogLevelType, LogOverridesType } from '@providers/interfaces/log-provider.interface';\n\n/**\n * Resolves the level a message is reported under.\n *\n * @param overrides - The configured levels, keyed by message id or by a pattern matching one\n * @param id - ID the message was reported with, absent on a message that carries none\n * @param level - Level the message takes when no override claims it\n * @returns The level the message is reported under\n *\n * @remarks\n * An id is looked up as a key first and read against the pattern keys only when that misses,\n * so a table naming its ids outright is answered without a match being run at all.\n * A pattern is anchored with `^(?:...)$` to make it match a whole id rather than a part of one,\n * which is what lets a set of ids be written as a single alternation, and the first the table declared wins.\n * A key whose syntax does not parse is passed over rather than thrown on.\n *\n * @example\n * ```ts\n * const overrides: LogOverridesType = { 'direct-eval': 'silent', 'TS-2\\\\d{3}': 'warning' };\n *\n * resolveLevel(overrides, 'direct-eval', 'warning'); // 'silent' - claimed by name\n * resolveLevel(overrides, 'TS-2304', 'error'); // 'warning' - claimed by pattern\n * resolveLevel(overrides, 'empty-glob', 'warning'); // 'warning' - claimed by neither\n * ```\n *\n * @see collectLog\n * @see LogOverridesType\n *\n * @since 3.0.0\n */\n\nexport function resolveLevel(overrides: LogOverridesType, id: string | undefined, level: LogLevelType): LogLevelType {\n if (id === undefined) return level;\n if (Object.hasOwn(overrides, id)) return overrides[id];\n\n for (const key in overrides) {\n try {\n if (new RegExp(`^(?:${ key })$`).test(id)) return overrides[key];\n } catch {\n if(id === key) return overrides[key];\n }\n }\n\n return level;\n}\n\n/**\n * Files a message under the level it resolves to.\n *\n * @param logs - Buckets the message is appended to, keyed by level\n * @param overrides - The configured levels, consulted for the message id\n * @param message - Message to file\n * @param level - Level the message takes when no override claims it\n *\n * @remarks\n * A message that resolves to `silent` is dropped rather than filed,\n * which is what keeps the log record free of a bucket for it.\n *\n * @example\n * ```ts\n * const logs = { debug: [], info: [], warning: [], error: [] };\n *\n * collectLog(logs, { 'direct-eval': 'silent' }, { id: 'direct-eval', text: 'Using eval' }, 'warning');\n * logs.warning; // [] - the override silenced it\n * ```\n *\n * @see collectLogs\n * @see resolveLevel\n *\n * @since 3.0.0\n */\n\nexport function collectLog(\n logs: LifecycleLogsType, overrides: LogOverridesType, message: PartialMessage, level: LogLevelType\n): void {\n const resolved = resolveLevel(overrides, message.id, level);\n if (resolved !== 'silent') logs[resolved].push(<Message> message);\n}\n\n/**\n * Files a batch of messages, each under the level it resolves to.\n *\n * @param logs - Buckets the messages are appended to, keyed by level\n * @param overrides - The configured levels, consulted for each message id\n * @param messages - Messages to file, in the order they were reported\n * @param level - Level a message takes when no override claims it\n * @param name - Plugin to credit each message to, left as reported when omitted or empty\n *\n * @remarks\n * Every message is resolved on its own, so one batch can end up spread across several buckets.\n * A name replaces whatever `pluginName` a message already carried,\n * so a batch coming out of one plugin reads as that plugin's even where esbuild credited another.\n * It writes onto the messages themselves rather than onto copies,\n * so a caller holding the same objects sees the credit as well.\n * The credit lands before the level resolves, so a message an override silences still carries it.\n *\n * @example\n * ```ts\n * const logs = { debug: [], info: [], warning: [], error: [] };\n *\n * collectLogs(logs, {}, [ { text: 'first' } ], 'error');\n * logs.error; // [ { text: 'first' } ] - left uncredited\n *\n * collectLogs(logs, {}, [ { text: 'second' } ], 'error', 'timing');\n * logs.error; // [ { text: 'first' }, { text: 'second', pluginName: 'timing' } ]\n * ```\n *\n * @see collectLog\n * @since 3.0.0\n */\n\nexport function collectLogs(\n logs: LifecycleLogsType, overrides: LogOverridesType, messages: Array<PartialMessage>, level: LogLevelType, name?: string\n): void {\n for (const message of messages) {\n if(name) message.pluginName = name;\n collectLog(logs, overrides, message, level);\n }\n}\n","/**\n * Imports\n */\n\nimport { parseSync } from 'oxc-parser';\nimport { inject } from '@remotex-labs/xinject';\nimport { FilesModel } from '@models/files.model';\nimport { isDefined } from '@directives/define.directive';\nimport { Macros, MacroScanHint } from '@constants/macros.constant';\n\n/**\n * Collects the names of the macro declarations a build is to drop.\n *\n * @param files - Paths to scan, relative or absolute\n * @param defines - The definition table the build substitutes, holding the source text each flag stands for\n * @returns The names bound to a conditional macro whose condition does not hold\n *\n * @remarks\n * Each file is read through {@link FilesModel}, so a path already tracked is served from the cache rather than\n * from the disk, and a path that is missing is skipped.\n * A file is parsed only once it contains {@link MacroScanHint}, which spares the parse where no conditional\n * macro can be.\n *\n * - **What is looked at** - an exported top-level binding alone, `export const NAME = $$ifdef('FLAG')` or its\n * `$$ifndef` counterpart. A macro nested in a block, or bound without an export, is not seen.\n * - **What counts as defined** - a definition holds source text rather than a value, so the text is what decides.\n * Anything in {@link MacroFalsyDefines} leaves the flag unset, as does a flag that the table does not name.\n * Every other text sets the flag, `'0'` and the empty string among them.\n * - **What ends up in the set** - an `$$ifdef` name whose flag is absent, and an `$$ifndef` name whose flag is\n * present. {@link Macros.inline} is not read here.\n *\n * @example\n * ```ts\n * // src/feature.ts\n * export const $$dev = $$ifdef('DEV');\n * export const $$release = $$ifndef('DEV');\n *\n * analyzeMacros([ 'src/feature.ts' ], { DEV: 'true' }); // Set { '$$release' }\n * analyzeMacros([ 'src/feature.ts' ], { DEV: 'false' }); // Set { '$$dev' }\n * ```\n *\n * @see Macros\n * @see isDefined\n * @see MacroScanHint\n *\n * @since 3.0.0\n */\n\nexport function analyzeMacros(files: Iterable<string>, defines: Record<string, string>): Set<string> {\n const dropped = new Set<string>();\n const filesModel = inject(FilesModel);\n\n for (const file of files) {\n const content = filesModel.touch(file).snapshot?.text;\n\n if (!content?.includes(MacroScanHint)) continue;\n const { program } = parseSync(file, content, { sourceType: 'module' });\n\n for (const node of program.body) {\n if (node.type !== 'ExportNamedDeclaration') continue;\n if (node.declaration?.type !== 'VariableDeclaration') continue;\n\n for (const declarator of node.declaration.declarations) {\n const call = declarator.init;\n if (call?.type !== 'CallExpression' || call.callee.type !== 'Identifier') continue;\n\n const directive = call.callee.name;\n if (directive !== Macros.ifdef && directive !== Macros.ifndef) continue;\n\n const arg = call.arguments[0];\n if (arg?.type !== 'Literal' || typeof arg.value !== 'string') continue;\n if (declarator.id.type !== 'Identifier') continue;\n\n if ((directive === Macros.ifdef) !== isDefined(defines, arg.value)) {\n dropped.add(declarator.id.name);\n }\n }\n }\n }\n\n return dropped;\n}\n","/**\n * The prefix every macro name is expected to open with.\n *\n * @remarks\n * Keeps a macro apart from an ordinary binding and doubles as the cheapest test that a source holds one at all,\n * since a file without it carries nothing to expand.\n * A declared macro named without it still expands and draws a `macro-prefix` warning.\n *\n * @example\n * ```ts\n * '$$ifdef'.startsWith(MacroPrefix); // true\n * ```\n *\n * @see Macros\n * @see MacroScanHint\n *\n * @since 3.0.0\n */\n\nexport const MacroPrefix = '$$';\n\n/**\n * The prefix the two conditional macros share.\n *\n * @remarks\n * What `$$ifdef` and `$$ifndef` both open with, so a source without it declares neither of them,\n * and the walk looking for one is skipped.\n * {@link Macros.inline} does not carry it and is reached through {@link MacroPrefix} instead.\n *\n * @example\n * ```ts\n * MacroScanHint; // '$$if'\n * 'const $$dev = $$ifdef(\"DEV\", 1);'.includes(MacroScanHint); // true\n * ```\n *\n * @see Macros\n * @see MacroPrefix\n *\n * @since 3.0.0\n */\n\nexport const MacroScanHint = `${ MacroPrefix }if`;\n\n/**\n * The three names that mark a call as a macro.\n *\n * @remarks\n * The callee of the call names the macro, and the shape of the call has to match the name:\n * the two conditional macros take a flag as a string literal and the value that flag guards,\n * while `inline` takes the value alone.\n * A call that matches neither shape is left as it stands rather than reported.\n *\n * @example\n * ```ts\n * export const $$dev = $$ifdef('DEV', () => console.log('dev')); // kept while DEV is set\n * export const $$prod = $$ifndef('DEV', () => 0); // kept while DEV is not set\n * export const $$stamp = $$inline(() => 2 + 2); // becomes 4 in the output\n * ```\n *\n * @see MacroPrefix\n * @see transformMacros\n *\n * @since 3.0.0\n */\n\nexport const enum Macros {\n /**\n * Keeps its value while the flag is set.\n *\n * @remarks\n * The flag is read from the definition table, and the declaration is dropped when the flag is not set,\n * along with every reference to the name that it bound.\n *\n * @example\n * ```ts\n * export const $$dev = $$ifdef('DEV', () => log()); // dropped while DEV is 'false'\n * ```\n *\n * @since 3.0.0\n */\n\n ifdef = `${ MacroPrefix }ifdef`,\n\n /**\n * Keeps its value while the flag is not set.\n *\n * @remarks\n * The counterpart of `ifdef`, reading the same definitions and dropped on the opposite answer,\n * which is what a fallback for an absent flag is written as.\n *\n * @example\n * ```ts\n * export const $$prod = $$ifndef('DEV', () => 0); // dropped while DEV is set\n * ```\n *\n * @since 3.0.0\n */\n\n ifndef = `${ MacroPrefix }ifndef`,\n\n /**\n * Replaces the call with what its value evaluates to.\n *\n * @remarks\n * Evaluated while the build runs, so the output carries the result rather than the call.\n * A failure is reported as a `macro-inline` error and leaves `undefined` behind.\n *\n * @example\n * ```ts\n * export const $$stamp = $$inline(() => 2 + 2); // export const $$stamp = 4;\n * ```\n *\n * @since 3.0.0\n */\n\n inline = `${ MacroPrefix }inline`\n}\n\n/**\n * The definition values that leave a flag unset.\n *\n * @remarks\n * A definition holds source text rather than a value, so `false` reaches the build as the string `'false'`.\n * These three leave the flag unset, and every other text sets it, `'0'` and the empty string among them.\n * A flag that the definition table does not name is not set either, which {@link isDefined} tests on its own.\n * The text is trimmed before the lookup.\n *\n * @example\n * ```ts\n * MacroFalsyDefines.has('false'); // true\n * MacroFalsyDefines.has('0'); // false - '0' sets the flag\n * ```\n *\n * @see Macros\n * @see isDefined\n *\n * @since 3.0.0\n */\n\nexport const MacroFalsyDefines = new Set([ 'false', 'null', 'undefined' ]);\n\n/**\n * The parent properties under which an identifier names something rather than reads it.\n *\n * @remarks\n * A dropped macro's identifier becomes `undefined` wherever it is read, and is left alone where it is only a name -\n * the `id` of a declaration, a label, an import or export binding, or a parameter.\n * An object key and a member property are decided by the parent's `computed` flag instead of by this set.\n *\n * @example\n * ```ts\n * MacroNameKeys.has('id'); // true - `const $$dev = ...` keeps the name it declares\n * MacroNameKeys.has('object'); // false - `$$dev.run()` has the reference replaced\n * ```\n *\n * @see transformMacros\n * @since 3.0.0\n */\n\nexport const MacroNameKeys = new Set([ 'id', 'label', 'local', 'params', 'exported', 'imported' ]);\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { MacroTargetInterface } from '@directives/interfaces/macros-directive.interface';\n\n/**\n * Imports\n */\n\nimport { MacroFalsyDefines } from '@constants/macros.constant';\n\n/**\n * Whether the definition table sets a flag.\n *\n * @param defines - The definition table the build substitutes, holding the source text each flag stands for\n * @param name - Name of the flag to test\n * @returns `true` when the table names the flag and holds something other than a falsy text for it\n *\n * @remarks\n * A definition holds source text rather than a value, so the text is what decides.\n * A flag that the table does not name is not set, and neither is one whose text is in {@link MacroFalsyDefines}.\n * The text is trimmed before the lookup, so padding around it does not change the answer.\n * Every other text sets the flag, `'0'` and the empty string among them.\n *\n * @example\n * ```ts\n * isDefined({ DEV: 'true' }, 'DEV'); // true\n * isDefined({ DEV: ' false ' }, 'DEV'); // false - trimmed before the lookup\n * isDefined({}, 'DEV'); // false - the table does not name it\n * ```\n *\n * @see MacroFalsyDefines\n * @since 3.0.0\n */\n\nexport function isDefined(defines: Record<string, string>, name: string): boolean {\n const value = defines[name];\n\n return value !== undefined && !MacroFalsyDefines.has(value.trim());\n}\n\n/**\n * Builds the replacement source for a declaration that a macro initializes.\n *\n * @param code - Source text the target's spans point into\n * @param name - Name the declaration binds\n * @param target - The macro call and whatever call text followed it\n * @param prefix - Text placed in front of the result, `'export '` for an exported declaration\n * @returns The source that replaces the whole declaration\n *\n * @remarks\n * The value the macro guards is its second argument, and the way that argument is written decides the form:\n *\n * - **A function the source already invokes** - parenthesized and left invoked, so the binding holds the result.\n * - **A function the source does not invoke** - rewritten as a function declaration under the same name, carrying\n * its parameters, its return type, and its `async` keyword. An expression body becomes a `return` statement, and\n * a function without a body becomes an empty one.\n * - **Anything else** - substituted as written, with the trailing call kept.\n *\n * @example\n * ```ts\n * // source: export const $$log = $$ifdef('DEV', (m: string) => console.log(m));\n * defineDeclaration(code, '$$log', target, 'export ');\n * // result: export function $$log(m: string) { return console.log(m); }\n *\n * // source: const $$now = $$ifdef('DEV', () => Date.now())();\n * defineDeclaration(code, '$$now', target, '');\n * // result: const $$now = (() => Date.now())();\n * ```\n *\n * @see defineExpression\n * @see MacroTargetInterface\n *\n * @since 3.0.0\n */\n\nexport function defineDeclaration(code: string, name: string, target: MacroTargetInterface, prefix: string): string {\n const { call, suffix } = target;\n const callback = call.arguments[1];\n const text = code.slice(callback.start, callback.end);\n\n if (callback.type !== 'ArrowFunctionExpression' && callback.type !== 'FunctionExpression')\n return `${ prefix }const ${ name } = ${ text }${ suffix };`;\n\n if (suffix) return `${ prefix }const ${ name } = (${ text })${ suffix };`;\n\n const { body } = callback;\n const params = callback.params.map(param => code.slice(param.start, param.end)).join(', ');\n const returns = callback.returnType ? code.slice(callback.returnType.start, callback.returnType.end) : '';\n const head = `${ prefix }${ callback.async ? 'async ' : '' }function ${ name }(${ params })${ returns }`;\n\n if (!body) return `${ head } {}`;\n if (body.type === 'BlockStatement') return `${ head } ${ code.slice(body.start, body.end) }`;\n\n return `${ head } { return ${ code.slice(body.start, body.end) }; }`;\n}\n\n/**\n * Builds the replacement source for a macro standing in an expression.\n *\n * @param code - Source text the target's spans point into\n * @param target - The macro call and whatever call text followed it\n * @param statement - Whether the macro stands as a statement of its own\n * @returns The source that replaces the macro call\n *\n * @remarks\n * The value the macro guards is its second argument, and the way that argument is written decides the form:\n *\n * - **A function inside an expression** - parenthesized and invoked, so the expression evaluates to what the\n * function returns. The call the source wrote is used where there is one, and `()` where there is not.\n * - **A function standing as a statement** - its body is inlined where the call stood, with no wrapper around it.\n * An expression body becomes that expression, and a function without a body leaves nothing behind.\n * - **Anything else** - substituted as written, with the trailing call kept.\n *\n * @example\n * ```ts\n * // source: $$ifdef('DEV', () => console.log('on'));\n * defineExpression(code, target, true);\n * // result: console.log('on');\n *\n * // source: const x = $$ifdef('DEV', () => 1);\n * defineExpression(code, target, false);\n * // result: (() => 1)()\n * ```\n *\n * @see defineDeclaration\n * @since 3.0.0\n */\n\nexport function defineExpression(code: string, target: MacroTargetInterface, statement: boolean): string {\n const { call, suffix } = target;\n const callback = call.arguments[1];\n const text = code.slice(callback.start, callback.end);\n const tail = statement ? ';' : '';\n\n if (callback.type !== 'ArrowFunctionExpression' && callback.type !== 'FunctionExpression')\n return `${ text }${ suffix }${ tail }`;\n\n if (suffix || !statement) return `(${ text })${ suffix || '()' }${ tail }`;\n\n const { body } = callback;\n if (!body) return '';\n if (body.type !== 'BlockStatement') return `${ code.slice(body.start, body.end) };`;\n\n return code.slice(body.start + 1, body.end - 1).trim();\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { PartialMessage } from 'esbuild';\nimport type { ParseResult } from 'oxc-parser';\nimport type { LifecycleContextInterface } from '@interfaces/lifecycle.interface';\nimport type { LogLevelType } from '@providers/interfaces/log-provider.interface';\nimport type { NodeVisitorType } from '@directives/interfaces/macros-directive.interface';\nimport type { ExportNamedDeclaration, ImportDeclaration, Node, Span } from '@oxc-project/types';\nimport type { SourceEditInterface } from '@components/interfaces/transformer-component.interface';\nimport type { DeclaredMacroType, MacroCallType } from '@directives/interfaces/macros-directive.interface';\nimport type { MacroStateInterface, MacroTargetInterface } from '@directives/interfaces/macros-directive.interface';\n\n/**\n * Imports\n */\n\nimport { visitorKeys } from 'oxc-parser';\nimport { collectLog } from '@providers/log.provider';\nimport { evaluate } from '@directives/inline.directive';\nimport { applyEdits } from '@components/transformer.component';\nimport { defineDeclaration, defineExpression, isDefined } from '@directives/define.directive';\nimport { MacroNameKeys, MacroPrefix, Macros, MacroScanHint } from '@constants/macros.constant';\n\n/**\n * Whether a value read out of a node is itself a node.\n *\n * @param value - Value read out of a parent node's property\n * @returns `true` when the value is an object carrying a string `type`\n *\n * @remarks\n * The test the walk applies before it steps into a property,\n * since a visitor key can hold a node, an array of them, or a plain value such as a name or a flag.\n *\n * @since 3.0.0\n */\n\nexport function isNode(value: unknown): value is Node {\n return typeof value === 'object' && value !== null && typeof (<Node> value).type === 'string';\n}\n\n/**\n * Visits a node and everything under it, depth-first.\n *\n * @param node - Node the walk starts from\n * @param visit - Called for each node, returning `true` to leave the subtree unvisited\n * @param parent - Node the current one hangs from, `null` at the root\n * @param key - Property of the parent the current node sits under, empty at the root\n *\n * @remarks\n * Child properties come from oxc's `visitorKeys`, so a node type that the table does not name is treated as a leaf.\n * A visitor returning `true` prunes the subtree,\n * so a rule further down never rewrites a node that an earlier one already replaced.\n *\n * @see NodeVisitorType\n * @since 3.0.0\n */\n\nexport function walk(node: Node, visit: NodeVisitorType, parent: Node | null = null, key = ''): void {\n if (visit(node, parent, key)) return;\n\n const keys: Array<string> | undefined = visitorKeys[node.type];\n\n for (const childKey of keys ?? []) {\n const value = (<Record<string, unknown>> <unknown> node)[childKey];\n\n if (Array.isArray(value)) {\n for (const item of value) if (isNode(item)) walk(item, visit, node, childKey);\n } else if (isNode(value)) walk(value, visit, node, childKey);\n }\n}\n\n/**\n * Files a message against a position in the file being transformed.\n *\n * @param state - Transform state, read for the source text and the file name\n * @param offset - Offset in the source the message points at\n * @param level - Level the message is filed under, before any override applies\n * @param message - Message to file, whose `location` this fills in\n *\n * @remarks\n * The line and the column are counted by scanning the source up to the offset,\n * since the parser reports spans rather than positions.\n * The message is filled in where it stands rather than copied, and it reaches the log through {@link collectLog},\n * so the overrides the build declared still decide the level it lands at.\n *\n * @see collectLog\n * @since 3.0.0\n */\n\nexport function report(state: MacroStateInterface, offset: number, level: LogLevelType, message: PartialMessage): void {\n const { code } = state;\n let line = 1;\n let start = 0;\n\n for (let index = code.indexOf('\\n'); index !== -1 && index < offset; index = code.indexOf('\\n', index + 1)) {\n line++;\n start = index + 1;\n }\n\n message.location = { file: state.target, line, column: offset - start };\n collectLog(state.logs, state.overrides, message, level);\n}\n\n/**\n * Queues an edit that replaces a span with text.\n *\n * @param state - Transform state the edit is collected on\n * @param span - Span of the source the edit replaces\n * @param text - Replacement text, empty to delete the span\n * @returns `true`, so a caller can hand it straight back to the walk\n *\n * @remarks\n * Returning `true` is what tells the walk that this node is dealt with and that it should not descend into it.\n * The edit is applied later along with the rest, so the offsets it carries stay valid for the whole walk.\n *\n * @see applyEdits\n * @since 3.0.0\n */\n\nexport function record(state: MacroStateInterface, span: Span, text: string): boolean {\n state.edits.push({ start: span.start, end: span.end, text });\n\n return true;\n}\n\n/**\n * Queues an edit whose text is known only once an inline call has run.\n *\n * @param state - Transform state the edit and the promise are collected on\n * @param span - Span of the source the edit replaces\n * @param call - The `$$inline` call to evaluate\n * @param wrap - Turns the value that comes back into the text that replaces the span\n * @returns `true`, so a caller can hand it straight back to the walk\n *\n * @remarks\n * The edit is queued empty and filled in when the call finishes, so the walk carries on while it runs.\n * The promise is collected on `state.pending` for the caller to await before the edits are applied.\n * A failure fills the edit with `wrap('undefined')` and reports a `macro-inline` error,\n * so a macro that cannot be evaluated still leaves the file parsable.\n *\n * @see evaluate\n * @since 3.0.0\n */\n\nexport function defer(state: MacroStateInterface, span: Span, call: MacroCallType, wrap: (value: string) => string): boolean {\n const edit: SourceEditInterface = { start: span.start, end: span.end, text: '' };\n\n state.edits.push(edit);\n state.pending.push(evaluate(state, call).then(value => {\n edit.text = wrap(value);\n }, (error: unknown) => {\n edit.text = wrap('undefined');\n report(state, call.start, 'error', {\n detail: error,\n id: 'macro-inline',\n text: `${ Macros.inline } failed: ${ (<Error> error)?.message ?? String(error) }`\n });\n }));\n\n return true;\n}\n\n/**\n * Whether a node is a macro call this transform handles.\n *\n * @param value - Node to test\n * @returns `true` when the callee names a macro and the arguments match that name\n *\n * @remarks\n * The callee has to be a plain identifier naming one of {@link Macros}, and the arguments have to match the name:\n * one for `inline`, and two for the conditional pair, the first of which is a string literal naming the flag.\n * Anything else is an ordinary call and is left alone.\n *\n * @see MacroCallType\n * @since 3.0.0\n */\n\nexport function isMacroCall(value: Node): value is MacroCallType {\n if (value.type !== 'CallExpression' || value.callee.type !== 'Identifier') return false;\n\n const { name } = value.callee;\n if (name === Macros.inline) return value.arguments.length === 1;\n if (name !== Macros.ifdef && name !== Macros.ifndef || value.arguments.length !== 2) return false;\n\n const flag = value.arguments[0];\n\n return flag.type === 'Literal' && typeof flag.value === 'string';\n}\n\n/**\n * Whether a conditional macro keeps its value.\n *\n * @param state - Transform state, read for the definition table\n * @param call - The `$$ifdef` or `$$ifndef` call to weigh\n * @returns `true` when the macro's condition holds\n *\n * @remarks\n * `$$ifdef` holds while its flag is set and `$$ifndef` while it is not, which {@link isDefined} answers.\n * A flag that is not a string literal is read as the empty name, which no table sets.\n *\n * @see isDefined\n * @since 3.0.0\n */\n\nexport function isActive(state: MacroStateInterface, call: MacroCallType): boolean {\n const flag = call.arguments[0];\n const name = flag.type === 'Literal' ? String(flag.value) : '';\n\n return (call.callee.name === Macros.ifdef) === isDefined(state.defines, name);\n}\n\n/**\n * Whether a node calls a macro that the build dropped.\n *\n * @param state - Transform state, read for the dropped names\n * @param node - Node to test\n * @returns `true` when the node calls an identifier that the build dropped\n *\n * @remarks\n * How a use of a disabled macro is recognized once its own declaration is gone,\n * which is what lets the transform replace the call rather than leave it to fail while the output runs.\n *\n * @since 3.0.0\n */\n\nexport function isDropped(state: MacroStateInterface, node: Node): boolean {\n return node.type === 'CallExpression' && node.callee.type === 'Identifier' && state.dropped.has(node.callee.name);\n}\n\n/**\n * The macro call a node holds, with whatever call followed it.\n *\n * @param state - Transform state, read for the source text\n * @param node - Node to look in, which may be absent\n * @returns The macro call and its trailing text, or `undefined` where the node holds none\n *\n * @remarks\n * Three shapes reach here.\n * A macro call on its own yields an empty suffix, a call whose callee is the macro yields the text of the outer\n * call as the suffix, and a TypeScript `as` expression is unwrapped and retried.\n *\n * @see MacroTargetInterface\n * @since 3.0.0\n */\n\nexport function macroTarget(state: MacroStateInterface, node?: Node | null): MacroTargetInterface | undefined {\n if (!node) return;\n if (isMacroCall(node)) return { call: node, suffix: '' };\n if (node.type === 'TSAsExpression') return macroTarget(state, node.expression);\n if (node.type !== 'CallExpression' || !isMacroCall(node.callee)) return;\n\n return { call: node.callee, suffix: state.code.slice(node.callee.end, node.end) };\n}\n\n/**\n * The name a declaration binds, together with the macro that initializes it.\n *\n * @param state - Transform state, read for the source text\n * @param node - Declaration to look at, exported or bare\n * @returns The declared name and its macro target, or `undefined` where the node declares no macro\n *\n * @remarks\n * An `export` wrapper is stepped through first, so one test serves the exported form and the bare one alike.\n * A single declarator alone qualifies, which leaves `const a = $$ifdef('DEV', 1), b = 2` untouched.\n *\n * @see DeclaredMacroType\n * @since 3.0.0\n */\n\nexport function declaredMacro(state: MacroStateInterface, node: Node): DeclaredMacroType | undefined {\n const declaration = node.type === 'ExportNamedDeclaration' ? node.declaration : node;\n if (declaration?.type !== 'VariableDeclaration' || declaration.declarations.length !== 1) return;\n\n const { id, init } = declaration.declarations[0];\n if (id.type !== 'Identifier') return;\n\n const target = macroTarget(state, init);\n\n return target && [ id, target ];\n}\n\n/**\n * Rewrites an import that names a dropped macro.\n *\n * @param state - Transform state the edit is collected on\n * @param node - Import declaration to prune\n * @returns `true` when the statement was rewritten\n *\n * @remarks\n * A named specifier bound to a dropped macro is removed, while a default or a namespace import is kept as written.\n * An import left with no specifiers at all becomes a bare `import 'source';`,\n * so a module imported for its side effect still runs.\n *\n * @since 3.0.0\n */\n\nexport function pruneImport(state: MacroStateInterface, node: ImportDeclaration): boolean {\n const named: Array<string> = [];\n const parts: Array<string> = [];\n let dropped = false;\n\n for (const specifier of node.specifiers) {\n const text = state.code.slice(specifier.start, specifier.end);\n\n if (specifier.type !== 'ImportSpecifier') parts.push(text);\n else if (state.dropped.has(specifier.local.name)) dropped = true;\n else named.push(text);\n }\n\n if (!dropped) return false;\n const source = state.code.slice(node.source.start, node.source.end);\n if (named.length > 0) parts.push(`{ ${ named.join(', ') } }`);\n\n if (parts.length < 1) return record(state, node, `import ${ source };`);\n\n return record(state, node, `import ${ parts.join(', ') } from ${ source };`);\n}\n\n/**\n * Rewrites an export list that names a dropped macro.\n *\n * @param state - Transform state the edit is collected on\n * @param node - Export declaration to prune\n * @returns `true` when the statement was rewritten\n *\n * @remarks\n * The specifiers that survive are re-emitted as they were written, and a list left with none is deleted outright.\n * A list that names nothing dropped is reported untouched, so the walk descends into it as usual.\n *\n * @since 3.0.0\n */\n\nexport function pruneExport(state: MacroStateInterface, node: ExportNamedDeclaration): boolean {\n const { specifiers } = node;\n const kept = specifiers.filter(\n ({ local }) => !state.dropped.has(local.type === 'Literal' ? local.value : local.name)\n );\n\n if (kept.length === specifiers.length) return false;\n if (kept.length < 1) return record(state, node, '');\n\n return record(state, node, `export { ${ kept.map(item => state.code.slice(item.start, item.end)).join(', ') } };`);\n}\n\n/**\n * Replaces a declaration whose value comes from a macro.\n *\n * @param state - Transform state the edit is collected on\n * @param node - Declaration to expand, exported or bare\n * @returns `true` when the declaration was rewritten\n *\n * @remarks\n * A name that does not open with {@link MacroPrefix} draws a `macro-prefix` warning and expands either way.\n * An `inline` declaration is deferred until its value has run.\n * A conditional declaration becomes what {@link defineDeclaration} builds while it is active\n * and is deleted where it is not.\n *\n * @since 3.0.0\n */\n\nexport function expandDeclaration(state: MacroStateInterface, node: Node): boolean {\n const declared = declaredMacro(state, node);\n if (!declared) return false;\n\n const [ id, target ] = declared;\n const { call, suffix } = target;\n const prefix = node.type === 'ExportNamedDeclaration' ? 'export ' : '';\n\n if (!id.name.startsWith(MacroPrefix)) report(state, id.start, 'warning', {\n id: 'macro-prefix',\n text: `Macro '${ id.name }' does not start with the '${ MacroPrefix }' prefix to avoid conflicts`\n });\n\n if (call.callee.name === Macros.inline)\n return defer(state, node, call, value => `${ prefix }const ${ id.name } = ${ value }${ suffix };`);\n\n return record(state, node, isActive(state, call) ? defineDeclaration(state.code, id.name, target, prefix) : '');\n}\n\n/**\n * Replaces a macro used as a value.\n *\n * @param state - Transform state the edit is collected on\n * @param node - Node the replacement stands in for\n * @param target - The macro call and whatever call followed it\n * @param statement - Whether the macro stands as a statement of its own\n * @returns `true`, since every call that reaches here rewrites something\n *\n * @remarks\n * An `inline` call is deferred until its value has run.\n * A conditional call becomes what {@link defineExpression} builds while it is active.\n * An inactive one leaves nothing behind as a statement, and `undefined` where a value is expected.\n *\n * @since 3.0.0\n */\n\nexport function expand(state: MacroStateInterface, node: Node, target: MacroTargetInterface, statement: boolean): boolean {\n const { call, suffix } = target;\n\n if (call.callee.name === Macros.inline)\n return defer(state, node, call, value => statement ? '' : `${ value }${ suffix }`);\n\n if (!isActive(state, call)) return record(state, node, statement ? '' : 'undefined');\n\n return record(state, node, defineExpression(state.code, target, statement));\n}\n\n/**\n * Rewrites one node and reports whether the walk should stop there.\n *\n * @param state - Transform state the edits are collected on\n * @param node - Node the walk arrived at\n * @param parent - Node it hangs from, `null` at the root\n * @param key - Property of the parent it sits under\n * @returns `true` when the node was rewritten and the walk should not descend into it\n *\n * @remarks\n * The visitor the rewriting walk runs, dispatching on the type of the node:\n *\n * - **An identifier** - a dropped name becomes `undefined` where it is read, and is left alone where it only names\n * something, which {@link MacroNameKeys} and the parent's `computed` flag decide between.\n * - **An import or an export list** - pruned of the names the build dropped.\n * - **A declaration** - expanded, or pruned where it re-exports rather than declares.\n * - **An expression statement or a call** - expanded, or replaced where it calls something dropped.\n *\n * Any other node is reported untouched, so the walk descends into it.\n *\n * @since 3.0.0\n */\n\nexport function expandNode(state: MacroStateInterface, node: Node, parent: Node | null, key: string): boolean {\n switch (node.type) {\n case 'Identifier': {\n if (!state.dropped.has(node.name) || !parent) return false;\n\n const keyed = key === 'key' || key === 'property';\n const named = keyed ? !('computed' in parent) || !parent.computed : MacroNameKeys.has(key);\n\n return !named && record(state, node, 'undefined');\n }\n\n case 'ImportDeclaration':\n return pruneImport(state, node);\n\n case 'ExportNamedDeclaration':\n if (expandDeclaration(state, node)) return true;\n if (node.source || node.specifiers.length < 1) return false;\n\n return pruneExport(state, node);\n\n case 'VariableDeclaration':\n return expandDeclaration(state, node);\n\n case 'ExpressionStatement': {\n if (isDropped(state, node.expression)) return record(state, node, '');\n const target = macroTarget(state, node.expression);\n\n return target !== undefined && expand(state, node, target, true);\n }\n\n case 'CallExpression':\n case 'TSAsExpression': {\n if (isDropped(state, node)) return record(state, node, 'undefined');\n const target = macroTarget(state, node);\n\n return target !== undefined && expand(state, node, target, false);\n }\n }\n\n return false;\n}\n\n/**\n * Expands every macro in a file and returns the rewritten source.\n *\n * @param parse - The file's parse result, walked rather than parsed again\n * @param target - Absolute path of the file, named in messages and used to resolve an inline value's packages\n * @param content - Source text of the file\n * @param context - Lifecycle context, read for the logs, the flags, and the names the build has dropped\n * @returns The rewritten source, or `content` itself where there was nothing to expand\n *\n * @remarks\n * An empty file comes back untouched, and so does any file under `node_modules`.\n * So does a file that carries no {@link MacroPrefix}, unless an earlier file dropped a name this one may still use.\n * A first walk over a file carrying {@link MacroScanHint} collects the conditional macros that are not active and\n * adds their names to the set the build shares, so dropping a name where it was declared.\n * also drops it where it is imported.\n * The rewriting walk follows, and any deferred `inline` value is awaited before the edits are applied.\n *\n * @example\n * ```ts\n * // source: export const $$dev = $$ifdef('DEV', () => log());\n * await transformMacros(parse, '/src/a.ts', content, context);\n * // result: export function $$dev() { return log(); } - while DEV is set\n * ```\n *\n * @see analyzeMacros\n * @see MacroStateInterface\n *\n * @since 3.0.0\n */\n\nexport async function transformMacros(\n parse: ParseResult, target: string, content: string, context: LifecycleContextInterface\n): Promise<string> {\n if (content.length < 1 || target.includes('node_modules')) return content;\n\n const { dropped } = context.stage;\n if (dropped.size < 1 && !content.includes(MacroPrefix)) return content;\n\n const state: MacroStateInterface = {\n target,\n dropped,\n code: content,\n logs: context.logs,\n edits: [],\n pending: [],\n defines: context.options.define ?? {},\n overrides: context.overrides\n };\n\n if (content.includes(MacroScanHint)) walk(parse.program, node => {\n const declared = declaredMacro(state, node);\n if (!declared) return false;\n\n const [ id, { call }] = declared;\n if (call.callee.name !== Macros.inline && !isActive(state, call)) dropped.add(id.name);\n\n return false;\n });\n\n walk(parse.program, expandNode.bind(null, state));\n if (state.pending.length > 0) await Promise.all(state.pending);\n\n return applyEdits(content, state.edits);\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { MacroCallType, MacroStateInterface } from '@directives/interfaces/macros-directive.interface';\n\n/**\n * Imports\n */\n\nimport { createRequire } from 'module';\nimport { inject } from '@remotex-labs/xinject';\nimport { sandboxExecute } from '@services/vm.service';\nimport { stringify } from '@components/object.component';\nimport { FrameworkService } from '@services/framework.service';\nimport { buildFromString } from '@services/transpiler.service';\n\n/**\n * Renders an evaluated value as the source text that stands in for the call.\n *\n * @param value - Value the callback produced\n * @returns Source text for the value, or `'undefined'` where there is nothing to render\n *\n * @remarks\n * `undefined` and `null` both come out as `undefined`, since the call has to leave an expression behind.\n * A function comes out as its own source, and a number or a boolean through `String`.\n * Everything else goes through {@link stringify}, which is JSON,\n * so a `Map` or a `Set` arrives as `{}` and a `bigint` as a quoted string.\n *\n * @since 3.0.0\n */\n\nexport function serialize(value: unknown): string {\n if (value === undefined || value === null) return 'undefined';\n if (typeof value === 'function') return value.toString();\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n\n return stringify(value) ?? 'undefined';\n}\n\n/**\n * Runs the callback of an `$$inline` call and renders what it produced.\n *\n * @param state - Transform state, read for the source text and for the file the call sits in\n * @param call - The `$$inline` call whose only argument is the callback to run\n * @returns Source text standing for the value the callback produced\n *\n * @throws BuildFailure - Rejected by esbuild when the callback does not build\n * @throws Error - Whatever the callback itself threw while it ran\n *\n * @remarks\n * The callback is taken from the source as written, wrapped in a CommonJS module that calls it,\n * and built through {@link buildFromString}.\n * A relative specifier inside it therefore resolves against the working directory rather than against the file that\n * the call sits in.\n * A package stays external and is required through a `require` bound to that file as the callback runs.\n * The built code runs through {@link sandboxExecute}, and the value is read from what the run returned,\n * falling back to `module.exports`.\n * What comes back is source text rather than a value, since {@link serialize} renders it.\n *\n * @example\n * ```ts\n * // $$inline(() => 2 + 2)\n * await evaluate(state, call); // '4'\n *\n * // $$inline(() => ({ region: 'eu' }))\n * await evaluate(state, call); // '{\"region\":\"eu\"}'\n * ```\n *\n * @see serialize\n * @see sandboxExecute\n * @see buildFromString\n *\n * @since 3.0.0\n */\n\nexport async function evaluate(state: MacroStateInterface, call: MacroCallType): Promise<string> {\n const target = state.target + '.inline';\n const thunk = state.code.slice(call.arguments[0].start, call.arguments[0].end);\n const [ map, output ] = (await buildFromString(`module.exports = (${ thunk })();`, target, {\n format: 'cjs',\n platform: 'node',\n packages: 'external'\n })).outputFiles!;\n\n const module = { exports: undefined };\n inject(FrameworkService).addSourceMap(target, map.text, true);\n const value = await sandboxExecute(output.text, { module, require: createRequire(state.target) }, {\n filename: target\n });\n\n return serialize(value ?? module.exports);\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { Context, ScriptOptions } from 'vm';\n\n/**\n * Imports\n */\n\nimport { Script, createContext } from 'vm';\n\n/**\n * Runs code in a VM context that shares the host's globals.\n *\n * @param code - Source to compile and run\n * @param sandbox - Values to expose as globals, each shadowing the host value of the same name\n * @param options - Compile-time options, such as the filename errors are reported against\n * @param isolateLogs - Whether to keep the code's console output from reaching the host\n * @returns The completion value of the last expression, awaited when it is a promise\n *\n * @throws SyntaxError - Thrown when the code does not compile\n * @throws Error - Whatever the code itself throws, propagated unchanged\n *\n * @remarks\n * The host's own globals are copied into the context before the sandbox is applied,\n * so the code inside sees the same intrinsics the caller does.\n * A value the code builds crosses back out intact - a `RegExp` made inside satisfies `instanceof RegExp` outside,\n * which a fresh context's own intrinsics would not.\n * This isolates the global scope, not the process.\n * `process` and the timers are reachable from the code being run,\n * so it is a scoping tool for code you trust rather than a boundary against code you do not.\n * Only compilation is configurable - the run is fixed to break on `SIGINT` and to leave errors undecorated.\n * It carries no timeout, so code that never finishes blocks the caller.\n *\n * `isolateLogs` drops the host `console` rather than replacing it,\n * so the code falls back to the console a fresh context is given and its output reaches nothing the caller sees.\n * A call still succeeds, since `console.log` is a function either way,\n * so quieting the output does not break code that logs.\n * The drop happens after the sandbox is applied, so it takes a `console` the caller injected as well.\n * It covers the console alone - code writing to `process.stdout` reaches the host whatever this is set to.\n *\n * @example\n * ```ts\n * await sandboxExecute('2 + 2'); // 4\n * (await sandboxExecute('new RegExp(\"a\")')) instanceof RegExp; // true - the host's RegExp\n *\n * const module = { exports: {} };\n * await sandboxExecute('module.exports = process.cwd();', { module });\n * module.exports; // 'D:/app' - read back through the injected object\n *\n * await sandboxExecute('console.log(\"noisy\"); 1', {}, {}, true); // 1 - nothing printed\n * ```\n *\n * @see Context\n * @see ScriptOptions\n *\n * @since 3.0.0\n */\n\nexport async function sandboxExecute(code: string, sandbox: Context = {}, options: ScriptOptions = {}, isolateLogs = false): Promise<unknown> {\n const base: Record<string, unknown> = {};\n const descriptors: { [x: string]: PropertyDescriptor; } = Object.getOwnPropertyDescriptors(globalThis);\n delete descriptors.globalThis;\n if(isolateLogs) delete descriptors.console;\n\n Object.defineProperties(base, descriptors);\n Object.assign(base, sandbox);\n\n const context = createContext(base);\n const script = new Script(code, options);\n\n return await script.runInContext(context, { breakOnSigint: true, displayErrors: false });\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { BuildOptions, BuildResult, Metafile } from 'esbuild';\nimport type { BuildResultType } from '@services/interfaces/transpiler-service.interface';\n\n/**\n * Imports\n */\n\nimport { cwd } from 'process';\nimport { build } from 'esbuild';\nimport { dirname, basename } from '@remotex-labs/xmap';\nimport { DefaultBuildOptions } from '@constants/transpiler.constant';\n\n/**\n * Builds whatever the options describe and returns the result in memory.\n *\n * @typeParam T - Extra fields to widen the result with, for a caller that attaches its own\n *\n * @param buildOptions - esbuild options, the entry points among them, overriding {@link DefaultBuildOptions}\n * @returns The build result, carrying a metafile the type still marks optional\n *\n * @throws BuildFailure - Rejected by esbuild when the build fails, carrying its errors and warnings\n *\n * @remarks\n * Options are layered in four steps: the working directory, then {@link DefaultBuildOptions},\n * then the caller's own, and last the metafile.\n * Only the metafile is applied after the caller's, so it is the single option that cannot be turned off.\n * Everything else is the caller's to change, including the working directory and whether output is written at all.\n * Entry points travel in the options like any other setting,\n * so a build is described by a single object rather than by an argument and an object that have to agree.\n *\n * @example\n * ```ts\n * const result = await buildFiles({ entryPoints: [ 'src/index.ts' ] });\n *\n * result.outputFiles?.length; // 2 - the source map and the code\n * Object.keys(result.metafile!.inputs); // [ 'src/index.ts', 'src/builder.ts' ]\n * ```\n *\n * @see DefaultBuildOptions\n * @since 3.0.0\n */\n\nexport async function buildFiles<T = object>(buildOptions: BuildOptions = {}): Promise<BuildResultType & T> {\n return await build({\n absWorkingDir: cwd(),\n ...DefaultBuildOptions,\n ...buildOptions,\n metafile: true\n }) as BuildResultType & T;\n}\n\n/**\n * Builds source text that has no file behind it.\n *\n * @typeParam T - Extra fields to widen the result with, for a caller that attaches its own\n *\n * @param source - TypeScript source to build\n * @param path - Name the source is reported under in its map and in errors, which need not exist on the disk\n * @param buildOptions - Options overriding {@link DefaultBuildOptions}\n * @returns The build result, carrying the code and its map in `outputFiles`\n *\n * @throws BuildFailure - Rejected by esbuild when the build fails, carrying its errors and warnings\n *\n * @remarks\n * The text is fed in through esbuild's `stdin` rather than read from a file,\n * which is what lets a macro body or a generated snippet be built before any file exists.\n * It is loaded as TypeScript, and its relative imports resolve against the working directory rather than against\n * `path`, which names the source in the map and in errors without pointing at a real location.\n * Four options are fixed after the caller's and cannot be overridden: the stdin input, in-memory output, the metafile,\n * and an external source map.\n * Logging is not among them: it arrives silent from {@link DefaultBuildOptions} and stays the caller's to raise.\n *\n * @example\n * ```ts\n * const result = await buildFromString('export const x: number = 42;', 'virtual.ts');\n *\n * result.outputFiles?.length; // 2 - the source map and the code\n * Object.keys(result.metafile!.inputs); // [ 'virtual.ts' ] - keyed by the name that was passed\n * ```\n *\n * @see DefaultBuildOptions\n * @since 3.0.0\n */\n\nexport async function buildFromString<T = object>(source: string, path: string, buildOptions: BuildOptions = {}): Promise<BuildResultType & T> {\n return await build({\n absWorkingDir: cwd(),\n ...DefaultBuildOptions,\n ...buildOptions,\n stdin: {\n loader: 'ts',\n contents: source,\n resolveDir: dirname(path),\n sourcefile: basename(path)\n },\n write: false,\n metafile: true,\n sourcemap: 'external'\n }) as BuildResultType & T;\n}\n\n/**\n * Walks the imports of the entry points named in the options and returns the dependency graph, building no output.\n *\n * @param buildOptions - esbuild options, the entry points to walk among them, applied under the ones it fixes\n * @returns The result, its `metafile` describing every input reached and the imports between them\n *\n * @throws BuildFailure - Rejected by esbuild when a specifier does not resolve\n *\n * @remarks\n * Bundling is what does the walking,\n * so the graph matches what a bundler would resolve rather than a reading of the import statements.\n * An unresolvable specifier therefore fails the call instead of being reported as a missing edge.\n * Packages are marked external, so the walk stops at the project's edge rather than descending into `node_modules`.\n * Nothing reaches the disk: output is kept in memory,\n * and the output directory is nominal, named only because esbuild insists on one.\n * {@link DefaultBuildOptions} is not applied here, unlike {@link buildFiles}, so the caller's options and the seven\n * fixed after them are the whole of the configuration.\n *\n * @example\n * ```ts\n * const result = await analyzeDependencies({ entryPoints: [ 'src/index.ts' ] });\n *\n * Object.keys(result.metafile.inputs); // [ 'src/index.ts', 'src/builder.ts' ]\n * result.metafile.inputs['src/index.ts'].imports; // [ { path: 'src/builder.ts', kind: 'import-statement' } ]\n * ```\n *\n * @see Metafile\n * @since 3.0.0\n */\n\nexport async function analyzeDependencies(buildOptions: BuildOptions = {}): Promise<\n BuildResult & { metafile: Metafile }\n> {\n return await build({\n ...buildOptions,\n write: false,\n bundle: true,\n outdir: 'tmp',\n outfile: undefined,\n metafile: true,\n packages: 'external',\n logLevel: 'silent'\n });\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { BuildOptions } from 'esbuild';\n\n/**\n * Base esbuild options every build in this package starts from.\n *\n * @remarks\n * Output is kept in memory rather than written,\n * so a caller reads `outputFiles` and decides for itself what reaches the disk.\n * The source map is emitted as its own output file rather than inlined,\n * which keeps the code readable and lets a consumer attach the map only when it wants it.\n * An output directory is set even though nothing is written,\n * since esbuild insists on one as soon as a build has more than a single entry point.\n * Spread before the caller's options wherever it is used,\n * so any of these can be overridden - unlike the options each build helper fixes after them.\n *\n * @example\n * ```ts\n * defaultBuildOptions.write; // false - the result is returned, not written\n * await buildFiles({ entryPoints: [ 'src/index.ts' ], minify: false }); // overrides one, keeps the rest\n * ```\n *\n * @see BuildOptions\n * @since 2.0.0\n */\n\nexport const DefaultBuildOptions: BuildOptions = {\n write: false,\n bundle: true,\n minify: true,\n outdir: 'dist',\n format: 'cjs',\n target: 'esnext',\n logLimit: 0,\n logLevel: 'silent',\n platform: 'browser',\n sourcemap: 'external'\n};\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { BuildOptions } from 'esbuild';\n\n/**\n * Imports\n */\n\nimport { cwd } from 'process';\nimport { relative } from '@remotex-labs/xmap';\nimport { collectFiles } from '@components/glob.component';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * Normalizes entry points of any esbuild form into an output name to input path record.\n *\n * @param entryPoints - Entry points in any form esbuild accepts, or `undefined`\n * @param root - Directory the output names are shortened against, defaulting to the working directory\n * @returns The entry points keyed by the output each one produces, or `undefined` when none were given\n *\n * @throws Error - When the entry points are neither an array, an object, nor `undefined`\n *\n * @remarks\n * The three forms differ only in where the output name comes from:\n * - A list of globs is matched from the working directory, and each file is keyed by its path with `root` stripped\n * off the front and the extension dropped, so `src` as the root turns `src/components/interactive.component.ts`\n * into `components/interactive.component`.\n * - A list of `in` and `out` pairs is keyed by `out`, both paths passing through untouched.\n * - A record is already in the target shape and is returned as it stands, without a copy.\n *\n * Globs are always matched from the working directory, whatever `root` says: `root` shortens the output names and\n * does nothing else, matching no files itself and excluding none.\n * A file the globs reach from outside `root` is therefore kept rather than dropped,\n * and is named by its whole path from the working directory instead.\n * One call can therefore carry files from either side of `root`:\n * an outside file lands in a directory of its own in the output, while an inside file lands at the top.\n * The values are the paths the walk produced, relative to the working directory,\n * so nothing is resolved a second time, and a key costs one slice.\n * An empty list yields an empty record rather than every file under the working directory, which a pattern set with\n * no includes would otherwise match.\n *\n * @example\n * ```ts\n * extractEntryPoints([ 'src/**' ]);\n * // { 'src/index': 'src/index.ts', 'src/components/glob.component': 'src/components/glob.component.ts' }\n *\n * extractEntryPoints([ 'src/**' ], 'src/components');\n * // {\n * // 'glob.component': 'src/components/glob.component.ts', // under the root, shortened to its own name\n * // 'src/services/vm.service': 'src/services/vm.service.ts' // outside it, named by its whole path\n * // }\n *\n * extractEntryPoints([ { in: 'src/index.ts', out: 'bundle' } ]);\n * // { bundle: 'src/index.ts' }\n * ```\n *\n * @see collectFiles\n * @see {@link https://esbuild.github.io/api/#entry-points | esbuild entry points}\n *\n * @since 3.0.0\n */\n\nexport function extractEntryPoints(entryPoints: BuildOptions['entryPoints'], root: string = cwd()): Record<string, string> | undefined {\n if (entryPoints === undefined) return undefined;\n if (!Array.isArray(entryPoints)) {\n if (typeof entryPoints !== 'object' || entryPoints === null) throw new Error('Unsupported entry points format');\n\n return entryPoints;\n }\n\n const result: Record<string, string> = {};\n if (entryPoints.length < 1) return result;\n\n if (typeof entryPoints[0] === 'object') {\n for (const entry of <Array<{ in: string, out: string }>> entryPoints) result[entry.out] = entry.in;\n\n return result;\n }\n\n const prefix = relative(cwd(), FrameworkService.resolve(root));\n const scope = prefix && prefix !== '.' ? `${ prefix }/` : '';\n\n for (const file of collectFiles(cwd(), <Array<string>> entryPoints)) {\n const name = scope && file.startsWith(scope) ? file.slice(scope.length) : file;\n const dot = name.lastIndexOf('.');\n result[dot > name.lastIndexOf('/') + 1 ? name.slice(0, dot) : name] = file;\n }\n\n return result;\n}\n","/**\n * The configuration blocks a build injects into its esbuild options as text.\n *\n * @remarks\n * The three settings a configuration states as a table of names to code rather than as a plain option,\n * so one pass over this list injects all of them instead of naming each at its own call site.\n * A value written as a function is called for the variant being built and its result injected,\n * which is what makes the three interchangeable here.\n *\n * @example\n * ```ts\n * for (const block of TextBlocks) injectTextBlock(options, block); // banner, then footer, then define\n * ```\n *\n * @see VariantService\n * @since 3.0.0\n */\n\nexport const TextBlocks = [ 'banner', 'footer', 'define' ] as const;\n\n/**\n * The reporting level each TypeScript diagnostic category maps to.\n *\n * @remarks\n * Indexed by `ts.DiagnosticCategory`, which counts `Warning` as `0`, `Error` as `1`, and `Suggestion` as `2`,\n * so the order of the entries is the mapping itself rather than a preference.\n * `Message` counts as `3` and falls off the end,\n * so whatever reads the table settles that one for itself.\n *\n * @example\n * ```ts\n * DiagnosticLevels[1]; // 'error' - ts.DiagnosticCategory.Error\n * DiagnosticLevels[3]; // undefined - a plain message, left to the reader\n * ```\n *\n * @see LogLevelType\n * @see VariantService\n *\n * @since 3.0.0\n */\n\nexport const DiagnosticLevels = [ 'warning', 'error', 'info' ];\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { PartialMessage, Message, OnStartResult } from 'esbuild';\n\n/**\n * Imports\n */\n\nimport { parseErrorStack } from '@remotex-labs/xmap/parser.component';\n\n/**\n * Reports whether a caught value carries esbuild's own messages rather than being an ordinary error.\n *\n * @param error - Value caught from a build, of unknown shape\n * @returns `true` when the value holds esbuild messages, which narrows it to {@link OnStartResult}\n *\n * @remarks\n * The test is a non-null object whose `errors` array holds at least one entry,\n * and whose first entry is an object carrying a `detail` key.\n * esbuild puts `detail` on every message it produces, so the key is there even where it holds nothing,\n * and the guard reads whether the key is present rather than what it holds.\n * That is what separates a nested build that failed from an error a hook threw:\n * the first already carries messages a reporter files as they stand,\n * while the second reaches {@link errorToMessage} to become one.\n * A result assembled by hand goes unrecognized, since a message written as `{ text }` carries no `detail` key.\n *\n * @example\n * ```ts\n * isEsbuildError(buildFailure); // true - errors[0] came from esbuild\n * isEsbuildError(new Error('boom')); // false - no errors\n * isEsbuildError({ errors: [] }); // false - nothing to report\n * isEsbuildError({ errors: [ { text: 'oops' } ] }); // false - no detail key\n * ```\n *\n * @see errorToMessage\n * @since 3.0.0\n */\n\nexport function isEsbuildError(error: unknown): error is OnStartResult {\n if (error === null || typeof error !== 'object') return false;\n\n const errors = (error as { errors?: unknown }).errors;\n if (!Array.isArray(errors) || errors.length === 0) return false;\n const first = errors[0];\n\n return first !== null && typeof first === 'object' && 'detail' in first;\n}\n\n/**\n * Converts a thrown error into an esbuild message.\n *\n * @param error - Error to convert, kept whole on the message's `detail`\n * @param id - Message id to file the diagnostic under, empty when the caller names none\n * @param name - Plugin name to credit the message to, empty when the caller names none\n * @returns The message, carrying a location when the error's first frame named one\n *\n * @remarks\n * The error travels on `detail` rather than flattened into the text,\n * so {@link getErrorStack} unwraps it later and resolves the whole trace instead of the summary line alone.\n * `text` is the message the stack parsed out, and `location` comes from the first frame,\n * set only when that frame names a file, a line, and a column.\n * A frame of the three leaves the message without a location,\n * which leaves a reader with the text alone.\n * The location is filed under the `file` namespace, since a parsed frame points at a path on disk\n * rather than at something a plugin serves itself.\n *\n * @example\n * ```ts\n * const message = errorToMessage(new Error('boom'), 'macro-failed', 'xbuild');\n * message.text; // 'boom'\n * message.id; // 'macro-failed'\n * message.location?.line; // 19 - the line the first frame points at\n * ```\n *\n * @see getErrorStack\n * @see parseErrorStack\n *\n * @since 3.0.0\n */\n\nexport function errorToMessage(error: Error, id: string = '', name: string = ''): Message {\n const message = { detail: error, id, pluginName: name } as PartialMessage;\n\n const parsedStack = parseErrorStack(error);\n const frame = parsedStack.stack[0];\n\n message.text = parsedStack.message;\n if (frame?.fileName && frame.line && frame.column) {\n message.location = {\n line: frame.line,\n file: frame.fileName,\n column: frame.column,\n namespace: 'file'\n };\n }\n\n return message as Message;\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { FSWatcher, Dirent } from 'fs';\nimport type { ErrorType, CompleteType, UnsubscribeType } from '@remotex-labs/xobservable';\nimport type { WatchEventType, ChangeType, ObserverType } from './interfaces/watch-service.interface';\nimport type { WatchChangeInterface, WatchOptionsInterface } from './interfaces/watch-service.interface';\n\n/**\n * Imports\n */\n\nimport { Injectable } from '@remotex-labs/xinject';\nimport { Subject } from '@remotex-labs/xobservable';\nimport { ChangeCode } from '@constants/watch.constant';\nimport { createMatcher } from '@components/glob.component';\nimport { resolve, join, relative } from '@remotex-labs/xmap';\nimport { watch, realpathSync, readdirSync, lstatSync, statSync } from 'fs';\n\n/**\n * A filesystem watcher that multicasts debounced batches of path changes to every subscriber.\n *\n * @remarks\n * Extends a multicast {@link Subject}: the underlying `fs.watch` handles are opened on the **first** subscription and\n * torn down only when the **last** subscription ends, while every active subscriber receives each emitted batch.\n * Events are filtered by a glob matcher, coalesced within a debounced window, and delivered as a single\n * {@link WatchEventType} keyed by path relative to the base.\n * Because `fs.watch` never follows symbolic links,\n * {@link WatchOptionsInterface.followSymlinks} places explicit watchers on the links it finds.\n * As a {@link Subject}, the emitted stream can be reshaped with `pipe` and operators before subscribing.\n *\n * @example\n * <caption>Multiple independent subscribers - each receives every batch</caption>\n * ```ts\n * const watcher = new WatchService('src', { recursive: true, filter: [ '**\\/*.{ts,js}' ], debounce: 100 });\n *\n * const stopA = watcher.subscribe((changes) => rebuild(changes)); // opens the fs watchers\n * const stopB = watcher.subscribe((changes) => reloadTypes(changes)); // reuses them\n *\n * stopB(); // watchers stay open - `stopA` is still subscribed\n * stopA(); // last subscriber leaves - every handle is closed\n * ```\n *\n * @example\n * <caption>Scoped teardown - the subscription disposes automatically at the end of the block</caption>\n * ```ts\n * const watcher = new WatchService(cwd(), { followSymlinks: true, filter: [ '**\\/*.{ts,js}' ] });\n * using sub = watcher.subscribe((changes) => console.log(Object.keys(changes)));\n * ```\n *\n * @see Subject.pipe\n * @see WatchEventType\n * @see WatchOptionsInterface\n *\n * @since 3.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class WatchService extends Subject<WatchEventType> {\n /**\n * The absolute root path being watched.\n *\n * @since 3.0.0\n */\n\n private readonly base: string;\n\n /**\n * Predicate deciding whether a path passes the configured filter.\n *\n * @since 3.0.0\n */\n\n private readonly matcher: ReturnType<typeof createMatcher>;\n\n /**\n * Active `fs.watch` handles, keyed by the path each was opened on.\n *\n * @since 3.0.0\n */\n\n private readonly watchers = new Map<string, FSWatcher>();\n\n /**\n * Changes accumulated in the current debounced window, keyed by path relative to the base.\n *\n * @since 3.0.0\n */\n\n private readonly pending = new Map<string, WatchChangeInterface>();\n\n /**\n * Count of currently active subscriptions, used to start watchers on the first and stop them on the last.\n *\n * @since 3.0.0\n */\n\n private subscriptions = 0;\n\n /**\n * Handle for the scheduled debounced flush, or `undefined` while idle.\n *\n * @since 3.0.0\n */\n\n private timer?: ReturnType<typeof setTimeout>;\n\n /**\n * Creates a watcher rooted at a base path.\n *\n * @param base - Directory to watch, resolved to an absolute path\n * @param options - Filtering, debounce, recursion, and symlink behavior\n *\n * @remarks\n * No watcher is opened until the first subscriber attaches, so constructing one costs a resolve and a matcher.\n *\n * @example\n * ```ts\n * const watcher = new WatchService('src', { filter: [ '**\\/*.ts' ] }); // nothing is watched yet\n * ```\n *\n * @see WatchOptionsInterface\n * @since 3.0.0\n */\n\n constructor(base: string, private options?: WatchOptionsInterface) {\n super();\n\n this.base = resolve(base);\n this.matcher = createMatcher(this.options?.filter ?? [], {\n dot: this.options?.dot ?? false\n });\n }\n\n /**\n * Subscribes to the debounced change stream, starting the watchers on the first subscriber.\n *\n * @param observerOrNext - A full observer object, or a `next` callback\n * @param error - Error handler, used when the first argument is a `next` callback\n * @param complete - Completion handler, used when the first argument is a `next` callback\n * @returns Idempotent, disposable unsubscribe function that detaches this subscriber and,\n * once it is the last one, closes every open watcher\n *\n * @remarks\n * The first subscription opens the `fs.watch` handles, and each later subscription reuses them.\n * Unsubscribing runs at most once.\n * The handles, the pending batch, and the flush timer are released only when the final subscriber leaves,\n * so a watcher shared by several consumers stays alive until all of them detach.\n *\n * @example\n * ```ts\n * const stop = watcher.subscribe((changes) => rebuild(changes));\n * stop(); // detaches, and closes the handles when no other subscriber is left\n * ```\n *\n * @see ObserverType\n * @see Subject.subscribe\n *\n * @since 3.0.0\n */\n\n override subscribe(observerOrNext?: ObserverType, error?: ErrorType, complete?: CompleteType): UnsubscribeType {\n const unsubscribe = super.subscribe(observerOrNext, error, complete);\n if (++this.subscriptions === 1) this.start();\n\n return this.toUnsubscribe(() => {\n unsubscribe();\n if (--this.subscriptions === 0) this.stop();\n });\n }\n\n /**\n * The debounced window in milliseconds, defaulting to 150.\n *\n * @since 3.0.0\n */\n\n private get debounce(): number {\n return this.options?.debounce ?? 150;\n }\n\n /**\n * Opens the base watcher and the symlink watchers when configured.\n *\n * @remarks\n * Invoked once when the subscriber count rises from zero to one.\n *\n * @since 3.0.0\n */\n\n private start(): void {\n this.watch(this.base, this.ignored.bind(this), this.options?.recursive);\n if (this.options?.followSymlinks) this.watchSymlinks(this.base);\n }\n\n /**\n * Clears the pending timer and closes every open watcher.\n *\n * @remarks\n * Invoked once when the subscriber count falls back to zero, returning the service to its pre-subscription state so\n * a later subscription can start clean.\n *\n * @since 3.0.0\n */\n\n private stop(): void {\n if (this.timer) clearTimeout(this.timer);\n for (const watcher of this.watchers.values()) watcher.close();\n\n this.timer = undefined;\n this.pending.clear();\n this.watchers.clear();\n }\n\n /**\n * Emits the accumulated batch to every subscriber and clears the window.\n *\n * @remarks\n * A no-op when nothing is pending, so an expired timer with no changes emits nothing.\n * A `next` that throws is reported to that subscriber's own `error` handler by the {@link Subject},\n * which then rethrows the failures as one aggregate.\n * That aggregate is swallowed here, so one faulty consumer cannot stop the watcher for the others.\n *\n * @since 3.0.0\n */\n\n private flush(): void {\n this.timer = undefined;\n if (this.pending.size === 0) return;\n\n const batch = Object.fromEntries(this.pending) as WatchEventType;\n this.pending.clear();\n\n try {\n this.next(batch);\n } catch {\n /* handled per-observer by the Subject */\n }\n }\n\n /**\n * Closes and forgets the watcher registered on a path, if any.\n *\n * @param path - Path whose watcher should be released\n *\n * @since 3.0.0\n */\n\n private watcherClose(path: string): void {\n const watcher = this.watchers.get(path);\n if (!watcher) return;\n\n watcher.close();\n this.watchers.delete(path);\n }\n\n /**\n * Classifies a raw watch event and queues it for the next flush.\n *\n * @param event - The `fs.watch` event name, either `rename` or `change`\n * @param path - Absolute path the event refers to\n *\n * @remarks\n * A symlink is stat-followed: when it resolves to a matching file, it is watched directly,\n * and when it resolves to a directory under a recursive watch, it is watched recursively.\n * A broken link is dropped.\n * The change type is read from that followed `stat` - a missing entry is {@link ChangeCode.Deleted} and closes its\n * watcher, an entry whose `birthtime` equals its `mtime` is {@link ChangeCode.Added},\n * and anything else is {@link ChangeCode.Change}.\n * Only paths that pass the filter arm the debounced timer and enter the pending batch.\n *\n * @since 3.0.0\n */\n\n private watcherEvent(event: string, path: string): void {\n const relativePath = relative(this.base, path);\n const link = lstatSync(path, { throwIfNoEntry: false });\n const stats = link?.isSymbolicLink() ? statSync(path, { throwIfNoEntry: false }) : link;\n\n if (link?.isSymbolicLink()) {\n if (!stats) return;\n if (event === 'rename') this.watcherClose(path);\n\n if (stats.isFile() && this.matcher(path)) this.watch(path);\n else if (stats.isDirectory() && this.options?.recursive)\n this.watch(path, this.ignored.bind(this), true);\n }\n\n if (!this.matcher(relativePath)) return;\n if (this.timer) this.timer.refresh();\n else this.timer = setTimeout(this.flush.bind(this), this.debounce);\n\n let type: ChangeType;\n if (!stats) {\n this.watcherClose(path);\n type = ChangeCode.Deleted;\n } else {\n type = stats.birthtimeMs === stats.mtimeMs ? ChangeCode.Added : ChangeCode.Change;\n }\n\n this.pending.set(relativePath, { type, stats });\n }\n\n /**\n * Opens an `fs.watch` on a path and registers its change and error handlers.\n *\n * @param path - Path to watch, ignored if already watched or filtered out by {@link ignored}\n * @param ignore - Optional per-entry ignore predicate forwarded to `fs.watch`\n * @param recursive - Whether the watch should cover nested entries\n *\n * @remarks\n * The watch is opened on the real (symlink-resolved) path, while events are reported against the original `path`.\n * A watcher error closes the watcher and forwards the error to every subscriber.\n *\n * @since 3.0.0\n */\n\n private watch(path: string, ignore?: (filename: string) => boolean, recursive: boolean = false): void {\n if (this.watchers.has(path) || this.ignored(path)) return;\n const watcher = watch(realpathSync(path), { recursive, ignore }, (event, filename) => {\n if (!filename) return;\n const target = path.includes(filename) ? path : join(path, filename);\n this.watcherEvent(event, target);\n });\n\n watcher.on('error', (error: Error) => {\n this.watcherClose(path);\n this.error(error);\n });\n\n this.watchers.set(path, watcher);\n }\n\n /**\n * Whether a path should be skipped by the watcher.\n *\n * @param target - Path to test\n * @returns `true` for an empty path, a `~` backup file, or - unless `dot` is set - any dot-prefixed segment\n *\n * @since 3.0.0\n */\n\n private ignored(target: string): boolean {\n if (!target || target.endsWith('~')) return true;\n if (!this.options?.dot) {\n if (target && target.split(/[/\\\\]/).some(\n seg => seg.startsWith('.'))\n ) return true;\n }\n\n return false;\n }\n\n /**\n * Walks the tree under a root and watches every symbolic link found.\n *\n * @param root - Directory to scan for links\n *\n * @remarks\n * Iterative and single-level per read, so ignored directories are pruned before entry and never fully materialized.\n * Descends into real subdirectories only when recursion is enabled.\n * Unreadable directories are skipped silently.\n *\n * @since 3.0.0\n */\n\n private watchSymlinks(root: string): void {\n const stack: Array<string> = [ root ];\n\n while (stack.length) {\n const dir = stack.pop()!;\n\n let entries: Array<Dirent>;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const full = join(entry.parentPath ?? dir, entry.name);\n if (this.ignored(full)) continue;\n\n if (entry.isSymbolicLink()) {\n this.watch(full, this.ignored.bind(this), this.options?.recursive);\n } else if (this.options?.recursive && entry.isDirectory()) {\n stack.push(full);\n }\n }\n }\n }\n}\n","/**\n * Type-only imports erased during TypeScript compilation.\n */\n\nimport type { xBuildConfigInterface } from '@providers/interfaces/config-file-provider.interface';\n\n/**\n * Imports\n */\n\nimport { resolve } from 'path';\nimport process from 'node:process';\nimport { createRequire } from 'module';\nimport { dirname } from '@remotex-labs/xmap';\nimport { ArgvModule } from '@argv/argv.module';\nimport { inject } from '@remotex-labs/xinject';\nimport { FilesModel } from '@models/files.model';\nimport { sandboxExecute } from '@services/vm.service';\nimport { deepMerge } from '@components/object.component';\nimport { FrameworkService } from '@services/framework.service';\nimport { buildFromString } from '@services/transpiler.service';\n\n/**\n * Runs a compiled configuration file and returns what it exported.\n *\n * @typeParam T - Shape the export is cast to, which the caller states rather than this function checks\n *\n * @param code - The file, already compiled to CommonJS\n * @param path - Path the file came from, which binds its `require` and names it in a stack\n * @param $argv - Arguments to expose to the file as a global, empty where none have been parsed yet\n * @param isolation - Whether to keep the file's console output from reaching the host\n * @returns The named `config` export, the default export where there is none, or an empty object for neither\n *\n * @throws Error - Whatever the file itself threw while it ran\n *\n * @remarks\n * The `require` handed in is bound to the file's own path rather than to this module,\n * so a configuration file resolves a package the way a file in its own directory would.\n * A named `config` export wins over a default export, and a file exporting neither comes back empty.\n * Compiled CommonJS replaces `module.exports` outright,\n * which is what leaves the two exports to be told apart rather than read off the object this function seeded.\n * Reach for `isolation` on a run whose output would only be repeated, since a file may be run more than once.\n *\n * @example\n * ```ts\n * // the file: export const config = { serve: { dir: 'dist' } };\n * const config = await execConfigFile(code, 'xbuild.config.ts', { watch: true });\n * config.serve; // { dir: 'dist' }\n * ```\n *\n * @see sandboxExecute\n * @see configFileProvider\n *\n * @since 3.0.0\n */\n\nexport async function execConfigFile<T>(code: string, path: string, $argv = {}, isolation = false): Promise<T> {\n const module = { exports: { config: {}, default: {} } };\n await sandboxExecute(code, { require: createRequire(resolve(path)), module, $argv }, { filename: path }, isolation);\n const config = module.exports.config ?? module.exports.default;\n\n return (config ?? {}) as T;\n}\n\n/**\n * Loads a configuration file and returns what it exported.\n *\n * @typeParam T - Shape the result is cast to, which the caller states rather than this provider checks\n * @param path - Path of the configuration file, relative or absolute\n * @param argv - Object the parsed arguments are written onto, left untouched where the file is missing\n * @returns What the file exported over the default watch settings, or an empty object where it exported nothing\n *\n * @throws BuildFailure - Rejected by esbuild when the file does not compile\n * @throws Error - Whatever the file itself threw while it ran\n *\n * @remarks\n * A configuration file is built as CommonJS and runs through {@link sandboxExecute},\n * with its `require` bound to its own path,\n * so it may import a package the project already depends on rather than only what this build bundles.\n * Its identifiers survive the build, and its source map is registered with {@link FrameworkService},\n * so an error thrown while it runs is reported against the source that was written.\n *\n * The file runs twice, since the options it declares through `userArgv` are known only once it has been read.\n * The first run is a throwaway: it sees an empty `$argv`, and its output is isolated,\n * so a file that logs does not report the same lines on both passes.\n * The command line is then parsed knowing those options, and the second run sees the whole option set on `$argv`.\n * The caller's `argv` object receives those arguments too, which is how a caller reads them back.\n * Anything the file does on its way to an export therefore happens twice.\n *\n * {@link execConfigFile} settles which of the two exports is read,\n * and what comes back here is that export merged over a default watch filter and recursive watching, key by key,\n * so a file naming one watch setting keeps the others.\n * A `filter` the file names joins the default list rather than replacing it,\n * since {@link deepMerge} concatenates two arrays.\n * A file that exports nothing still picks up those defaults,\n * while one that is missing or holds no text returns before the merge and comes back as a bare empty object.\n * The result is cast rather than validated, so a file exporting something else entirely reaches the caller unchanged.\n *\n * @example\n * ```ts\n * // the configuration file\n * export const config = { serve: { dir: 'dist', start: true }, watch: { debounce: 50 } };\n *\n * const loaded = await configFileProvider('xbuild.config.ts');\n * loaded.serve; // { dir: 'dist', start: true }\n * loaded.watch; // { filter: [ ... ], recursive: true, debounce: 50 } - the defaults kept\n * ```\n *\n * @see deepMerge\n * @see execConfigFile\n * @see buildFromString\n * @see xBuildConfigInterface\n *\n * @since 3.0.0\n */\n\nexport async function configFileProvider<T extends xBuildConfigInterface>(path: string, argv: Record<string, unknown> = {}): Promise<T> {\n const fileObject = inject(FilesModel).touch(path);\n const text = fileObject.snapshot?.text;\n if (!text) return <T> {};\n\n const [ map, code ] = (await buildFromString(text, path, {\n minify: false,\n format: 'cjs',\n outdir: dirname(path),\n platform: 'node',\n logLevel: 'silent',\n packages: 'external',\n minifySyntax: true,\n minifyWhitespace: true,\n minifyIdentifiers: false\n })).outputFiles!;\n\n const argvService = inject(ArgvModule);\n inject(FrameworkService).addSourceMap(path, map.text, true);\n\n const preConfig = await execConfigFile<T>(code.text, path, {}, true);\n const args = argvService.enhancedParse(process.argv, preConfig.userArgv ?? {});\n\n Object.assign(argv, args);\n const config = await execConfigFile<T>(code.text, path, args);\n\n return deepMerge({} as T, {\n watch: {\n filter: [ '**/*.{js,ts,json}', '!**/*.d.ts' ],\n recursive: true\n }\n }, config as T);\n}\n"],"mappings":"wVAaA,OAAS,UAAAA,OAAc,KCTvB,OAAOC,OAAa,eCSpB,OAAS,UAAAC,OAAc,wBCDvB,OAAS,gBAAAC,GAAc,YAAAC,OAAgB,KACvC,OAAS,WAAAC,OAAe,qBACxB,OAAS,cAAAC,OAAkB,wBA+BpB,IAAMC,EAAN,KAAiB,CAWH,SAAW,IAAI,IAWf,MAAQ,IAAI,IAkB7B,OAAc,CACV,KAAK,MAAM,MAAM,EACjB,KAAK,SAAS,MAAM,CACxB,CAuBA,YAAYC,EAAiD,CACzD,OAAO,KAAK,MAAM,IAAI,KAAK,QAAQA,CAAI,CAAC,CAC5C,CAuBA,MAAMA,EAAcC,EAAkD,CAClE,IAAMC,EAAS,KAAK,QAAQF,CAAI,EAEhC,OAAO,KAAK,MAAM,IAAIE,CAAM,GAAK,KAAK,KAAKA,EAAQ,KAAK,KAAKA,CAAM,EAAGD,CAAQ,CAClF,CA0BA,QAAQD,EAAcG,EAAeF,EAAkD,CACnF,IAAMC,EAAS,KAAK,QAAQF,CAAI,EAEhC,OAAO,KAAK,KAAKE,EAAQC,GAAS,KAAK,KAAKD,CAAM,EAAGD,CAAQ,CACjE,CA6BA,WAAWG,EAA6B,CACpC,IAAMC,EAAWD,GAAS,KAAK,MAAM,KAAK,EAC1C,QAAWJ,KAAQK,EACf,KAAK,QAAQL,CAAI,CAEzB,CAmBA,QAAQA,EAAsB,CAC1B,IAAIE,EAAS,KAAK,SAAS,IAAIF,CAAI,EACnC,OAAIE,IAAW,QAAW,KAAK,SAAS,IAAIF,EAAME,EAASI,GAAQN,CAAI,CAAC,EAEjEE,CACX,CAkBQ,KAAKA,EAAgBK,EAAyBN,EAA2B,QAAgC,CAC7G,IAAMO,EAAQ,KAAK,MAAM,IAAIN,CAAM,EAEnC,OAAKK,GAAM,OAAO,EAMdC,GAAO,UAAYD,EAAK,QAAgBC,EAErC,KAAK,MAAMN,EAAQ,CACtB,QAASK,EAAK,QACd,SAAUC,GAAO,SAAW,GAAK,EACjC,SAAU,KAAK,SAASC,GAAaP,EAAQD,CAAQ,CAAC,CAC1D,CAAC,EAXOO,GAAS,CAACA,EAAM,SAAiBA,EAE9B,KAAK,MAAMN,EAAQ,CAAE,QAAS,EAAG,SAAU,OAAW,SAAUM,GAAO,SAAW,GAAK,CAAE,CAAC,CAUzG,CAiBQ,YAAYE,EAAiBC,EAAkC,CACnE,IAAMC,EAAYF,EAAQ,OACpBG,EAAYF,EAAQ,OACpBG,EAAM,KAAK,IAAIF,EAAWC,CAAS,EAErCE,EAAS,EACb,KAAOA,EAASD,GAAOJ,EAAQ,WAAWK,CAAM,IAAMJ,EAAQ,WAAWI,CAAM,GAAGA,IAElF,IAAIC,EAAS,EACb,KAAOA,EAASF,EAAMC,GAAUL,EAAQ,WAAWE,EAAY,EAAII,CAAM,IAAML,EAAQ,WAAWE,EAAY,EAAIG,CAAM,GAAGA,IAE3H,MAAO,CACH,KAAM,CAAE,MAAOD,EAAQ,OAAQH,EAAYG,EAASC,CAAO,EAC3D,UAAWH,EAAYE,EAASC,CACpC,CACJ,CAeQ,SAASC,EAAkC,CAC/C,MAAO,CACH,KAAAA,EACA,QAAS,CAACC,EAAOC,IAAgBF,EAAK,MAAMC,EAAOC,CAAG,EACtD,UAAW,IAAcF,EAAK,OAC9B,eAAiBG,GACM,KAAK,YAAYA,EAAS,QAAQ,EAAGA,EAAS,UAAU,CAAC,EAAGH,CAAI,CAC3F,CACJ,CAeQ,MAAMf,EAAgBM,EAAqD,CAC/E,YAAK,MAAM,IAAIN,EAAQM,CAAK,EAErBA,CACX,CAcQ,KAAKR,EAAiC,CAC1C,OAAOqB,GAASrB,EAAM,CAAE,eAAgB,EAAM,CAAC,CACnD,CACJ,EApTaD,EAANuB,EAAA,CAHNC,GAAW,CACR,MAAO,WACX,CAAC,GACYxB,GD9Bb,OAAS,gBAAAyB,OAAoB,qBAC7B,OAAS,SAAAC,OAAa,sCENtB,OAAS,OAAAC,OAAW,UACpB,OAAS,gBAAAC,OAAoB,KAE7B,OAAS,UAAAC,GAAQ,cAAAC,OAAkB,wBACnC,OAAS,aAAAC,GAAW,iBAAAC,OAAqB,qBAYzC,IAAMC,GAAuB,sBAavBC,GAAuB,sBAgChBC,EAAN,KAAuB,CAgBjB,cAgBA,cAiBA,YAuBQ,WAAa,IAAI,IAqBlC,aAAc,CACV,KAAK,YAAcC,GAAUC,GAAI,CAAC,EAClC,KAAK,cAAgBD,GAAU,YAAY,QAAQ,EACnD,KAAK,cAAgBA,GAAU,YAAY,OAAO,EAElD,KAAK,cAAc,KAAK,aAAa,CACzC,CAwBA,OAAO,QAAQE,EAAsB,CACjC,OAAQH,EAAiB,QAAUI,GAAOC,CAAU,GAAG,QAAQF,CAAI,CACvE,CA2BA,gBAAgBG,EAAkE,CAC9E,OAAOR,GAAqB,KAAKQ,EAAS,QAAU,EAAE,GAAKR,GAAqB,KAAKQ,EAAS,YAAc,EAAE,CAClH,CAuBA,aAAaH,EAAyC,CAClD,OAAO,KAAK,WAAW,IAAIH,EAAiB,QAAQG,CAAI,CAAC,CAC7D,CAgCA,aAAaA,EAAcI,EAAgBC,EAAiB,GAAa,CACrE,IAAMC,EAAMT,EAAiB,QAAQG,CAAI,EACrC,CAACK,GAAS,KAAK,WAAW,IAAIC,CAAG,GAErC,KAAK,SAASA,EAAKF,CAAM,CAC7B,CA2BA,cAAcJ,EAAoB,CAC9B,GAAI,CAACA,EAAM,OAEX,IAAMM,EAAMT,EAAiB,QAAQG,CAAI,EACzC,GAAI,KAAK,WAAW,IAAIM,CAAG,EAAG,OAE9B,IAAIF,EACJ,GAAI,CACAA,EAASG,GAAa,GAAID,CAAI,OAAQ,OAAO,CACjD,OAASE,EAAO,CACZ,MAAMX,EAAiB,QAAQS,EAAKE,CAAK,CAC7C,CAEA,KAAK,SAASF,EAAKF,CAAM,CAC7B,CAgBA,OAAe,QAAQE,EAAaE,EAAuB,CACvD,OAAO,IAAI,MACP,kCAAmCF,CAAI;AAAA,EAAME,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAE,EACxG,CACJ,CAmBQ,SAASF,EAAaF,EAAsB,CAChD,GAAI,CAAAR,GAAqB,KAAKQ,CAAM,EAEpC,GAAI,CACA,KAAK,WAAW,IAAIE,EAAK,IAAIG,GAAcL,EAAQE,CAAG,CAAC,CAC3D,OAASE,EAAO,CACZ,MAAMX,EAAiB,QAAQS,EAAKE,CAAK,CAC7C,CACJ,CACJ,EAjPIE,GAhESb,EAgEM,SAhENA,EAANc,EAAA,CAHNC,GAAW,CACR,MAAO,WACX,CAAC,GACYf,GFrDb,OAAS,mBAAAgB,OAAuB,sCAChC,OAAS,mBAAAC,OAAuB,yCAChC,OAAS,iBAAAC,OAAqB,2CAgCvB,SAASC,GAAUC,EAAmB,GAA0B,CAEnE,IAAMC,EADYC,GAAOC,CAAgB,EAChB,aAAaH,CAAQ,EAC9C,GAAIC,EAAQ,OAAOA,EAEnB,IAAMG,EAAWF,GAAOG,CAAU,EAAE,MAAML,CAAQ,EAC5CM,EAAOF,EAAS,UAAU,KAEhC,GAAI,CAACA,GAAY,CAACE,EAAM,OAAO,KAC/B,IAAMC,EAAQD,EAAK,MAAM;AAAA,CAAI,EAE7B,MAAO,CACH,oBAAqB,CAACE,EAAMC,EAAQC,EAAOC,IAAY,CACnD,IAAMC,EAAQD,GAAS,YAAc,EAC/BE,EAASF,GAAS,aAAe,EAGjCG,EAAY,KAAK,IAAIN,EAAOK,EAAQ,CAAC,EACrCE,EAAU,KAAK,IAAIP,EAAOI,EAAOL,EAAM,MAAM,EAEnD,MAAO,CACH,KAAAC,EACA,KAAM,KACN,KAAMD,EAAM,MAAMO,EAAY,EAAGC,CAAO,EAAE,KAAK;AAAA,CAAI,EACnD,OAAQf,EACR,OAAQS,EACR,QAAAM,EACA,UAAAD,EACA,WAAY,KACZ,YAAa,GACb,cAAe,GACf,gBAAiB,EACrB,CACJ,CACJ,CACJ,CA+BO,SAASE,GAAcC,EAAiE,CAC3F,OAAIA,aAAe,MAAcrB,GAAgBqB,CAAG,EAChDA,EAAI,kBAAkB,MAAcrB,GAAgBqB,EAAI,MAAM,EAE7DA,EAAI,SAIF,CACH,KAAM,iBACN,QAASA,EAAI,MAAQ,GACrB,SAAU,GACV,MAAO,CACH,CACI,OAAQ,IAAKA,EAAI,SAAS,IAAK,GAC/B,KAAMA,EAAI,SAAS,KACnB,OAAQA,EAAI,SAAS,QAAU,EAC/B,SAAUA,EAAI,SAAS,KACvB,KAAM,GACN,MAAO,GACP,OAAQ,GACR,YAAa,EACjB,CACJ,CACJ,EAnBW,CAAE,MAAO,CAAC,EAAG,KAAM,iBAAkB,QAASA,EAAI,MAAQ,GAAI,SAAU,EAAG,CAoB1F,CAiCO,SAASC,EAAiBD,EAA6BN,EAA+BQ,EAAmB,GAAiC,CAC7I,IAAMC,EAAYlB,GAAOC,CAAgB,EACnCkB,EAASL,GAAcC,CAAG,EAC1BK,EAAqCC,GAAaF,EAAQ,CAC5D,GAAGV,EACH,iBAAkBQ,IAAYR,GAAS,qBAAuB,IAC9D,UAAUa,EAAoC,CAC1C,OAAOzB,GAAUyB,CAAI,CACzB,CACJ,CAAC,EAED,OAAAF,EAAS,MAAM,OAAOG,GAAS,CAC3B,GAAI,EAAEd,GAAS,qBAAuB,KAAUS,EAAU,gBAAgBK,CAAK,EAAG,MAAO,GACtF,CAACH,EAAS,YAAcG,EAAM,OAC7BH,EAAS,WAAazB,GAClB,CACI,KAAMC,GAAc2B,EAAM,IAAI,EAC9B,KAAMA,EAAM,MAAQ,EACpB,OAAQA,EAAM,QAAU,EACxB,UAAWA,EAAM,WAAa,CAClC,EACA,CAAE,MAAOC,GAAM,UAAW,CAC9B,EAER,CAAC,EAEMJ,CACX,CAqCO,SAASK,EAAYC,EAAoCC,EAAcC,EAAiBC,EAAiC,CAAC,EAAW,CACxI,IAAMC,EAAQ,CAAE;AAAA,EAAMH,CAAK,KAAMH,GAAM,WAAWI,CAAO,CAAE,EAAG,EAC9D,QAAWG,KAAQF,GAAS,CAAC,EACtBE,EAAK,MAAMD,EAAM,KAAK;AAAA,GAAQN,GAAM,KAAKO,EAAK,IAAI,CAAC,EAG1D,OAAIL,EAAS,YAAYI,EAAM,KAAK;AAAA;AAAA,EAAQJ,EAAS,UAAW,EAAE,EAC9DA,EAAS,MAAM,QACfI,EAAM,KAAK;AAAA;AAAA;AAAA,MAAmCJ,EAAS,MAAM,IAAIM,GAASA,EAAM,MAAM,EAAE,KAAK;AAAA,KAAQ,CAAE;AAAA,CAAI,EAGxGF,EAAM,KAAK,EAAE,CACxB,CG9MO,IAAeG,EAAf,cAAuC,KAAM,CAYtC,cAaA,eAiBA,YAAYC,EAAiBC,EAAe,kBAAmB,CACrE,MAAMD,CAAO,EAGb,OAAO,eAAe,KAAM,WAAW,SAAS,EAChD,KAAK,KAAOC,EAER,MAAM,mBACN,MAAM,kBAAkB,KAAM,KAAK,WAAW,CAEtD,CAqBA,IAAI,UAAiD,CACjD,OAAO,KAAK,aAChB,CAsBA,CAAC,OAAO,IAAI,4BAA4B,CAAC,GAAwB,CAC7D,OAAO,KAAK,gBAAkB,KAAK,KACvC,CAsBU,cAAcC,EAAcC,EAAqC,CACvE,KAAK,cAAgBC,EAAiBF,EAAOC,CAAO,EACpD,KAAK,eAAiBE,EAAY,KAAK,cAAeH,EAAM,KAAMA,EAAM,OAAO,CACnF,CACJ,EJxIO,SAASI,GAAaC,EAAuB,CAChD,GAAIA,aAAkB,eAAgB,CAClC,QAAQ,MAAM,kBAAmBA,EAAO,OAAO,EAC/C,QAAWC,KAAOD,EAAO,OACrB,GAAIC,aAAe,OAAS,EAAEA,aAAeC,GAAkB,CAC3D,IAAMC,EAAWC,EAAiBH,EAAK,CAAE,oBAAqB,GAAM,iBAAkB,EAAK,CAAC,EAC5F,QAAQ,MAAMI,EAAYF,EAAUF,EAAI,KAAMA,EAAI,OAAO,CAAC,CAC9D,MACI,QAAQ,MAAMA,CAAG,EAIzB,MACJ,CAEA,GAAID,aAAkB,OAAS,EAAEA,aAAkBE,GAAkB,CACjE,IAAMC,EAAWC,EAAiBJ,EAAQ,CAAE,oBAAqB,GAAM,iBAAkB,EAAK,CAAC,EAC/F,QAAQ,MAAMK,EAAYF,EAAUH,EAAO,KAAMA,EAAO,OAAO,CAAC,CACpE,MACI,QAAQ,MAAMA,CAAM,CAE5B,CAuBAM,GAAQ,GAAG,oBAAsBN,GAAoB,CACjDD,GAAaC,CAAM,EACnBM,GAAQ,KAAK,CAAC,CAClB,CAAC,EAuBDA,GAAQ,GAAG,qBAAuBN,GAAoB,CAClDD,GAAaC,CAAM,EACnBM,GAAQ,KAAK,CAAC,CAClB,CAAC,EKhGD,OAAS,QAAAC,OAAY,UCDrB,OAAS,QAAAC,OAAY,gBACrB,UAAYC,OAAc,gBCC1B,OAAS,WAAAC,OAAe,OACxB,OAAS,UAAAC,OAAc,UCVvB,OAAS,SAAAC,OAAa,sCAmBf,IAAMC,GAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BlB,SAASC,IAAmB,CAC/B,MAAO;AAAA,YACEF,GAAM,YAAYC,EAAS,CAAE;AAAA,qBACpBD,GAAM,WAAW,OAAS,CAAE;AAAA,OAElD,CAkBO,SAASG,IAAiB,CAC7B,OAAOH,GAAM,WAAW,UAAU,CACtC,CD7DA,OAAS,YAAAI,OAAgB,qBACzB,OAAS,UAAAC,OAAc,wBACvB,OAAS,aAAAC,OAAiB,sBAC1B,OAAS,YAAAC,GAAU,mBAAAC,OAAuB,WAC1C,OAAS,SAAAC,OAAa,sCEhBtB,OAAS,SAAAC,MAAa,sCAiBf,IAAMC,GAAUD,EAAM,IAAI,SAAS,EAiB7BE,GAAYF,EAAM,IAAI,SAAS,EAiB/BG,EAAYH,EAAM,IAAI,SAAS,EAiB/BI,EAAYJ,EAAM,IAAI,SAAS,EAiB/BK,EAAYL,EAAM,IAAI,SAAS,EAiB/BM,GAAaN,EAAM,IAAI,SAAS,EAiBhCO,EAAeP,EAAM,IAAI,SAAS,EAiBlCQ,EAAaR,EAAM,IAAI,SAAS,ECsHtC,IAAMS,EAAuC,CAAE,QAAS,EAAG,KAAM,EAAG,QAAS,EAAG,MAAO,EAAG,OAAQ,CAAE,EHlNpG,SAASC,EAAmBC,EAAgBC,EAAiBC,EAAU,IAAI,QAAW,EAAW,CACpG,MAAO,GAAIC,GAAO,CAAE,IAAKF,CAAO,IAAKC,EAAUF,CAAM,CAAE,EAC3D,CAoBO,SAASI,GAAQC,EAAsB,CAC1C,OAAOC,GAAUD,CAAI,EAAE,MAC3B,CAwBO,SAASE,EAAIF,EAAcG,EAAsB,CACpD,OAAOH,EAAO,IAAI,OAAO,KAAK,IAAI,EAAGG,EAAOJ,GAAQC,CAAI,CAAC,CAAC,CAC9D,CA0BO,SAASI,GAAWC,EAAsB,CAC7C,GAAIA,EAAK,SAAS,KAAK,EAAG,OAAOA,EACjC,IAAMC,EAAWD,EAAK,WAAW,GAAG,EAC9BE,GAAQC,GAAOC,CAAgB,EAAE,cAAeJ,CAAI,EACpDI,EAAiB,QAAQJ,CAAI,EAEnC,OAAOK,GAAS,QAAQ,IAAI,EAAGJ,CAAQ,CAC3C,CAoBO,SAASK,GAAeN,EAAeO,EAAe,EAAGC,EAAiB,EAAW,CACxF,GAAI,CAACR,EAAM,MAAO,GAClB,IAAMS,EAAYC,EAAW,IAAI,GAAG,EAEpC,MAAO,GAAIC,EAAUZ,GAAWC,CAAI,CAAC,CAAE,GAAIS,CAAU,GAAIG,EAAU,OAAOL,CAAI,CAAC,CAAE,GAAIE,CAAU,GAAIG,EAAU,OAAOJ,CAAM,CAAC,CAAE,EACjI,CAiBO,SAASK,GAAaC,EAAoCC,EAA+B,CAC5F,IAAMC,EAAO,GAAI,QAAQ,IAAI,CAAE,IACzBC,EAAuB,CAAC,EAE9B,OAAIH,EAAS,YACTG,EAAM,KAAK,GAAI,GAAGH,EAAS,WAAW,MAAM;AAAA,CAAI,EAAE,IAAIP,GAAQ,GAAIQ,CAAO,GAAIG,GAAM,IAAIX,CAAI,CAAE,EAAE,CAAC,EAEhGO,EAAS,MAAM,OAAS,GAAGG,EAAM,KAAK,GAAI,GAAGH,EAAS,MAAM,IAAIK,GACzD,GAAIJ,CAAO,GAAIL,EAAW,IAAIS,EAAM,OAAO,WAAWH,EAAM,EAAE,CAAC,CAAE,EAC3E,CAAC,EAEKC,EAAM,OAAS,EAAI,CAAE,GAAGA,EAAO,EAAG,EAAIA,CACjD,CA8BO,SAASG,GAAgBC,EAAyBC,EAAoC,CACzF,IAAMC,EAAaF,EAAQ,IAAI,WAAW,IAAI,GAAK,GAC7CP,EAAWS,GAAc,CAACD,EAC1B,OACAE,EAAiBH,EAAS,CAAE,WAAY,EAAG,YAAa,EAAG,oBAAqB,EAAK,CAAC,EAEtFF,EAAQI,EAAa,OAAYT,GAAU,MAAM,CAAC,EAClDW,EAAQN,GAASE,EAAQ,SAE/B,MAAO,CACH,GAAIA,EAAQ,IAAM,GAClB,OAAQC,GAAQR,EAAWD,GAAaC,EAAU,MAAO,OAAO,CAAC,CAAC,EAAI,CAAC,EACvE,SAAUR,GAAea,GAAO,UAAYE,EAAQ,UAAU,KAAMI,GAAO,KAAMA,GAAO,MAAM,CAClG,CACJ,CA2BO,SAASC,GACZC,EAAiCC,EAAeC,EAA0BtC,EAAgB+B,EAAO,GAC7F,CACJ,GAAIK,EAAS,OAAS,EAAG,OAEzB,IAAIG,EAAO,EACPC,EAAS,EACPC,EAAmC,CAAC,EAE1C,QAAWX,KAAWM,EAAU,CAC5B,IAAMM,EAAMb,GAAgBC,EAASC,CAAI,EACzCQ,EAAO,KAAK,IAAIA,EAAMpC,GAAQuC,EAAI,QAAQ,CAAC,EAC3CF,EAAS,KAAK,IAAIA,EAAQE,EAAI,GAAG,MAAM,EACvCD,EAAK,KAAKC,CAAG,CACjB,CAEA,IAAMhB,EAAQ,CAAE;AAAA,GAAOY,EAAMD,CAAK,CAAE,IAAKlB,EAAW,IAAI,IAAKsB,EAAK,MAAO,GAAG,CAAE,EAAG,EACjF,OAAW,CAAEE,EAAO,CAAE,GAAAC,EAAI,SAAAC,EAAU,OAAAC,CAAO,CAAC,IAAKL,EAAK,QAAQ,EAAG,CAC7D,IAAMM,EAAMP,EAAS,EAAI,GAAIlC,EAAIgC,EAAMM,CAAE,EAAGJ,CAAM,CAAE,KAAO,GAE3Dd,EAAM,KAAK,GAAI,KAAO,GAAIY,EAAMtC,CAAM,CAAE,IAAKM,EAAIuC,EAAUN,CAAI,CAAE,KAAMQ,CAAI,GAAI5B,EAAWiB,EAASO,CAAK,EAAE,MAAQ,EAAE,CAAE,EAAE,EACxHjB,EAAM,KAAK,GAAGoB,CAAM,CACxB,CAEA,QAAQ,IAAIpB,EAAM,KAAK;AAAA,CAAI,CAAC,CAChC,CAWO,SAASsB,IAAoB,CAChC,IAAMP,EAAO,KAAK,IAAI,EAAGQ,GAAO,KAAO,CAAC,EACpCR,EAAO,GAAG,QAAQ,IAAI;AAAA,EAAK,OAAOA,CAAI,CAAC,EAE3CS,GAASD,GAAQ,EAAG,CAAC,EACrBE,GAAgBF,EAAM,CAC1B,CAUO,SAASG,IAAgB,CAC5B,OAAOH,GAAO,SAAW,GAC7B,CAiBO,SAASI,GAAWC,EAAuB,CAC9C,OAAIA,EAAQ,KAAiB,GAAIA,CAAM,KACnCA,EAAQ,QAAiB,IAAKA,EAAQ,MAAU,QAAQ,CAAC,CAAE,MAExD,IAAKA,EAAQ,SAAU,QAAQ,CAAC,CAAE,KAC7C,CAwBO,SAASC,GAAaC,EAAoBC,EAAgB,EAAmB,CAChF,IAAMC,EAAU,OAAO,QAAQF,EAAS,OAAO,EAAE,KAC7C,CAAC,CAAE,CAAEG,CAAE,EAAG,CAAE,CAAEC,CAAE,IAAMA,EAAE,MAAQD,EAAE,KACtC,EAEA,GAAID,EAAQ,OAAS,EAAG,OACxB,IAAMG,EAASH,EAAQ,MAAM,EAAGD,CAAK,EAC/BK,EAAQD,EAAO,IAAI,CAAC,CAAE,CAAE,CAAE,MAAAP,CAAM,CAAC,IAAMD,GAAWC,CAAK,CAAC,EACxDS,EAAQ,KAAK,IAAI,GAAGD,EAAM,IAAIvD,GAAQA,EAAK,MAAM,CAAC,EAClDyD,EAAQN,EAAQ,OAAO,CAACO,EAAK,CAAE,CAAE,CAAE,MAAAX,CAAM,CAAC,IAAMW,EAAMX,EAAO,CAAC,EAE9DY,EAAOd,GAAM,EAAI,MAAO,OAASW,EAAQ,EACzCI,EAAS,IAAKC,GAAQ,SAAS,CAAE,IAAKjD,EAAW,IAAI,IAAKuC,EAAQ,MAAO,GAAG,CAAE,GAC9EhC,EAAQ,CAAE;AAAA,EAAMpB,EAAI6D,EAAQf,GAAM,EAAIW,EAAQ,CAAC,CAAE,GAAI1C,EAAU,IAAIgC,GAAWW,CAAK,CAAC,CAAE,EAAG,EAE/F,OAAW,CAAErB,EAAO,CAAE0B,CAAK,CAAC,IAAKR,EAAO,QAAQ,EAC5CnC,EAAM,KACF,GAAI,KAAO,GAAIzB,EAAU,IAAI,QAAW,CAAE,IAAKK,EAAIc,EAAUiD,CAAI,EAAGH,EAAO,CAAC,CAAE,GAC5E7C,EAAU,IAAIyC,EAAMnB,CAAK,EAAE,SAASoB,CAAK,CAAC,CAChD,EAEJ,GAAIL,EAAQ,OAASD,EAAO,CACxB,IAAMa,EAAOZ,EAAQ,MAAMD,CAAK,EAAE,OAAO,CAACQ,EAAK,CAAE,CAAE,CAAE,MAAAX,CAAM,CAAC,IAAMW,EAAMX,EAAO,CAAC,EAC1EiB,EAAOpD,EAAW,IAAI,GAAI,MAAU,IAAKuC,EAAQ,OAASD,CAAM,OAAO,EAC7E/B,EAAM,KAAK,GAAI,KAAO,KAAMpB,EAAIiE,EAAML,EAAO,CAAC,CAAE,GAAI7C,EAAU,IAAIgC,GAAWiB,CAAI,EAAE,SAASP,CAAK,CAAC,CAAE,EAAE,CAC1G,CAEA,QAAQ,IAAIrC,EAAM,KAAK;AAAA,CAAI,CAAC,CAChC,CDlXA,OAAS,YAAA8C,GAAU,SAAAC,EAAO,UAAAC,EAAQ,QAAAC,OAAY,UAC9C,OAAS,SAAAC,OAAa,sCACtB,OAAS,QAAAC,EAAM,cAAAC,GAAY,YAAAC,MAAgB,sBAC3C,OAAS,kBAAAC,OAAsB,qCAa/B,IAAMC,GAAuC,CAAE,OAAQ,OAAQ,MAAO,OAAQ,EAYxEC,GAAO,CACT,CAAE,IAAK,IAAK,SAAU,iBAAkB,OAAQ,EAAM,EACtD,CAAE,IAAK,IAAK,SAAU,gBAAiB,OAAQ,EAAM,EACrD,CAAE,IAAK,IAAK,SAAU,qBAAsB,OAAQ,EAAM,EAC1D,CAAE,IAAK,IAAK,SAAU,iBAAkB,OAAQ,EAAM,EACtD,CAAE,IAAK,IAAK,SAAU,mBAAoB,OAAQ,EAAM,EACxD,CAAE,IAAK,IAAK,SAAU,uBAAwB,OAAQ,EAAK,EAC3D,CAAE,IAAK,IAAK,SAAU,OAAQ,OAAQ,EAAM,CAChD,EAYIC,EAQAC,GAAW,GAgBXC,EAQAC,GAkBJ,SAASC,IAA6B,CAClC,OAAO,IAAI,QAAQC,GAAW,CAC1B,IAAMC,EAAUC,GAAuB,CACnC,IAAMC,EAAW,eAAe,KAAKD,EAAK,SAAS,CAAC,EAC/CC,IAELC,EAAM,IAAI,OAAQH,CAAM,EACxBD,EAAQ,OAAOG,EAAS,CAAC,CAAC,CAAC,EAC/B,EAEAC,EAAM,GAAG,OAAQH,CAAM,EACvBI,EAAS,SAAW,EACpB,WAAW,KAAOD,EAAM,IAAI,OAAQH,CAAM,EAAGD,EAAQM,EAAO,IAAI,GAAI,GAAa,EAAE,MAAM,CAC7F,CAAC,CACL,CAmBO,SAASC,GAAcC,EAAmB,CAC7CC,GAAK,GAAIhB,GAAaiB,EAAQ,GAAK,UAAW,IAAKF,CAAI,EAAE,CAC7D,CAoBO,SAASG,IAAmB,CAC/B,IAAMC,EAAQ,CAAE;AAAA,YAASC,EAAa,WAAW,CAAE,EAAG,EACtD,OAAW,CAAE,IAAAC,EAAK,SAAAC,EAAU,OAAAC,CAAO,IAAKtB,IAChC,CAACsB,GAAUrB,GAAS,MACpBiB,EAAM,KAAK,GAAI,KAAO,GAAIK,EAAW,IAAI,OAAO,CAAE,IAAKC,GAAM,KAAKJ,CAAG,CAAE,IAAKG,EAAW,IAAI,MAAOF,CAAS,EAAE,CAAE,EAAE,EAGzH,MAAO,GAAIH,EAAM,KAAK;AAAA,CAAI,CAAE;AAAA,CAChC,CAuBO,SAASO,GAAcC,EAAQ,GAAa,CAC/C,GAAI,CAACvB,EAAK,OAEV,IAAMwB,EAAQ,CAAEzB,IAAY,GAAI0B,EAAU,IAAI,QAAY,CAAE,IAAKL,EAAW,UAAU,CAAE,EAAG,EACvFtB,GAAS,KAAK0B,EAAM,KAAKE,EAAU5B,EAAQ,GAAG,CAAC,EAC/CA,GAAS,WAAa,WAAW0B,EAAM,KAAKR,EAAa,SAAS,CAAC,EACvEQ,EAAM,KAAKJ,EAAW,IAAI,uBAAuB,CAAC,EAElDZ,EAASmB,EAAK,WAAW,EACzB3B,EAAI,UAAU,EAAG,EAAG,IAAKwB,EAAM,KAAKJ,EAAW,IAAI,IAAK,MAAU,GAAG,CAAC,CAAE,GAAI,EAAI,EAChFpB,EAAI,OAAOuB,CAAK,EAChBf,EAASmB,EAAK,cAAc,CAChC,CAgBO,SAASC,GAAYC,EAAoB,CAC5C9B,GAAW8B,EACXP,GAAc,CAClB,CA+BA,eAAsBQ,GAAiBC,EAA+B,CAClE,GAAI,CAACxB,EAAM,OAAS,CAACE,EAAO,OAASR,GAAS,OAC9CH,EAAUiC,EAEVxB,EAAM,WAAW,EAAI,EACrBC,EAASmB,EAAK,WAAW,EAEzB,IAAMK,EAAU,MAAM9B,GAAU,EAC5B8B,GAAWvB,EAAO,MAAMD,EAAS;AAAA,CAAI,EACzCyB,GAAS,KAAK,IAAID,EAASvB,EAAO,KAAO,CAAC,CAAC,EAElC,sBAAmBF,CAAK,EACjCA,EAAM,GAAG,WAAY,CAAC2B,EAAGjB,IAAakB,GAAUlB,CAAG,CAAC,EAEpDR,EAAO,GAAG,SAAU,IAAMwB,GAAS,CAAC,EACpChC,GAAU,YAAY,IAAMqB,GAAc,EAAI,EAAG,GAAe,EAAE,MAAM,EACxE,QAAQ,GAAG,OAAQc,EAAe,CACtC,CAYO,SAASA,IAAwB,CAC/BnC,KAEL,cAAcA,EAAO,EACrBA,GAAU,OACVD,EAAM,OAENQ,EAAS,SAAY6B,GAAW5B,EAAO,KAAM,CAAC,CAAE,GAAIkB,EAAK,UAAW,GAAIA,EAAK,WAAY,EAAE,EAC/F,CAmBA,SAASM,GAASK,EAAuB,CACrC,GAAI7B,EAAO,KAAO,EACd,OAAAT,EAAM,OAECQ,EAAS,SAAYmB,EAAK,UAAW,EAAE,EAGlD,IAAMY,EAAO9B,EAAO,KAAO,EACrB+B,EAAOF,IAAW,OAAYX,EAAK,eAAiBU,GAAWC,EAAQ,CAAC,EAE9EtC,EAAM,IAAIyC,GAAe,EAAGC,GAAM,EAAGH,EAAM,CAAC,EAC5C/B,EACI,GAAImB,EAAK,WAAY,UAAaY,CAAK,IACjCF,GAAW5B,EAAO,KAAM,CAAC,CAAE,GAAIkB,EAAK,UAAW,GAAIa,CAAK,EAClE,EAEAlB,GAAc,EAAI,CACtB,CAqBA,eAAea,GAAUlB,EAAyB,CAG9C,OAFIA,EAAI,OAASA,EAAI,OAAS,KAAOA,EAAI,OAAS,OAAMA,EAAI,KAAO,KAE3DA,EAAI,KAAM,CACd,IAAK,IACDmB,GAAgB,EAChB3B,EAAO,MAAM,GAAIW,EAAW,UAAU,CAAE;AAAA,EAAM,IAAMuB,GAAK,QAAQ,SAAW,OAAO,QAAQ,QAAQ,EAAI,CAAC,CAAC,EAEzG,OACJ,IAAK,IACD,OAAAC,GAAY,EAELtB,GAAc,EAAI,EAC7B,IAAK,IACD,OAAO,QAAQ,IAAIR,GAAS,CAAC,EACjC,IAAK,IACD,OAAAhB,GAAS,cAAc,EAEhBwB,GAAc,EAAI,EAC7B,IAAK,IACGxB,GAAS,KAAKY,GAAcZ,EAAQ,GAAG,EAE3C,OACJ,IAAK,IACD,OAAOA,GAAS,QAAQ,YAAY,EACxC,IAAK,IACD,OAAOA,GAAS,QAAQ,YAAa,EAAI,CACjD,CACJ,CDhXA,OAAS,cAAA+C,GAAY,UAAAC,OAAc,wBMDnC,OAAS,cAAAC,OAAkB,wBAC3B,OAAS,mBAAAC,OAAuB,4BCUzB,SAASC,GAASC,EAAgD,CACrE,MAAO,CAAC,CAACA,GAAQ,OAAOA,GAAS,UAAY,CAAC,MAAM,QAAQA,CAAI,CACpE,CA+BO,SAASC,GAAcD,EAAgD,CAC1E,GAAI,CAACD,GAASC,CAAI,EAAG,MAAO,GAC5B,IAAME,EAAY,OAAO,eAAeF,CAAI,EAE5C,OAAOE,IAAc,MAAQ,OAAO,eAAeA,CAAS,IAAM,IACtE,CAmCO,SAASC,EAA4BC,KAAcC,EAA2B,CACjF,GAAI,CAACA,EAAQ,OAAQ,OAAOD,EAC5B,IAAME,EAASD,EAAQ,MAAM,EAE7B,GAAIN,GAASK,CAAM,GAAKL,GAASO,CAAM,EAAG,CACtC,QAAWC,KAAOD,EAAQ,CACtB,IAAME,EAAcF,EAAOC,CAAG,EACxBE,EAAcL,EAAOG,CAAG,EAE1B,MAAM,QAAQC,CAAW,GAAK,MAAM,QAAQC,CAAW,EACvD,OAAO,OAAOL,EAAQ,CAAE,CAACG,CAAG,EAAG,CAAE,GAAGE,EAAa,GAAGD,CAAY,CAAE,CAAC,EAC5DP,GAAcO,CAAW,EAChC,OAAO,OAAOJ,EAAQ,CAClB,CAACG,CAAG,EAAGJ,EACHF,GAAcQ,CAAW,EAAIA,EAAc,CAAC,EAC5CD,CACJ,CACJ,CAAC,EAED,OAAO,OAAOJ,EAAQ,CAAE,CAACG,CAAG,EAAGC,CAAY,CAAC,CAEpD,CAEA,OAAOL,EAAUC,EAAQ,GAAGC,CAAO,CACvC,CAEA,OAAOD,CACX,CA+BO,SAASM,GAAOC,EAAYC,EAAYC,EAAc,GAAe,CAExE,OADIF,IAAMC,GACN,OAAO,GAAGD,EAAGC,CAAC,EAAU,GACxBD,IAAM,MAAQC,IAAM,KAAa,GAEjCD,aAAa,MAAQC,aAAa,KAC3BD,EAAE,QAAQ,IAAMC,EAAE,QAAQ,EAEjCD,aAAa,QAAUC,aAAa,OAC7BD,EAAE,SAAWC,EAAE,QAAUD,EAAE,QAAUC,EAAE,MAE9C,KAAOD,aAAa,KAAOC,aAAa,IACjCD,EAAE,OAASC,EAAE,KAEpB,OAAOD,GAAM,UAAY,OAAOC,GAAM,SAC/BE,GAAWH,EAAGC,EAAGC,CAAW,EAGhC,EACX,CA0BO,SAASE,GAAOC,EAAcT,EAA+B,CAChE,OAAIS,GAAO,MAAS,OAAOA,GAAQ,UAAY,OAAOA,GAAQ,WACnD,GAEJT,KAAOS,GAAO,OAAO,UAAU,eAAe,KAAKA,EAAKT,CAAG,CACtE,CAmBA,SAASO,GAAWH,EAAWC,EAAWC,EAAuB,GAAe,CAC5E,GAAI,MAAM,QAAQF,CAAC,GAAK,MAAM,QAAQC,CAAC,EACnC,OAAGC,GAAeF,EAAE,SAAWC,EAAE,OAAe,GAEzCD,EAAE,MAAM,CAACM,EAAKC,IAAMR,GAAOO,EAAKL,EAAEM,CAAC,EAAGL,CAAW,CAAC,EAG7D,IAAMM,EAAQ,OAAO,KAAKR,CAAC,EACrBS,EAAQ,OAAO,KAAKR,CAAC,EAC3B,GAAIC,GAAeM,EAAM,SAAWC,EAAM,OAAQ,MAAO,GAEzD,QAAWb,KAAOY,EAEd,GADI,CAACJ,GAAOH,EAAGL,CAAG,GACd,CAACG,GAAQC,EAA8BJ,CAAG,EAAIK,EAA8BL,CAAG,EAAGM,CAAW,EAC7F,MAAO,GAIf,MAAO,EACX,CAgCO,SAASQ,GAAUC,EAAwB,CAC9C,OAAO,KAAK,UAAUA,EAAO,CAACC,EAAGC,IAAU,OAAOA,GAAU,SAAWA,EAAM,SAAS,EAAI,IAAMA,CAAK,CACzG,CDrQA,OAAS,OAAAC,GAAK,wBAAAC,OAA4B,4BEWnC,IAAMC,GAAiD,OAAO,OAAO,CACxE,OAAQ,OAAO,OAAO,CAClB,MAAO,GACP,YAAa,CAAC,EACd,YAAa,GACb,QAAS,OAAO,OAAO,CACnB,MAAO,GACP,OAAQ,GACR,OAAQ,GACR,OAAQ,MACR,OAAQ,OACR,SAAU,UACV,cAAe,QAAQ,IAAI,EAC3B,cAAe,MACnB,CAAC,CACL,CAAC,CACL,CAAC,EFQM,IAAMC,EAAN,KAA+F,CAiClG,YAAoBC,EAAmBC,GAA2B,CAA9C,mBAAAD,EAChB,KAAK,QAAU,IAAIE,GAAmBC,EAAU,CAAC,EAAGH,CAAa,CAAM,CAC3E,CAFoB,cAtBH,QAuEjB,SAAYI,EAAoC,CAC5C,OAAKA,EAGEA,EAAS,KAAK,QAAQ,KAAK,EAFvB,KAAK,QAAQ,KAG5B,CAwBA,UAAUC,EAA+C,CACrD,OAAO,KAAK,QAAQ,UAAUA,CAAQ,CAC1C,CA4BA,OAAUD,EAA2C,CACjD,OAAO,KAAK,QAAQ,KAChBE,GAAIF,CAAQ,EACZG,GAAqB,CAACC,EAAMC,IAASC,GAAOF,EAAMC,CAAI,CAAC,CAC3D,CACJ,CAuBA,MAAME,EAAmC,CACrC,IAAMC,EAAeT,EACjB,CAAC,EACD,KAAK,QAAQ,MACbQ,CACJ,EAEA,KAAK,QAAQ,KAAKC,CAAY,CAClC,CAyBA,OAAOC,EAAkC,CACrC,KAAK,QAAQ,KAAKV,EAAU,CAAC,EAAG,KAAK,cAAeU,CAAM,CAAM,CACpE,CACJ,EA7Mad,EAANe,EAAA,CAHNC,GAAW,CACR,MAAO,WACX,CAAC,GACYhB,GGpCb,OAAOiB,MAAQ,aACf,OAAS,cAAAC,OAAkB,wBAC3B,OAAS,aAAAC,GAAW,YAAAC,GAAU,WAAAC,OAAe,qBCD7C,OAAS,cAAAC,OAAkB,KAC3B,OAAS,aAAAC,OAAiB,aAC1B,OAAS,UAAAC,OAAc,wBACvB,OAAS,SAAAC,GAAO,aAAAC,OAAiB,cAGjC,OAAS,QAAAC,GAAM,WAAAC,GAAS,YAAAC,OAAgB,qBCmBjC,SAASC,EAAWC,EAAYC,EAAiBC,EAAyC,CAC7F,IAAIC,EAASH,EAAK,IAElB,KAAOG,EAASF,EAAQ,QAAQ,CAC5B,IAAMG,EAAOH,EAAQ,WAAWE,CAAM,EACtC,GAAIC,IAAS,IAAcA,IAAS,EAAU,MAC9CD,GACJ,CACIF,EAAQ,WAAWE,CAAM,IAAM,IAASA,IACxCF,EAAQ,WAAWE,CAAM,IAAM,IAASA,IAE5CD,EAAM,KAAK,CAAE,MAAOF,EAAK,MAAO,IAAKG,CAAO,CAAC,CACjD,CA4BO,SAASE,EAAWJ,EAAiBC,EAA2C,CACnF,GAAIA,EAAM,OAAS,EAAG,OAAOD,EAC7BC,EAAM,KAAK,CAACI,EAAMC,IAAUD,EAAK,MAAQC,EAAM,KAAK,EAEpD,IAAMC,EAAuB,IAAI,MAAMN,EAAM,OAAS,EAAI,CAAC,EACvDO,EAAQ,EACRN,EAAS,EAEb,QAASO,EAAI,EAAGA,EAAIR,EAAM,OAAQQ,IAAK,CACnC,IAAMC,EAAOT,EAAMQ,CAAC,EAChBC,EAAK,MAAQR,IACjBK,EAAMC,GAAO,EAAIR,EAAQ,MAAME,EAAQQ,EAAK,KAAK,EACjDH,EAAMC,GAAO,EAAIE,EAAK,MAAQ,GAC9BR,EAASQ,EAAK,IAClB,CAEA,OAAAH,EAAMC,GAAO,EAAIR,EAAQ,MAAME,CAAM,EACrCK,EAAM,OAASC,EAERD,EAAM,KAAK,EAAE,CACxB,CA6BO,SAASI,GAAQC,EAA8BC,EAAgBZ,EAAmCa,EAA6B,CAClI,GAAI,CAACF,EAAQ,OAEb,IAAMG,EAAWD,EAAG,QAAQF,EAAO,MAAOC,CAAM,EAChD,GAAI,CAACE,GAAYA,EAAS,wBAAyB,OACnD,GAAM,CAAE,UAAAC,EAAW,iBAAAC,CAAiB,EAAIF,EAClCG,EAAOF,EAAYC,EAAiB,MAAM,EAAG,CAACD,EAAU,MAAM,EAAIC,EAExEhB,EAAM,KAAK,CAAE,IAAKW,EAAO,IAAK,MAAOA,EAAO,MAAO,KAAM,IAAKM,CAAK,MAAO,CAAC,CAC/E,CAoCO,SAASC,GAAcC,EAAoBP,EAAgBb,EAAkB,GAAIc,EAA+B,CACnH,GAAG,CAACd,EAAS,OAAOA,EACpB,IAAMC,EAAoC,CAAC,EAE3C,QAAWoB,KAAaD,EAAM,QAAQ,KAClC,OAAQC,EAAU,KAAM,CACpB,IAAK,oBACL,IAAK,uBACL,IAAK,yBACDV,GAAQU,EAAU,OAAQR,EAAQZ,EAAOa,CAAE,EAC3C,MAEJ,IAAK,4BACGO,EAAU,gBAAgB,OAAS,6BACnCV,GAAQU,EAAU,gBAAgB,WAAYR,EAAQZ,EAAOa,CAAE,CAC3E,CAGJ,OAAOV,EAAWJ,EAASC,CAAK,CACpC,CCzKO,IAAMqB,GAA0B;AAAA;AAAA;AAAA;EFgChC,IAAMC,GAAN,KAAuB,CA0D1B,YAA6BC,EAAuB,CAAvB,QAAAA,CAAwB,CAAxB,GAxCpB,MAAQ,IAAI,IAQJ,WAAaC,GAAOC,CAAU,EAe9B,QAAU,IAAI,IAyC/B,OAAc,CACV,KAAK,MAAM,MAAM,EACjB,KAAK,QAAQ,MAAM,CACvB,CA4BA,MAAMC,EAAyC,CAC3C,IAAMC,EAAS,KAAK,WAAW,QAAQD,CAAI,EACrCE,EAAO,KAAK,WAAW,MAAMD,CAAM,EACnCE,EAAS,KAAK,MAAM,IAAIF,CAAM,EAEpC,GAAIE,GAAQ,UAAYD,EAAK,QAAS,OAAOC,EAE7C,IAAMC,EAAQ,KAAK,MAAMH,EAAQC,EAAK,OAAO,EAC7C,YAAK,MAAM,IAAID,EAAQG,CAAK,EAErBA,CACX,CAiCA,MAAM,KAAKC,EAAqCC,EAAyC,CACrF,IAAMC,EAAyB,CAAC,EAC1BC,EAA0B,CAAC,EAC3BC,EAAU,IAAI,IACdC,EAAQ,IAAI,IAElB,OAAW,CAAEC,EAAMP,CAAM,IAAK,OAAO,QAAQC,CAAW,EACpDK,EAAM,IAAI,KAAK,WAAW,QAAQN,CAAK,EAAGO,CAAI,EAElD,IAAMC,EAAU,CAAE,GAAGF,EAAM,KAAK,CAAE,EAClC,KAAOE,EAAQ,OAAS,GAAG,CACvB,IAAMX,EAASW,EAAQ,IAAI,EAC3B,GAAIH,EAAQ,IAAIR,CAAM,GAAKA,EAAO,SAAS,OAAO,EAAG,SACrDQ,EAAQ,IAAIR,CAAM,EAElB,IAAMG,EAAQ,KAAK,MAAMH,CAAM,EAC/B,QAAWY,KAAcT,EAAM,oBACtBK,EAAQ,IAAII,CAAU,GAAGD,EAAQ,KAAKC,CAAU,EAEzD,IAAMC,EAAS,KAAK,WAAWb,EAAQK,EAAQI,EAAM,IAAIT,CAAM,CAAC,EAC5D,KAAK,QAAQ,IAAIa,CAAM,IAAMV,EAAM,SAAWW,GAAWD,CAAM,IAEnE,KAAK,QAAQ,IAAIA,EAAQV,EAAM,OAAO,EACtCG,EAAQ,KAAKO,CAAM,EACnBN,EAAS,KAAKJ,EAAM,WAAW,EACnC,CAEA,OAAO,KAAK,MAAMG,EAASC,CAAQ,CACvC,CA2BA,MAAM,WAAWH,EAAqCC,EAAyC,CAC3F,IAAMU,EAAU,KAAK,GAAG,OAAO,QACzBC,EAAO,KAAK,WAAW,QAAQX,GAAUU,EAAQ,gBAAkBA,EAAQ,QAAU,GAAG,EAE9F,OAAO,KAAK,MACR,OAAO,KAAKX,CAAW,EAAE,IAAIM,GAAQO,GAAKD,EAAM,GAAIN,CAAK,OAAO,CAAC,EACjE,OAAO,OAAON,CAAW,EAAE,IAAID,GAAS,KAAK,OAAOA,CAAK,CAAC,CAC9D,CACJ,CAkBQ,OAAOA,EAAuB,CAClC,IAAMH,EAAS,KAAK,WAAW,QAAQG,CAAK,EACtCe,EAAO,KAAK,MAAMlB,CAAM,EAE9B,OAAO,KAAK,OAAO,KAAK,eAAeA,EAAQkB,CAAI,EAAG,KAAK,eAAelB,EAAQkB,CAAI,CAAC,CAC3F,CAgBA,MAAc,MAAMZ,EAAwBC,EAAiD,CACzF,GAAID,EAAQ,OAAS,EAAG,OAAOA,EAE/B,IAAMa,EAAc,IAAI,IAAIb,EAAQ,IAAIO,GAAUO,GAAQP,CAAM,CAAC,CAAC,EAClE,aAAM,QAAQ,IAAI,CAAE,GAAGM,CAAY,EAAE,IAAIE,GAAaC,GAAMD,EAAW,CAAE,UAAW,EAAK,CAAC,CAAC,CAAC,EAC5F,MAAM,QAAQ,IAAIf,EAAQ,IAAI,CAACO,EAAQU,IAAUC,GAAUX,EAAQN,EAASgB,CAAK,EAAG,OAAO,CAAC,CAAC,EAEtFjB,CACX,CAsBQ,WAAWmB,EAAgBpB,EAAiBK,EAAuB,CACvE,GAAM,CAAE,eAAAgB,EAAgB,OAAAC,EAAQ,QAAAC,CAAQ,EAAI,KAAK,GAAG,OAAO,QACrDZ,EAAOX,GAAUqB,GAAkBC,EACnC3B,EAASgB,EAAO,KAAK,WAAW,QAAQA,CAAI,EAAII,GAAQK,CAAM,EACpE,GAAIf,EAAM,OAAOO,GAAKjB,EAAQ,GAAIU,CAAK,OAAO,EAE9C,IAAMmB,EAAOD,EAAU,KAAK,WAAW,QAAQA,CAAO,EAAIR,GAAQK,CAAM,EAExE,OAAOR,GAAKjB,EAAQ8B,GAASD,EAAMJ,CAAM,EAAE,QAAQ,iBAAkB,SAAS,CAAC,CACnF,CAkBQ,eAAezB,EAAgBG,EAAoE,CACvG,IAAMK,EAAU,IAAI,IAAY,CAAER,CAAO,CAAC,EACpC+B,EAA4C,CAAC,EAC7CpB,EAAU,CAAE,GAAGR,EAAM,mBAAoB,EAE/C,KAAOQ,EAAQ,OAAS,GAAG,CACvB,IAAMC,EAAaD,EAAQ,IAAI,EAC/B,GAAIH,EAAQ,IAAII,CAAU,EAAG,SAC7BJ,EAAQ,IAAII,CAAU,EAEtB,IAAMM,EAAO,KAAK,MAAMN,CAAU,EAClCmB,EAAQ,KAAKb,CAAI,EAEjB,QAAWc,KAAUd,EAAK,oBACjBV,EAAQ,IAAIwB,CAAM,GAAGrB,EAAQ,KAAKqB,CAAM,CACrD,CAEA,OAAAD,EAAQ,KAAK5B,CAAK,EAEX4B,CACX,CAoBQ,eAAe/B,EAAgBG,EAA0D,CAC7F,IAAM8B,EAAU,IAAI,IACdC,EAAa,IAAI,IACjB1B,EAAU,IAAI,IAAY,CAAER,CAAO,CAAC,EACpCW,EAAU,CAAER,CAAM,EAExB,KAAOQ,EAAQ,OAAS,GAAG,CACvB,IAAMO,EAAOP,EAAQ,IAAI,EACzB,QAAWwB,KAAWjB,EAAK,eAAe,QAASe,EAAQ,IAAI,KAAK,OAAOE,CAAO,CAAC,EAEnF,OAAW,CAAEC,EAAQC,CAAS,IAAK,OAAO,QAAQnB,EAAK,cAAc,EAAG,CAChEmB,EAAS,MAAMH,EAAW,IAAI,kBAAmBE,CAAO,IAAI,EAC5DC,EAAS,OAAO,QAChBH,EAAW,IAAI,YAAaG,EAAS,MAAM,IAAIF,GAAW,KAAK,OAAOA,CAAO,CAAC,EAAE,KAAK,IAAI,CAAE,YAAaC,CAAO,IAAI,EAEvH,QAAW1B,KAAQ2B,EAAS,YAAc,CAAC,EAAGH,EAAW,IAAI,eAAgBxB,CAAK,UAAW0B,CAAO,IAAI,CAC5G,CAEA,QAAWE,KAAQpB,EAAK,eAAe,KAC/BV,EAAQ,IAAI8B,CAAI,IACpB9B,EAAQ,IAAI8B,CAAI,EAChB3B,EAAQ,KAAK,KAAK,MAAM2B,CAAI,CAAC,EAErC,CAEA,MAAO,CAAE,QAAAL,EAAS,WAAAC,CAAW,CACjC,CAgBQ,aAAaH,EAA+E,CAChG,IAAMQ,EAAS,IAAI,IAEnB,QAAWrB,KAAQa,EACf,OAAW,CAAEK,EAAQC,CAAS,IAAK,OAAO,QAAQnB,EAAK,cAAc,EAAG,CACpE,IAAIf,EAAQoC,EAAO,IAAIH,CAAM,EACxBjC,GAAOoC,EAAO,IAAIH,EAAQjC,EAAQ,CAAE,KAAM,GAAO,MAAO,IAAI,IAAO,WAAY,IAAI,GAAM,CAAC,EAE3FkC,EAAS,OAAMlC,EAAM,KAAO,IAChCA,EAAM,UAAYkC,EAAS,QAC3B,QAAW3B,KAAQ2B,EAAS,YAAc,CAAC,EAAGlC,EAAM,WAAW,IAAIO,CAAI,EACvE,QAAWyB,KAAWE,EAAS,OAAS,CAAC,EAAGlC,EAAM,MAAM,IAAI,KAAK,OAAOgC,CAAO,CAAC,CACpF,CAGJ,OAAOI,CACX,CAgBQ,cAAcA,EAA2D,CAC7E,IAAML,EAA4B,CAAC,EAEnC,OAAW,CAAEE,EAAQjC,CAAM,IAAKoC,EAAQ,CAChCpC,EAAM,MAAM+B,EAAW,KAAK,WAAYE,CAAO,IAAI,EACvD,QAAW1B,KAAQP,EAAM,WAAY+B,EAAW,KAAK,eAAgBxB,CAAK,UAAW0B,CAAO,IAAI,EAEhG,IAAMI,EAAyB,CAAC,EAC5BrC,EAAM,SAASqC,EAAQ,KAAKrC,EAAM,OAAO,EACzCA,EAAM,MAAM,KAAO,GAAGqC,EAAQ,KAAK,KAAM,CAAE,GAAGrC,EAAM,KAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAE,IAAI,EAClFqC,EAAQ,OAAS,GAAGN,EAAW,KAAK,UAAWM,EAAQ,KAAK,IAAI,CAAE,UAAWJ,CAAO,IAAI,CAChG,CAEA,OAAOF,CACX,CAmBQ,OAAOH,EAA2CU,EAAyC,CAC/F,IAAMC,EAAuB,CAAEC,EAAwB,EACjDC,EAAU,KAAK,cAAc,KAAK,aAAab,CAAO,CAAC,EACzDa,EAAQ,OAAS,GAAGF,EAAM,KAAK,GAAGE,EAAS,EAAE,EAEjD,QAAW1B,KAAQa,EAAS,CACxB,IAAMc,EAAU3B,EAAK,QAAQ,KAAK,EAC9B2B,GAASH,EAAM,KAAKG,EAAS,EAAE,CACvC,CAEA,OAAIJ,EAAQ,QAAQ,KAAO,GAAGC,EAAM,KAAK;AAAA,GAAgB,CAAE,GAAGD,EAAQ,OAAQ,EAAE,KAAK,EAAE,KAAK;AAAA,EAAO,CAAE;AAAA,GAAM,EAC3GC,EAAM,KAAK,GAAGD,EAAQ,UAAU,EAC5BA,EAAQ,QAAQ,KAAO,GAAKA,EAAQ,WAAW,KAAO,GAAGC,EAAM,KAAK,YAAY,EAE7E,GAAIA,EAAM,KAAK;AAAA,CAAI,CAAE;AAAA,CAChC,CAYQ,OAAOP,EAAwC,CACnD,OAAOA,EAAQ,MAAQ,GAAIA,EAAQ,IAAK,OAAQA,EAAQ,KAAM,GAAKA,EAAQ,IAC/E,CAoBQ,gBAAgBnC,EAAwB,CAC5C,IAAM8C,EAAU,KAAK,GAAG,gBAExB,MAAI,CAACA,EAAQ,WAAW,GAAG,cAAc9C,CAAM,IAC3C,KAAK,GAAG,WAAW,CAAEA,CAAO,CAAC,EACzB,CAAC8C,EAAQ,WAAW,GAAG,cAAc9C,CAAM,GAAU,GAGtD8C,EAAQ,cAAc9C,EAAQ,GAAM,EAAI,EAC1C,YAAY,KAAKC,GAAQA,EAAK,KAAK,SAAS,OAAO,CAAC,GAAG,MAAQ,EACxE,CAsBQ,MAAMD,EAAgB+C,EAA4C,CAEtE,IAAMC,EAAc,KAAK,gBAAgBhD,CAAM,EACzCiD,EAAiC,CACnC,MAAO,CAAC,EACR,OAAAjD,EACA,OAAQkD,GAAUlD,EAAQgD,EAAa,CAAE,WAAY,QAAS,CAAC,EAC/D,QAASA,EACT,YAAa,CAAC,EACd,eAAgB,OAAO,OAAO,IAAI,EAClC,eAAgB,OAAO,OAAO,IAAI,EAClC,eAAgB,CAAE,KAAM,IAAI,IAAO,QAAS,CAAC,EAAG,UAAW,OAAO,OAAO,IAAI,CAAE,EAC/E,oBAAqB,IAAI,GAC7B,EAEMG,EAAsB,CAAC,EACvB,CAAE,KAAAC,CAAK,EAAIH,EAAQ,OAAO,QAEhC,QAAWI,KAAaD,EAChB,KAAK,MAAMC,EAAWJ,CAAO,GAAGE,EAAK,KAAKE,EAAU,KAAK,EAEjE,YAAK,cAAcJ,EAASG,EAAMD,CAAI,EAE/B,CACH,QAAAJ,EACA,QAASO,EAAWN,EAAaC,EAAQ,WAAW,EACpD,YAAaK,EAAWN,EAAaC,EAAQ,KAAK,EAClD,eAAgBA,EAAQ,eACxB,eAAgBA,EAAQ,eACxB,eAAgBA,EAAQ,eACxB,oBAAqBA,EAAQ,mBACjC,CACJ,CAkBQ,MAAMI,EAAkCJ,EAAyC,CACrF,OAAQI,EAAU,KAAM,CACpB,IAAK,oBACD,YAAK,YAAYA,EAAWJ,CAAO,EAE5B,GAEX,IAAK,uBACD,YAAK,gBAAgBI,EAAWJ,CAAO,EAEhC,GAEX,IAAK,yBACD,OAAO,KAAK,iBAAiBI,EAAWJ,CAAO,EAEnD,IAAK,2BACD,OAAO,KAAK,mBAAmBI,EAAWJ,CAAO,EAErD,IAAK,4BACD,OAAO,KAAK,kBAAkBI,EAAWJ,CAAO,EAEpD,IAAK,qBACL,IAAK,+BACD,OAAAM,EAAWF,EAAWJ,EAAQ,QAASA,EAAQ,WAAW,EAEnD,GAEX,QACI,MAAO,EACf,CACJ,CAiBQ,YAAYI,EAA8BJ,EAAsC,CAEpF,GADAM,EAAWF,EAAWJ,EAAQ,QAASA,EAAQ,WAAW,EACtD,KAAK,KAAKI,EAAU,OAAQJ,CAAO,EAAG,OAE1C,IAAMb,EAASa,EAAQ,eAAeI,EAAU,OAAO,KAAK,IAAM,CAAC,EACnE,GAAIA,EAAU,WAAW,OAAS,EAAG,CACjCjB,EAAO,KAAO,GAEd,MACJ,CAEA,QAAWjC,KAASkD,EAAU,WAC1B,OAAQlD,EAAM,KAAM,CAChB,IAAK,yBACDiC,EAAO,UAAYjC,EAAM,MAAM,KAC/B,MAEJ,IAAK,4BACAiC,EAAO,aAAe,CAAC,GAAG,KAAKjC,EAAM,MAAM,IAAI,EAChD,MAEJ,SACKiC,EAAO,QAAU,CAAC,GAAG,KAAK,KAAK,QAAQ,KAAK,OAAOjC,EAAM,QAAQ,EAAGA,EAAM,MAAM,IAAI,CAAC,CAC9F,CAER,CAmBQ,kBAAkBkD,EAAsCJ,EAAyC,CACrG,GAAM,CAAE,gBAAAO,CAAgB,EAAIH,EAC5B,GAAIG,EAAgB,OAAS,4BAA6B,MAAO,GAEjED,EAAWF,EAAWJ,EAAQ,QAASA,EAAQ,WAAW,EAC1D,IAAMxB,EAAS+B,EAAgB,WAE/B,OAAK,KAAK,KAAK/B,EAAQwB,CAAO,KACxBA,EAAQ,eAAexB,EAAO,KAAK,IAAM,CAAC,GAAG,aAAe,CAAC,GAAG,KAAK4B,EAAU,GAAG,IAAI,EAErF,EACX,CAoBQ,iBAAiBA,EAAmCJ,EAAyC,CACjG,GAAM,CAAE,QAAAhB,CAAQ,EAAIgB,EAAQ,eAE5B,GAAII,EAAU,YACV,YAAK,gBAAgBA,EAAU,YAAapB,CAAO,EACnDgB,EAAQ,YAAY,KAAK,CAAE,MAAOI,EAAU,MAAO,IAAKA,EAAU,YAAY,KAAM,CAAC,EAE9E,GAGXE,EAAWF,EAAWJ,EAAQ,QAASA,EAAQ,WAAW,EAC1D,IAAMQ,EAAQJ,EAAU,QAAU,CAAC,KAAK,KAAKA,EAAU,OAAQJ,CAAO,GAC/DA,EAAQ,eAAeI,EAAU,OAAO,KAAK,IAAM,CAAC,GAAG,QAAU,CAAC,EACnEpB,EAEN,QAAW9B,KAASkD,EAAU,WAC1BI,EAAM,KAAK,KAAK,QAAQ,KAAK,OAAOtD,EAAM,KAAK,EAAG,KAAK,OAAOA,EAAM,QAAQ,CAAC,CAAC,EAElF,MAAO,EACX,CAgBQ,gBAAgBkD,EAAiCJ,EAAsC,CAC3FM,EAAWF,EAAWJ,EAAQ,QAASA,EAAQ,WAAW,EAE1D,IAAMjD,EAAS,KAAK,KAAKqD,EAAU,OAAQJ,CAAO,EAC5CS,EAAUL,EAAU,SAAW,KAAK,OAAOA,EAAU,QAAQ,EAAI,KAEvE,GAAIrD,EAAQ,CACJ0D,EAAST,EAAQ,eAAe,UAAUS,CAAO,EAAI1D,EACpDiD,EAAQ,eAAe,KAAK,IAAIjD,CAAM,EAE3C,MACJ,CAEA,IAAMoC,EAASa,EAAQ,eAAeI,EAAU,OAAO,KAAK,IAAM,CAAC,EAC/DK,GAAUtB,EAAO,aAAe,CAAC,GAAG,KAAKsB,CAAO,EAC/CtB,EAAO,KAAO,EACvB,CAoBQ,mBAAmBiB,EAAqCJ,EAAyC,CACrG,GAAM,CAAE,YAAAD,CAAY,EAAIK,EAClBM,EAAQ,KAAK,eAAeX,CAAW,EAG7C,OAFIW,GAAOV,EAAQ,eAAe,QAAQ,KAAK,CAAE,KAAMU,EAAO,MAAO,SAAU,CAAC,EAE5EA,GAASX,EAAY,OAAS,cAC9BC,EAAQ,YAAY,KAAK,CAAE,MAAOI,EAAU,MAAO,IAAKL,EAAY,MAAO,KAAM,UAAW,CAAC,EAEtF,KAGXO,EAAWF,EAAWJ,EAAQ,QAASA,EAAQ,WAAW,EAEnD,GACX,CAuBQ,cAAcA,EAAgCG,EAAoCD,EAA2B,CACjH,GAAM,CAAE,QAAAN,EAAS,YAAAe,CAAY,EAAIX,EAC7BY,EAAQ,EACRtC,EAAQ,EAEZ,QAAWuC,KAAWb,EAAQ,OAAO,SACjC,GAAI,EAAAa,EAAQ,OAAS,SAAWA,EAAQ,MAAM,WAAW,CAAC,IAAM,IAEhE,MAAOD,EAAQT,EAAK,QAAUA,EAAKS,CAAK,EAAE,KAAOC,EAAQ,OAAOD,IAChE,GAAI,EAAAA,EAAQT,EAAK,QAAUA,EAAKS,CAAK,EAAE,MAAQC,EAAQ,OAEvD,MAAOvC,EAAQ4B,EAAK,QAAUA,EAAK5B,CAAK,EAAIuC,EAAQ,KAAKvC,IACrDA,EAAQ4B,EAAK,QAAU,KAAK,MAAMN,EAASiB,EAAQ,IAAKX,EAAK5B,CAAK,CAAC,GAEvEgC,EAAWO,EAASjB,EAASe,CAAW,GAEhD,CAqBQ,KAAKnC,EAAuBwB,EAA+C,CAC/E,IAAMc,EAAW,KAAK,GAAG,QAAQtC,EAAO,MAAOwB,EAAQ,MAAM,EAC7D,GAAI,CAACc,GAAYA,EAAS,wBAAyB,OAAO,KAE1D,GAAM,CAAE,UAAAC,EAAW,iBAAAC,EAAkB,iBAAAC,CAAiB,EAAIH,EACpD/D,EAAS,KAAK,WAAW,QAAQkE,CAAgB,EAEvD,OAAAjB,EAAQ,oBAAoB,IAAIjD,CAAM,EACtCiD,EAAQ,MAAM,KAAK,CACf,IAAKxB,EAAO,IACZ,MAAOA,EAAO,MACd,KAAM,IAAKuC,EAAYC,EAAiB,MAAM,EAAG,CAACD,EAAU,MAAM,EAAIC,CAAiB,QAC3F,CAAC,EAEMjE,CACX,CAgBQ,gBAAgBgD,EAA0BvC,EAA2C,CACzF,GAAIuC,EAAY,OAAS,sBAAuB,CAC5C,QAAW7C,KAAS6C,EAAY,aACxB7C,EAAM,GAAG,OAAS,cAAcM,EAAM,KAAK,CAAE,KAAMN,EAAM,GAAG,IAAK,CAAC,EAE1E,MACJ,CAEI,OAAQ6C,GAAeA,EAAY,IAAM,SAAUA,EAAY,IAAIvC,EAAM,KAAK,CAAE,KAAMuC,EAAY,GAAG,IAAK,CAAC,CACnH,CAWQ,eAAeA,EAA+D,CAClF,OAAIA,EAAY,OAAS,aAAqBA,EAAY,KAEnD,OAAQA,EAAcA,EAAY,IAAI,KAAO,MACxD,CAWQ,OAAOtC,EAAgC,CAC3C,MAAO,SAAUA,EAAOA,EAAK,KAAO,KAAK,UAAUA,EAAK,KAAK,CACjE,CAaQ,QAAQA,EAAcyD,EAAsC,CAChE,OAAOzD,IAASyD,EAAQ,CAAE,KAAAzD,CAAK,EAAI,CAAE,KAAAA,EAAM,MAAAyD,CAAM,CACrD,CAiBQ,MAAMtB,EAAiBuB,EAAeC,EAAsB,CAChE,QAAS9C,EAAQ6C,EAAO7C,EAAQ8C,EAAK9C,IAAS,CAC1C,IAAM+C,EAAOzB,EAAQ,WAAWtB,CAAK,EACrC,GAAI+C,IAAS,IAAcA,IAAS,GAAYA,IAAS,IAAWA,IAAS,GAAS,MAAO,EACjG,CAEA,MAAO,EACX,CACJ,EGv/BA,OAAOC,MAAQ,aACf,OAAS,YAAAC,OAAgB,qBACzB,OAAS,UAAAC,OAAc,wBCFvB,OAAS,eAAAC,OAAmB,KAC5B,OAAS,QAAAC,OAAY,qBCqId,IAAMC,GAAsC,CAC9C,GAAU,IACV,GAAY,KACZ,GAAY,KACZ,GAAgB,IACrB,EDhHO,SAASC,GAAIC,EAAsB,CACtC,MAAO,kBAAkB,SAASA,CAAI,EAAI,KAAOA,EAAOA,CAC5D,CAuBO,SAASC,EAAGC,EAAcC,EAAuB,CACpD,OAAOD,EAAK,WAAWC,CAAK,CAChC,CA4BO,SAASC,GAAWF,EAAcC,EAAwB,CAC7D,OAAQA,IAAU,GAAKF,EAAGC,EAAMC,EAAQ,CAAC,IAAM,MACvCA,EAAQ,IAAMD,EAAK,QAAUD,EAAGC,EAAMC,EAAQ,CAAC,IAAM,GACjE,CAoBO,SAASE,GAAMC,EAAsB,CACxC,MAAO,MAAOA,CAAK,GACvB,CA0BO,SAASC,GAASL,EAAcM,EAA2B,CAC9D,IAAIC,EAAOD,EAAY,EACjBE,EAAOT,EAAGC,EAAMO,CAAI,EAK1B,KAHIC,IAAS,IAAaA,IAAS,KAAYD,IAC3CR,EAAGC,EAAMO,CAAI,IAAM,IAAeA,IAE/BA,EAAOP,EAAK,QAAUD,EAAGC,EAAMO,CAAI,IAAM,IAC5CA,GAAQR,EAAGC,EAAMO,CAAI,IAAM,GAAiB,EAAI,EAEpD,OAAOA,CACX,CAyBO,SAASE,GAAUT,EAAcM,EAA2B,CAC/D,QAASI,EAASJ,EAAWK,EAAQ,EAAGD,EAASV,EAAK,OAAQU,IAAU,CACpE,IAAMZ,EAAOC,EAAGC,EAAMU,CAAM,EAE5B,GAAIZ,IAAS,GAAgBY,YACpBZ,IAAS,GAAaa,QAC1B,IAAIb,IAAS,IAAe,EAAEa,IAAU,EAAG,OAAOD,EAC9CZ,IAAS,KAAeY,EAASL,GAASL,EAAMU,CAAM,GACnE,CAEA,MAAO,EACX,CA0BO,SAASE,GAAWZ,EAAcM,EAA2B,CAChE,IAAIO,EAAQ,GAEZ,QAASH,EAASJ,EAAY,EAAGK,EAAQ,EAAGD,EAASV,EAAK,OAAQU,IAAU,CACxE,IAAMZ,EAAOC,EAAGC,EAAMU,CAAM,EAE5B,GAAIZ,IAAS,GAAgBY,YACpBZ,IAAS,IAAaa,YACtBb,IAAS,IAAa,CAC3B,GAAIa,IAAU,EAAG,OAAOE,EAAQH,EAAS,GACzCC,GACJ,MACSb,IAAS,IAAca,IAAU,EAAGE,EAAQ,GAC5Cf,IAAS,KAAeY,EAASL,GAASL,EAAMU,CAAM,EACnE,CAEA,MAAO,EACX,CA2BO,SAASI,GAAad,EAAcM,EAAqC,CAC5E,IAAMS,EAAMV,GAASL,EAAMM,CAAS,EACpC,GAAIS,GAAOf,EAAK,OAAQ,MAAO,CAAE,MAAOM,EAAY,CAAE,EAEtD,IAAII,EAASJ,EAAY,EAAGU,EAAM,IAC5BR,EAAOT,EAAGC,EAAMU,CAAM,EAK5B,KAHIF,IAAS,IAAaA,IAAS,MAAcQ,GAAO,KAAMN,KAC1DX,EAAGC,EAAMU,CAAM,IAAM,KAAiBM,GAAO,MAAON,KAEjDA,EAASK,EAAKL,IACbX,EAAGC,EAAMU,CAAM,IAAM,GAAgBM,GAAO,KAAOhB,EAAK,EAAEU,CAAM,EAC3DX,EAAGC,EAAMU,CAAM,IAAM,GAAYM,GAAO,MAC5CA,GAAOhB,EAAKU,CAAM,EAG3B,MAAO,CAAEM,EAAM,IAAKD,EAAM,CAAE,CAChC,CAsBO,SAASE,GAAWjB,EAAckB,EAAsB,CAC3D,QAASR,EAASQ,EAAMR,EAASV,EAAK,OAAQU,IAAU,CACpD,GAAIX,EAAGC,EAAMU,CAAM,IAAM,GAAY,OAAOA,EACxCX,EAAGC,EAAMU,CAAM,IAAM,IAAgBA,GAC7C,CAEA,OAAOV,EAAK,MAChB,CAwCO,SAASmB,GAAgBnB,EAAcoB,EAA0B,GAAOC,EAAc,EAAGC,EAAgC,CAAC,EAAW,CACxI,GAAM,CAAE,IAAAC,EAAM,EAAM,EAAID,EAEpBN,EAAM,GACNf,EAAQ,EACRuB,EAAWJ,EAETK,EAAQF,EAAM,aACdG,EAAKD,EAAQ,OAAwB,IACrCE,EAAWxB,GAAMuB,EAAK,OAASA,EAAK,IAAI,EAAI,IAElD,KAAOzB,EAAQD,EAAK,QAAQ,CACxB,IAAMF,EAAOC,EAAGC,EAAMC,CAAK,EACrB2B,EAAQ7B,EAAGC,EAAMC,EAAQ,CAAC,EAEhC,GAAI2B,IAAU,KAAgB9B,IAAS,IAAa+B,GAAY/B,CAAI,GAAI,CACpE,IAAMgC,EAAQrB,GAAUT,EAAMC,EAAQ,CAAC,EAEvC,GAAIH,IAAS,GAAW,CACpB,IAAMiB,EAAMe,IAAU,GAAK9B,EAAK,OAAS8B,EACnCC,GAAQZ,GAAgBnB,EAAK,MAAMC,EAAQ,EAAGc,CAAG,EAAGS,MAAqBF,CAAO,EAEtFN,GAAO,MAAoBe,GAAQF,GAAY/B,CAAI,EACnDG,EAAQc,EAAM,EACd,QACJ,CAEA,GAAIe,IAAU,GAAI,CACd,IAAMC,EAAQZ,GAAgBnB,EAAK,MAAMC,EAAQ,EAAG6B,CAAK,EAAGN,MAAqBF,CAAO,EAClFU,GAAUf,GAAWjB,EAAM8B,EAAQ,CAAC,EACpCG,GAAOd,GAAgBnB,EAAK,MAAM8B,EAAQ,EAAGE,EAAO,EAAG,GAAO,EAAGV,CAAO,EAE9EN,GAAOb,IACFqB,EAAWC,EAAQ,IACpB,MAAOtB,GAAM4B,CAAK,EAAIE,GAAO,SAAsB,IACnD,SAA4BA,EAChC,EAEAhC,EAAQ+B,GACR,QACJ,CACJ,CAEA,OAAQlC,EAAM,CACV,QACIkB,GAAO,IACPf,IACAuB,EAAW,GACX,MAEJ,QACIR,GAAOf,EAAQ,EAAID,EAAK,OAASH,GAAIG,EAAKC,EAAQ,CAAC,CAAC,EAAI,OACxDA,GAAS,EACT,MAEJ,QACIe,GAAOQ,GAAY,CAACD,iBACpBtB,IACA,MAEJ,QACI,GAAI2B,IAAU,IAAaP,IAAQ,MAAcpB,EAAQ,GAAKmB,IAAmBlB,GAAWF,EAAMC,CAAK,EAAG,CACtG,IAAMiC,EAAOjC,IAAU,GAAKoB,IAAQ,qBAA2B,GAC3DtB,EAAGC,EAAMC,EAAQ,CAAC,IAAM,IACxBe,GAAOkB,EAAO/B,GAAMuB,EAAK,GAAkB,EAAI,IAAKzB,GAAS,EAAGuB,EAAW,KAE3ER,GAAOkB,EAAOP,EAAU1B,GAAS,EAEzC,MACIe,IAAQQ,EAAWC,EAAQ,IAAM,QACjCxB,IAEJ,MAEJ,SAAkB,CACd,IAAM6B,EAAQlB,GAAWZ,EAAMC,CAAK,EAEhC6B,IAAU,IACVd,GAAO,MAAOf,MAEde,GAAOb,GAAMgB,GAAgBnB,EAAK,MAAMC,EAAQ,EAAG6B,CAAK,EAAGN,KAAsBF,CAAO,CAAC,EACzFrB,EAAQ6B,EAAQ,GAEpB,KACJ,CAEA,QAAoB,CAChB,GAAM,CAAEK,EAAKC,CAAK,EAAItB,GAAad,EAAMC,CAAK,EAC9Ce,IAAQQ,GAAY,CAACD,GAAOY,IAAQ,gBAA8B,IAAMA,EACxElC,EAAQmC,EACR,KACJ,CAEA,SACA,QACQf,IAAQvB,GAAQkB,GAAO,IAAkBQ,EAAWJ,GACnDJ,GAAOnB,GAAIG,EAAKC,CAAK,CAAC,EAC3BA,IACA,MAEJ,QACIe,GAAOnB,GAAIG,EAAKC,CAAK,CAAC,EAAGA,GACjC,CACJ,CAEA,OAAOe,CACX,CAyEO,SAASqB,GAAarC,EAAcsB,EAAgC,CAAC,EAAW,CACnF,OAAO,IAAI,OAAO,IAAMH,GAAgBnB,EAAM,GAAM,EAAGsB,CAAO,EAAI,IAAKA,EAAQ,KAAK,CACxF,CAkCO,SAASgB,GAAcC,EAAsBjB,EAAgC,CAAC,EAA8B,CAC/G,IAAMkB,EAAyB,CAAC,EAC1BC,EAAyB,CAAC,EAEhC,QAASzC,KAAQuC,EAAO,CACpB,IAAIG,EAAM,GACV,KAAO3C,EAAGC,EAAM,CAAC,IAAM,IAAaD,EAAGC,EAAM,CAAC,IAAM,IAChD0C,EAAM,CAACA,EACP1C,EAAOA,EAAK,MAAM,CAAC,GAGtB0C,EAAMD,EAAUD,GAAS,KAAKH,GAAarC,EAAMsB,CAAO,CAAC,CAC9D,CAEA,OAAQqB,IACHH,EAAQ,SAAW,GAAKA,EAAQ,KAAKI,GAAKA,EAAE,KAAKD,CAAI,CAAC,IACvD,CAACF,EAAQ,KAAKG,GAAKA,EAAE,KAAKD,CAAI,CAAC,CACvC,CAiCO,SAASE,GAAaC,EAAcP,EAAsBjB,EAAgC,CAAC,EAAkB,CAChH,IAAMY,EAAOa,EAAiB,QAAQD,CAAI,EACpCE,EAAUV,GAAcC,EAAOjB,CAAO,EACtC2B,EAAS3B,EAAQ,KAAOiB,EAAM,KAAKvC,GAAQD,EAAGC,EAAM,CAAC,IAAM,IAAYA,EAAK,SAAS,IAAI,CAAC,EAE1FkD,EAAuB,CAAC,EACxBC,EAAuB,CAAE,EAAG,EAElC,KAAOA,EAAM,OAAS,GAAG,CACrB,IAAMC,EAAYD,EAAM,IAAI,EAExBE,EACJ,GAAI,CACAA,EAAUC,GAAYF,EAAYG,GAAKrB,EAAMkB,CAAS,EAAIlB,EAAM,CAAE,cAAe,EAAK,CAAC,CAC3F,MAAQ,CACJ,QACJ,CAEA,QAAWsB,KAASH,EAAS,CACzB,GAAI,CAACJ,GAAUlD,EAAGyD,EAAM,KAAM,CAAC,IAAM,GAAU,SAC/C,IAAMb,EAAOS,EAAY,GAAIA,CAAU,IAAKI,EAAM,IAAK,GAAKA,EAAM,KAE9DA,EAAM,YAAY,EAAGL,EAAM,KAAKR,CAAI,EAC/BK,EAAQL,CAAI,GAAGO,EAAM,KAAKP,CAAI,CAC3C,CACJ,CAEA,OAAOO,CACX,CDrlBO,IAAMO,GAAN,KAA4D,CA+E/D,YAAoBC,EAA2B,CAA3B,YAAAA,EAChB,KAAK,OAAO,CAChB,CAFoB,OA/DX,WAAaC,GAAOC,CAAU,EActB,aAAe,IAAI,IAanB,WAAa,IAAI,IAc1B,QA6CR,IAAI,SAAuB,CACvB,OAAO,KAAK,YAChB,CAoBA,IAAI,kBAAkD,CAClD,OAAQC,GAA8B,KAAK,WAAWA,EAAK,QAAQ,CACvE,CAqBA,IAAI,QAAQH,EAA2B,CACnC,KAAK,OAASA,EACd,KAAK,OAAO,CAChB,CAoBA,cAAqB,CACjB,KAAK,aAAa,MAAM,EACxB,KAAK,aAAa,KAAK,OAAO,SAAS,CAC3C,CAuBA,QAAe,CACX,KAAK,QAAU,KAAK,eAAe,KAAK,OAAO,KAAK,OAAO,EAC3D,KAAK,WAAW,MAAM,EAEtB,KAAK,aAAa,CACtB,CAuBA,QAAQI,EAAqC,CACzC,OAAO,KAAK,WAAW,QAAQ,KAAK,MAAMA,CAAI,CAAC,CACnD,CAqBA,aAAaC,EAAqC,KAAK,aAAoB,CACvE,QAAWD,KAAQC,EACX,KAAK,WAAWD,CAAI,GACxB,KAAK,QAAQA,CAAI,CAEzB,CAeA,wBAA0C,CACtC,OAAO,KAAK,OAAO,OACvB,CAmBA,WAAWA,EAAuB,CAC9B,OAAOE,EAAG,IAAI,WAAWF,CAAI,CACjC,CAsBA,SAASA,EAAcG,EAA+C,CAClE,OAAO,KAAK,WAAW,MAAMH,EAAMG,CAAQ,EAAE,UAAU,IAC3D,CAoBA,cAAcH,EAAcI,EAA4BC,EAAyBC,EAAyBC,EAA+B,CACrI,OAAOL,EAAG,IAAI,cAAcF,EAAMI,EAAYC,EAASC,EAASC,CAAK,CACzE,CAgBA,eAAeP,EAA6B,CACxC,OAAOE,EAAG,IAAI,eAAeF,CAAI,CACrC,CAgBA,gBAAgBA,EAAuB,CACnC,OAAOE,EAAG,IAAI,gBAAgBF,CAAI,CACtC,CAeA,qBAA8B,CAC1B,OAAOE,EAAG,IAAI,oBAAoB,CACtC,CAoBA,oBAAoC,CAChC,MAAO,CAAE,GAAG,KAAK,YAAa,CAClC,CAgBA,sBAAsBM,EAAkC,CACpD,OAAON,EAAG,sBAAsBM,CAAO,CAC3C,CAwBA,iBAAiBR,EAAsB,CACnC,OAAO,KAAK,WAAW,MAAM,KAAK,MAAMA,CAAI,CAAC,EAAE,QAAQ,SAAS,CACpE,CAsBA,kBAAkBA,EAA2C,CACzD,OAAO,KAAK,WAAW,MAAMA,CAAI,EAAE,QACvC,CAqBA,SAASA,EAAsB,CAC3B,OAAO,KAAK,WAAW,QAAQA,CAAI,CACvC,CAgBQ,eAAeS,EAAkD,CACrE,OAAOA,GAASA,EAAM,OAAS,EAAIC,GAAcD,CAAK,EAAI,IAAe,EAC7E,CAgBQ,WAAWT,EAAuB,CACtC,IAAMW,EAAS,KAAK,WAAW,QAAQX,CAAI,EACvCY,EAAW,KAAK,WAAW,IAAID,CAAM,EACzC,OAAIC,IAAa,QAAW,KAAK,WAAW,IACxCD,EAAQC,EAAW,KAAK,QAAQC,GAAS,QAAQ,IAAI,EAAGF,CAAM,CAAC,CACnE,EAEOC,CACX,CAiBQ,MAAMZ,EAAsB,CAChC,IAAMW,EAAS,KAAK,WAAW,QAAQX,CAAI,EAC3C,YAAK,aAAa,IAAIW,CAAM,EAErBA,CACX,CACJ,EJziBO,IAAMG,EAAN,KAAwB,CA6J3B,YAAqBC,EAAsB,gBAAiB,CAAvC,gBAAAA,EACjB,KAAK,aAAe,KAAK,YAAY,EACrC,KAAK,oBAAsB,IAAIC,GAAoB,KAAK,YAAY,EACpE,KAAK,cAAgB,KAAK,oBAAoB,WAAW,MAAM,KAAK,UAAU,EAAE,QAChF,KAAK,gBAAkB,KAAK,sBAAsB,EAClD,KAAK,gBAAkBC,EAAG,sBACtB,KAAK,oBAAqBA,EAAG,uBAAuB,EAAI,CAC5D,EAEA,KAAK,YAAc,IAAIC,GAAiB,IAAI,CAChD,CAVqB,WA7IZ,gBAiBA,oBA4BQ,iBAAmB,IAAI,IAavB,YAAyD,CACtE,WAAYD,EAAG,IAAI,WACnB,SAAU,CAACE,EAAcC,IACrB,KAAK,oBAAoB,SAASD,EAAMC,CAAQ,EACpD,oBAAqB,IAAcH,EAAG,IAAI,oBAAoB,EAC9D,0BAA2B,IAAeA,EAAG,IAAI,yBACrD,EAYiB,YAST,aAaA,cASA,gBAWA,QA0ER,OAAO,OAAOI,EAAiB,GAAsB,CACjD,IAAMC,EAA0B,CAAC,EACjC,OAAW,CAAEC,EAAMC,CAAM,IAAKV,EAAkB,MACxCU,EAAM,SAAS,QAAQH,CAAK,GAAGC,EAAS,KAAKC,CAAI,EAGzD,OAAOD,CACX,CAoBA,IAAI,QAA4B,CAC5B,OAAO,KAAK,YAChB,CAuCA,MAAMG,EAA0D,CAC5D,IAAMC,EAAU,KAAK,gBAAgB,WAAW,EAChD,GAAI,CAACA,EAAS,MAAO,CAAC,EAEtB,IAAMC,EAAS,KAAK,oBAAoB,iBAClCC,EAAQT,GACPA,EAAK,SAAS,SAAS,cAAc,EAAU,GAE3CQ,EAAOR,CAAI,EAGlBU,EAEJ,IADA,KAAK,QAAUZ,EAAG,+CAA+CS,EAAS,KAAK,YAAa,KAAK,OAAO,EACjGG,EAAW,KAAK,QAAQ,yCAAyC,OAAWD,CAAI,GACnF,GAAI,aAAcC,EAAS,SAAU,CACjC,IAAMV,EAAOU,EAAS,SACtB,KAAK,iBAAiB,IAAIV,EAAK,SAAU,CACrC,GAAGU,EAAS,OACZ,GAAG,KAAK,QAAS,wBAAwBV,CAAI,EAC7C,GAAG,KAAK,gBAAgB,yBAAyBA,EAAK,QAAQ,CAClE,EAAE,IAAIW,GAAc,KAAK,iBAAiBA,CAAU,CAAC,CAAC,CAC1D,CAGJ,OAAO,KAAK,qBAAqBJ,EAASD,GAAa,KAAK,iBAAiB,KAAK,CAAC,CACvF,CA2BA,MAAM,KAAKM,EAAqCC,EAAyC,CACrF,OAAAA,IAAW,KAAK,OAAO,QAAQ,QAAU,OAElC,KAAK,YAAY,KAAKD,EAAaC,CAAM,CACpD,CAyBA,MAAM,WAAWD,EAAqCC,EAAyC,CAC3F,OAAAA,IAAW,KAAK,OAAO,QAAQ,QAAU,OAElC,KAAK,YAAY,WAAWD,EAAaC,CAAM,CAC1D,CAqBA,WAAWC,EAA4B,CACnC,KAAK,oBAAoB,aAAaA,CAAK,CAC/C,CA8BA,QAAQC,EAAmBC,EAA8D,CACrF,IAAMC,EAAYD,EAAiB,KAAK,oBAAoB,WAAW,QAAQE,GAAQF,CAAc,CAAC,EAAI,QAAQ,IAAI,EAEhHG,EADW,KAAK,gBAAgB,6BAA6BF,CAAS,EACpD,IAAIF,EAAW,MAAS,GAAG,eACnD,GAAGI,EAAQ,OAAOA,EAElB,IAAMC,EAAmCtB,EAAG,kBACxCiB,EAAWC,GAAkB,GAAI,KAAK,aAAa,QAAS,KAAK,oBAAqB,KAAK,eAC/F,EAAE,eAEF,GAAII,EAAQ,CACR,IAAMhB,EAAOiB,GAASJ,EAAWG,EAAO,gBAAgB,EAExDA,EAAO,UAAYH,EACnBG,EAAO,iBAAmBhB,EAAK,WAAW,GAAG,EAAIA,EAAO,KAAMA,CAAK,EACvE,CAEA,OAAOgB,CACX,CAuBA,SAAgB,CACZ,IAAMf,EAAQV,EAAkB,MAAM,IAAI,KAAK,UAAU,EACpDU,IAELA,EAAM,WACF,EAAAA,EAAM,SAAW,KAErB,KAAK,gBAAgB,QAAQ,EAC7BV,EAAkB,MAAM,OAAO,KAAK,UAAU,GAClD,CAoBA,CAAC,OAAO,SAAW,OAAO,IAAI,gBAAgB,CAAC,GAAU,CACrD,KAAK,QAAQ,CACjB,CAmBA,OAAe,QAAQS,EAAe,gBAAoC,CACtE,IAAMkB,EAAMC,GAAUnB,CAAI,EACpBC,EAAQV,EAAkB,MAAM,IAAI2B,CAAG,EAE7C,GAAIjB,EACA,OAAAA,EAAM,WAECA,EAAM,SAGjB,IAAMmB,EAAW,IAAI7B,EAAkB2B,CAAG,EAC1C,OAAA3B,EAAkB,MAAM,IAAI2B,EAAK,CAAE,SAAAE,EAAU,SAAU,CAAE,CAAC,EAEnDA,CACX,CAuBQ,QAAQtB,EAAiB,GAAgB,CAC7C,GAAM,CAAE,QAAAuB,CAAQ,EAAI,KAAK,oBAAoB,WAAW,MAAM,KAAK,UAAU,EAC7E,MAAI,CAACvB,GAASuB,IAAY,KAAK,cAAsB,IAErD,KAAK,cAAgBA,EACrB,KAAK,aAAe,KAAK,YAAY,EACrC,KAAK,oBAAoB,QAAU,KAAK,aACxC,KAAK,gBAAkB,KAAK,sBAAsB,EAClD,KAAK,YAAY,MAAM,EACvB,KAAK,iBAAiB,MAAM,EAC5B,KAAK,QAAU,OAER,GACX,CAeQ,uBAA+C,CACnD,OAAO3B,EAAG,4BACNA,EAAG,IAAI,oBAAoB,EAC3BM,GAAQ,KAAK,oBAAoB,SAASA,CAAI,EAC9C,KAAK,aAAa,OACtB,CACJ,CAuBQ,qBAAqBG,EAAkBD,EAAyD,CACpG,IAAMQ,EAAQ,KAAK,oBAAoB,WACjCM,EAAqC,CAAC,EAE5C,QAAWM,KAAQpB,EAAW,CAC1B,IAAMF,EAAOU,EAAM,QAAQY,CAAI,EACzBC,EAAc,KAAK,iBAAiB,IAAIvB,CAAI,EAE7CuB,IACDpB,EAAQ,cAAcH,CAAI,EAAGgB,EAAO,KAAK,GAAGO,CAAW,EACtD,KAAK,iBAAiB,OAAOvB,CAAI,EAC1C,CAEA,OAAOgB,CACX,CAiBQ,iBAAiBT,EAA6C,CAClE,IAAMS,EAA8B,CAChC,QAAStB,EAAG,6BAA6Ba,EAAW,YAAa;AAAA,CAAI,EACrE,SAAUA,EAAW,QACzB,EAEA,GAAIA,EAAW,MAAQA,EAAW,QAAU,OAAW,CACnD,GAAM,CAAE,KAAAiB,EAAM,UAAAC,CAAU,EAAIlB,EAAW,KAAK,8BAA8BA,EAAW,KAAK,EAC1FS,EAAO,KAAOT,EAAW,KAAK,SAC9BS,EAAO,KAAOQ,EAAO,EACrBR,EAAO,OAASS,EAAY,EAC5BT,EAAO,KAAOT,EAAW,IAC7B,CAEA,OAAOS,CACX,CAmBQ,aAAiC,CACrC,IAAIU,EAAShC,EAAG,iCACZ,KAAK,WACL,CACI,UAAW,GACX,aAAc,GACd,cAAe,GACf,eAAgB,GAChB,oBAAqB,EACzB,EACA,CACI,GAAGA,EAAG,IACN,oCAAqC,IAAM,CAAC,CAChD,CACJ,EAEA,OAAKgC,IACDA,EAAS,CACL,QAAS,CACL,OAAQ,GACR,OAAQhC,EAAG,aAAa,OACxB,OAAQA,EAAG,WAAW,SACtB,UAAW,GACX,aAAc,GACd,cAAe,GACf,eAAgB,GAChB,oBAAqB,GACrB,iBAAkBA,EAAG,qBAAqB,QAC9C,EACA,OAAQ,CAAC,EACT,UAAW,CAAC,EACZ,kBAAmB,MACvB,GAGJgC,EAAO,QAAU,CACb,GAAGA,EAAO,QACV,OAAQ,GACR,QAASA,EAAO,SAAS,SAAW,QAAQ,IAAI,EAChD,gBAAiB,GACjB,0BAA2B,EAC/B,EAEOA,CACX,CACJ,EAvpBIC,GA9CSpC,EA8Ce,QAAQ,IAAI,KA9C3BA,EAANqC,EAAA,CALNC,GAAW,CACR,QAAQ7B,EAAkC,CACtC,OAAOT,EAAkB,QAAQS,CAAI,CACzC,CACJ,CAAC,GACYT,GTZN,IAAMuC,EAAN,KAAa,CA6DhB,YAA6BC,EAA4B,CAA5B,WAAAA,EACzB,KAAK,aAAe,KAAK,WAAa,UAAY,KAAK,SAAW,MACtE,CAF6B,MA5CpB,QAAUC,GAAOC,CAAoB,EAYtC,UAYA,aA0CR,IAAI,SAASC,EAAqB,CAC9B,KAAK,QAAQ,MAAM,CAAE,SAAUA,CAAM,CAAC,CAC1C,CAgBA,IAAI,UAAyB,CACzB,OAAO,KAAK,QAAQ,SAAS,EAAE,UAAY,MAC/C,CAkBA,IAAI,KAAc,CACd,OAAO,KAAK,WAAa,EAC7B,CAeA,IAAI,IAAIA,EAAe,CACnB,KAAK,UAAYA,CACrB,CA0BA,WAAWC,EAAkC,CACzC,GAAIA,EAAM,OAAS,QACf,OAAO,KAAK,IAAI,GAAIC,EAAU,IAAI,QAAW,CAAE,IAAKC,EAAW,UAAU,CAAE,IAAKC,EAAaH,EAAM,QAAQ,WAAW,CAAE,GACpH,GAAII,EAAmB,OAAO,CAAE,IAAKD,EAAaH,EAAM,QAAQ,WAAW,CAAE,EAAE,EAEvF,GAAM,CAAE,OAAAK,EAAQ,SAAAC,EAAU,KAAAC,EAAM,QAASC,EAAO,SAAAC,CAAS,EAAIT,EAAM,YAC7DU,EAAS,CAACD,EACZC,EAAQ,QAAQ,SAAW,EAC1B,QAAQ,SAAW,EAExB,KAAK,OAAO,CAAE,MAAOL,EAAQ,QAASC,EAAU,KAAAC,EAAM,QAASC,CAAM,CAAC,EAClEC,GAAUE,GAAaF,EAAU,KAAK,WAAa,UAAY,IAAW,MAAS,EAEvF,IAAMG,EAASF,EAASG,GAAW,MAAW,EAAIC,GAAQ,QAAa,EACjEC,EAAOL,EAASM,EAAUhB,EAAM,QAAQ,WAAW,EAAIG,EAAaH,EAAM,QAAQ,WAAW,EAEnG,KAAK,IAAI,GAAIY,CAAO,IAAKG,CAAK,IAAKb,EAAW,IAAI,MAAOF,EAAM,QAAS,KAAK,CAAE,GAC3E;AAAA,EAAMI,EAAmB,QAASQ,CAAM,CAAE,IAAKG,CAAK,IAAKb,EAAW,IAAI,MAAOF,EAAM,QAAS,KAAK,CAAE,EAAE,CAC/G,CAwBA,YAAYA,EAA+B,CACvC,OAAQA,EAAM,KAAM,CAChB,IAAK,QACD,YAAK,IAAMA,EAAM,IAEV,QAAQ,IAAI,GAAII,EAAmB,OAAO,CAAE,IAAKa,EAAUjB,EAAM,GAAG,CAAE,EAAE,EACnF,IAAK,OACD,KAAK,UAAY,OACbA,EAAM,SAAS,QAAQ,IAAI,GAAII,EAAmB,OAAO,CAAE,IAAKF,EAAW,SAAS,CAAE,EAAE,EAE5F,OACJ,IAAK,UACG,KAAK,WAAa,WAClB,QAAQ,IAAI,GAAIE,EAAmB,OAAO,CAAE,IAAKF,EAAW,IAAIF,EAAM,GAAG,CAAE,EAAE,EAEjF,OACJ,IAAK,QACD,GAAIA,EAAM,KAAK,SAAS,SAAS,EAAG,OACpC,QAAQ,IACJ,GAAII,EAAmB,QAASS,GAAW,MAAW,CAAC,CAAE,IAAKX,EAAWF,EAAM,MAAM,OAAO,CAAE,EAClG,CACR,CACJ,CAyBA,YAAYkB,EAAsD,CAC9D,IAAIR,EAAS,GAEb,OAAW,CAAEK,EAAMI,CAAK,IAAK,OAAO,QAAQD,CAAW,EAAG,CACtD,IAAME,EAAQD,EAAK,MAAM,OAASA,EAAK,QAAQ,OAASA,EAAK,KAAK,OAASA,EAAK,QAAQ,OAExFT,IAAWS,EAAK,MAAM,OAAS,EAC/B,QAAQ,IAAI,GAAIf,EAAmB,YAAY,CAAE,IAAKD,EAAaY,CAAI,CAAE,IAAKb,EAAW,IAAI,GAAIkB,CAAM,aAAa,CAAE,EAAE,EACxH,KAAK,OAAOD,CAAI,EAChB,QAAQ,IAAI,EAAE,CAClB,CAEAE,GAAKX,EAAS,EAAI,CAAC,CACvB,CA4BA,MAAM,QAAQY,EAAgBC,EAAiB,GAAsB,CACjEC,GAAY,EACZC,EAAkB,OAAOF,CAAK,EAE9B,KAAK,IAAI,GAAItB,EAAU,IAAI,QAAY,CAAE,IAAKC,EAAWoB,CAAM,CAAE,GAC7D,GAAIlB,EAAmB,UAAWH,EAAU,IAAI,QAAY,CAAC,CAAE,IAAKC,EAAWoB,CAAM,CAAE,EAAE,EAE7F,MAAM,KAAK,MAAM,CACrB,CAqBA,eAA8B,CAC1B,OAAI,KAAK,WAAa,UAAW,KAAK,SAAW,KAAK,cAElD,KAAK,aAAe,KAAK,SACzB,KAAK,SAAW,WAGb,KAAK,QAChB,CAgBQ,IAAII,EAAkBC,EAAoB,CAC9C,QAAQ,IAAIA,CAAI,EAChBC,GAAYF,CAAQ,CACxB,CAoBQ,OAAOP,EAA+B,CAC1C,IAAMU,EAASC,EAAO,KAAK,QAAQ,EAC7BC,EAAO,KAAK,WAAa,UAE3BD,EAAO,OAASD,GAAQG,GAAWb,EAAK,MAAO,SAAUN,GAAY,OAAa,EAAI,EACtFiB,EAAO,SAAWD,GAAQG,GAAWb,EAAK,QAAS,WAAYH,EAAW,SAAee,CAAI,EAC7FD,EAAO,MAAQD,GAAQG,GAAWb,EAAK,KAAM,OAAQlB,EAAW,SAAa8B,CAAI,EACjFD,EAAO,SAAWD,GAAQG,GAAWb,EAAK,QAAS,UAAWjB,EAAY,OAAW6B,CAAI,CACjG,CACJ,EA7XapC,EAANsC,EAAA,CAHNC,GAAW,CACR,MAAO,WACX,CAAC,GACYvC,GgBjCb,OAAOwC,OAAW,QAClB,OAAS,WAAAC,OAAe,gBACxB,OAAS,cAAAC,OAAkB,wBCSpB,IAAMC,GAAiB,mBA4BjBC,GAA8C,CACvD,YAAa,CACT,SAAU,iDACV,KAAM,SACN,MAAO,EACX,EACA,UAAW,CACP,SAAU,gDACV,MAAO,KACP,KAAM,SACV,EACA,SAAU,CACN,SAAU,uCACV,MAAO,IACP,KAAM,SACN,QAAS,CAAE,UAAW,OAAQ,SAAU,CAC5C,EACA,MAAO,CACH,SAAU,+BACV,MAAO,IACP,KAAM,QACV,EACA,OAAQ,CACJ,SAAU,mCACV,MAAO,IACP,KAAM,QACV,EACA,YAAa,CACT,SAAU,gDACV,MAAO,KACP,KAAM,SACV,EACA,MAAO,CACH,SAAU,uCACV,MAAO,IACP,KAAM,SACV,EACA,OAAQ,CACJ,SAAU,mCACV,MAAO,IACP,KAAM,SACN,QAASD,EACb,EACA,SAAU,CACN,SAAU,wCACV,MAAO,MACP,KAAM,QACV,EACA,OAAQ,CACJ,SAAU,0BACV,MAAO,IACP,KAAM,SACV,EACA,OAAQ,CACJ,SAAU,wCACV,MAAO,IACP,KAAM,SACV,EACA,MAAO,CACH,SAAU,4CACV,MAAO,MACP,KAAM,SACV,EACA,YAAa,CACT,SAAU,iDACV,MAAO,MACP,KAAM,SACV,EACA,OAAQ,CACJ,SAAU,uBACV,MAAO,IACP,KAAM,SACN,QAAS,CAAE,MAAO,MAAO,MAAO,CACpC,EACA,QAAS,CACL,SAAU,6BACV,MAAO,IACP,KAAM,SACV,EACA,MAAO,CACH,SAAU,kFACV,MAAO,KACP,KAAM,SACN,MAAO,EACX,EACA,MAAO,CACH,SAAU,wBACV,KAAM,UACN,QAAS,EACb,CACJ,EAmBaE,GAAoB,CAC7B,CAAE,sBAAuB,2CAA4C,EACrE,CAAE,uCAAwC,wCAAyC,EACnF,CAAE,uBAAwB,4CAA6C,EACvE,CAAE,4BAA6B,6DAA8D,EAC7F,CAAE,+CAAgD,yCAA0C,EAC5F,CAAE,qDAAsD,0CAA2C,EACnG,CAAE,qBAAsB,2CAA4C,EACpE,CAAE,mCAAoC,+BAAgC,CAC1E,ED5HO,IAAMC,EAAN,KAAiB,CA0BpB,gBAAgBC,EAAkE,CAC9E,OAAOC,GAAMD,CAAI,EACZ,KAAK,EAAK,EACV,QAAQ,EAAK,EACb,QAAQ,CACL,OAAQE,GAAmB,MAC/B,CAAC,EAAE,UAAU,CACrB,CAmCA,cAAcF,EAAqBG,EAAyC,CAAC,EAAuB,CAChG,IAAMC,EAASH,GAAMI,GAAQL,CAAI,CAAC,EAAE,OAAO,IAAI,EACzCM,EAAmBF,EAAO,SAChC,OAAAA,EAAO,SAAW,SAAUG,EAAiE,CACzF,YAAK,MAAM,OAAO,KAAKL,EAAkB,EAAG,iBAAiB,EAC7D,KAAK,MAAM,OAAO,KAAKC,CAAc,EAAG,eAAe,EAEhDG,EAAiB,KAAK,KAAMC,CAAsC,CAC7E,EAEAH,EACK,MAAM,mCAAmC,EACzC,QAAQ,oBAAqB,mDAAqDH,GACxEA,EAAM,WAAW,cAAe,CACnC,SAAU,mDACV,KAAM,SACN,MAAO,EACX,CAAC,CACJ,EACA,QAAQE,CAAc,EACtB,QAAQD,EAAkB,EAC1B,SAAS,sFAAsF,EAC/F,KAAK,EACL,MAAM,OAAQ,GAAG,EACjB,OAAO,EACP,QAAQ,EAEbM,GAAkB,QAAQ,CAAC,CAAEC,EAASC,CAAY,IAAM,CACpDN,EAAO,QAAQK,EAASC,CAAW,CACvC,CAAC,EAEMN,EAAO,UAAU,CAC5B,CACJ,EArGaL,EAANY,EAAA,CAHNC,GAAW,CACR,MAAO,WACX,CAAC,GACYb,GtB3Bb,OAAS,UAAAc,OAAc,wBwBPvB,UAAYC,OAAU,OACtB,UAAYC,OAAW,QACvB,OAAS,WAAAC,OAAe,OACxB,OAAS,gBAAAC,OAAoB,KCd7B,IAAAC,GAAA,w7JDgBA,OAAS,QAAAC,OAAY,qBACrB,OAAS,UAAAC,OAAc,wBACvB,OAAS,WAAAC,OAAe,4BACxB,OAAS,WAAAC,GAAS,QAAAC,GAAM,YAAAC,OAAgB,cA4BjC,IAAMC,GAAN,KAAmB,CA4EtB,YAAqBC,EAAsCC,EAAa,CAAnD,YAAAD,EACjB,KAAK,QAAUE,EAAiB,QAAQD,CAAG,EAC3C,KAAK,OAAO,OAAS,EACrB,KAAK,OAAO,OAAS,WACzB,CAJqB,OAhEb,OAeS,QAAU,IAAIE,GAWd,QAYA,UAAYC,GAAOF,CAAgB,EAgDpD,IAAI,MAAiC,CACjC,OAAO,KAAK,QAAQ,KAAK,KAAK,KAAK,OAAO,CAC9C,CAmBA,IAAI,WAA2C,CAC3C,OAAO,KAAK,QAAQ,UAAU,KAAK,KAAK,OAAO,CACnD,CA0BA,MAAM,OAAuB,CACzB,GAAI,KAAK,OAAO,MACZ,OAAO,MAAM,KAAK,iBAAiB,EAEvC,MAAM,KAAK,gBAAgB,CAC/B,CAwBA,MAAM,MAAsB,CACxB,GAAI,CAAC,KAAK,OAAQ,OAAO,KAAK,QAAQ,KAAK,CAAE,KAAM,OAAQ,QAAS,EAAM,CAAC,EAE3E,MAAM,IAAI,QAAc,CAACG,EAASC,IAAW,CACzC,KAAK,OAAQ,MAAMC,GAAO,CAClBA,EAAKD,EAAOC,CAAG,EACdF,EAAQ,CACjB,CAAC,CACL,CAAC,EAED,KAAK,OAAS,OACd,KAAK,QAAQ,KAAK,CAAE,KAAM,OAAQ,QAAS,EAAK,CAAC,CACrD,CAwBA,MAAM,SAAyB,CAC3B,MAAM,KAAK,KAAK,EAChB,MAAM,KAAK,MAAM,CACrB,CAaQ,eAAsB,CAC1B,GAAI,KAAK,OAAO,OAAS,EAAG,CACxB,IAAMG,EAAU,KAAK,OAAQ,QAAQ,EAClCA,GAAW,OAAOA,GAAY,UAAYA,EAAQ,OACjD,KAAK,OAAO,KAAOA,EAAQ,KACnC,CACJ,CAeQ,iBAAiC,CACrC,OAAO,IAAI,QAAeH,GAAY,CAClC,KAAK,OAAc,gBAAa,CAACI,EAAKC,IAAQ,CAC1C,KAAK,cAAcD,EAAKC,EAAK,IAAM,KAAK,gBAAgBD,EAAKC,CAAG,CAAC,CACrE,CAAC,EAED,KAAK,OAAO,OAAO,KAAK,OAAO,KAAM,KAAK,OAAO,KAAM,IAAM,CACzD,KAAK,cAAc,EACnB,IAAMF,EAAkC,CACpC,KAAM,KAAK,OAAO,KAClB,KAAM,KAAK,OAAO,KAClB,IAAK,UAAW,KAAK,OAAO,IAAK,IAAK,KAAK,OAAO,IAAK,EAC3D,EAEA,KAAK,OAAO,UAAUA,CAAO,EAC7B,KAAK,QAAQ,KAAK,CAAE,GAAGA,EAAS,KAAM,OAAQ,CAAC,EAC/CH,EAAQ,CACZ,CAAC,CACL,CAAC,CACL,CAmBQ,kBAAkC,CACtC,OAAO,IAAI,QAASA,GAAY,CAC5B,IAAMM,EAAU,CACZ,IAAKC,GAAa,KAAK,OAAO,KAAOC,GAAK,KAAK,UAAU,cAAe,KAAM,QAAS,YAAY,CAAC,EACpG,KAAMD,GAAa,KAAK,OAAO,MAAQC,GAAK,KAAK,UAAU,cAAe,KAAM,QAAS,YAAY,CAAC,CAC1G,EAEA,KAAK,OAAe,gBAAaF,EAAS,CAACF,EAAKC,IAAQ,CACpD,KAAK,cAAcD,EAAKC,EAAK,IAAM,KAAK,gBAAgBD,EAAKC,CAAG,CAAC,CACrE,CAAC,EAED,KAAK,OAAO,OAAO,KAAK,OAAO,KAAM,KAAK,OAAO,KAAM,IAAM,CACzD,KAAK,cAAc,EACnB,IAAMF,EAAkC,CACpC,KAAM,KAAK,OAAO,KAClB,KAAM,KAAK,OAAO,KAClB,IAAK,WAAY,KAAK,OAAO,IAAK,IAAK,KAAK,OAAO,IAAK,EAC5D,EAEA,KAAK,OAAO,UAAUA,CAAO,EAC7B,KAAK,QAAQ,KAAK,CAAE,GAAGA,EAAS,KAAM,OAAQ,CAAC,EAC/CH,EAAQ,CACZ,CAAC,CACL,CAAC,CACL,CAoBQ,cAAcI,EAAsBC,EAAqBI,EAAkC,CAC/F,GAAI,CACA,KAAK,QAAQ,KAAK,CAAE,KAAM,UAAW,IAAKL,EAAI,KAAO,EAAG,CAAC,EAErD,KAAK,OAAO,UACZ,KAAK,OAAO,UAAUA,EAAKC,EAAKI,CAAc,EAE9CA,EAAe,CAEvB,OAASC,EAAO,CACZ,KAAK,UAAUL,EAAaK,CAAK,CACrC,CACJ,CAgBQ,eAAeC,EAAqB,CAgBxC,MAf6C,CACzC,KAAM,YACN,IAAK,WACL,GAAI,yBACJ,IAAK,yBACL,IAAK,yBACL,GAAI,aACJ,IAAK,mBACL,KAAM,mBACN,IAAK,YACL,IAAK,aACL,IAAK,YACL,IAAK,YACT,EAEoBA,CAAG,GAAK,0BAChC,CAwBA,MAAc,gBAAgBP,EAAsBC,EAAoC,CACpF,IAAMO,EAAcR,EAAI,MAAQ,IAAM,GAAKA,EAAI,KAAK,QAAQ,OAAQ,EAAE,GAAK,GACrES,EAAWL,GAAK,KAAK,QAASI,CAAW,EAE/C,GAAI,CAACC,EAAS,WAAW,KAAK,OAAO,EAAG,CACpCR,EAAI,WAAa,IACjBA,EAAI,IAAI,EAER,MACJ,CAEA,GAAI,CACA,IAAMS,EAAQ,MAAMC,GAAKF,CAAQ,EAE7BC,EAAM,YAAY,EAClB,MAAM,KAAK,gBAAgBD,EAAUD,EAAaP,CAAG,EAC9CS,EAAM,OAAO,GACpB,MAAM,KAAK,WAAWD,EAAUR,CAAG,CAE3C,OAASK,EAAO,CACZ,KAAK,QAAQ,KAAK,CAAE,KAAM,QAAS,MAAeA,EAAO,IAAKN,EAAI,GAAI,CAAC,EACvE,KAAK,aAAaC,CAAG,CACzB,CACJ,CAoBA,MAAc,gBAAgBQ,EAAkBD,EAAqBP,EAAoC,CAErG,IAAIW,GADU,MAAMC,GAAQJ,CAAQ,GACf,IAAIK,GAAQ,CAC7B,IAAML,EAAWL,GAAKI,EAAaM,CAAI,EACjCP,EAAMQ,GAAQD,CAAI,EAAE,MAAM,CAAC,GAAK,SAEtC,OAAGP,IAAQ,SACA;AAAA,gCACUE,CAAS;AAAA;AAAA,8DAEqBK,CAAK;AAAA;AAAA,kBAKjD;AAAA,4BACUL,CAAS;AAAA;AAAA,0DAEqBK,CAAK,0BAA2BP,CAAI;AAAA;AAAA,aAGvF,CAAC,EAAE,KAAK,EAAE,EAENK,EAGAA,EAAW,qBAAsBA,CAAS,SAF1CA,EAAW,qDAKf,IAAII,EAAa,IACXC,EAAWT,EAAY,MAAM,GAAG,EAAE,IAAIU,IACxCF,GAAc,GAAIE,CAAK,IAEhB,gBAAiBF,CAAW,KAAME,CAAK,YACjD,EAAE,KAAK,EAAE,EAEJC,EAAaC,GAAK,QAAQ,gBAAiBR,CAAQ,EACpD,QAAQ,aAAc,gCAAkCK,CAAQ,EAChE,QAAQ,UAAW,IAAMT,EAAY,MAAM,GAAG,EAAE,MAAM,EAAG,EAAE,EAAE,KAAK,GAAG,CAAC,EAE3EP,EAAI,UAAU,IAAK,CAAE,eAAgB,WAAY,CAAC,EAClDA,EAAI,IAAIkB,CAAU,CACtB,CAkBA,MAAc,WAAWV,EAAkBR,EAAoC,CAC3E,IAAMM,EAAMQ,GAAQN,CAAQ,EAAE,MAAM,CAAC,GAAK,MACpCY,EAAc,KAAK,eAAed,CAAG,EAErCe,EAAO,MAAMC,GAASd,CAAQ,EACpCR,EAAI,UAAU,IAAK,CAAE,eAAgBoB,CAAY,CAAC,EAClDpB,EAAI,IAAIqB,CAAI,CAChB,CAaQ,aAAarB,EAA2B,CAC5CA,EAAI,UAAU,IAAK,CAAE,eAAgB,YAAa,CAAC,EACnDA,EAAI,IAAI,WAAW,CACvB,CAeQ,UAAUA,EAAqBK,EAAoB,CACvD,KAAK,QAAQ,KAAK,CAAE,KAAM,QAAS,MAAAA,CAAM,CAAC,EAC1CL,EAAI,UAAU,IAAK,CAAE,eAAgB,YAAa,CAAC,EACnDA,EAAI,IAAI,uBAAuB,CACnC,CACJ,EEpkBA,OAAS,UAAAuB,OAAc,wBCwBhB,IAAMC,EAAN,cAA0BC,CAAgB,CAwB7C,YAAYC,EAAiBC,EAA+B,CAAE,oBAAqB,EAAK,EAAG,CACvF,MAAMD,CAAO,EACb,KAAK,cAAc,KAAMC,CAAO,CACpC,CACJ,EDlDA,OAAS,WAAAC,OAAe,4BEQxB,OAAS,aAAAC,OAAiB,aAC1B,OAAS,YAAAC,OAAgB,qBACzB,OAAS,UAAAC,OAAc,wBCahB,SAASC,GAAaC,EAA6BC,EAAwBC,EAAmC,CACjH,GAAID,IAAO,OAAW,OAAOC,EAC7B,GAAI,OAAO,OAAOF,EAAWC,CAAE,EAAG,OAAOD,EAAUC,CAAE,EAErD,QAAWE,KAAOH,EACd,GAAI,CACA,GAAI,IAAI,OAAO,OAAQG,CAAI,IAAI,EAAE,KAAKF,CAAE,EAAG,OAAOD,EAAUG,CAAG,CACnE,MAAQ,CACJ,GAAGF,IAAOE,EAAK,OAAOH,EAAUG,CAAG,CACvC,CAGJ,OAAOD,CACX,CA4BO,SAASE,GACZC,EAAyBL,EAA6BM,EAAyBJ,EAC3E,CACJ,IAAMK,EAAWR,GAAaC,EAAWM,EAAQ,GAAIJ,CAAK,EACtDK,IAAa,UAAUF,EAAKE,CAAQ,EAAE,KAAeD,CAAO,CACpE,CAkCO,SAASE,GACZH,EAAyBL,EAA6BS,EAAiCP,EAAqBQ,EACxG,CACJ,QAAWJ,KAAWG,EACfC,IAAMJ,EAAQ,WAAaI,GAC9BN,GAAWC,EAAML,EAAWM,EAASJ,CAAK,CAElD,CCzHA,OAAS,aAAAS,OAAiB,aAC1B,OAAS,UAAAC,OAAc,wBCchB,IAAMC,EAAc,KAsBdC,GAAgB,OAwBXC,OAgBdA,EAAA,MAAQ,GAAIF,CAAY,QAiBxBE,EAAA,OAAS,GAAIF,CAAY,SAiBzBE,EAAA,OAAS,GAAIF,CAAY,SAlDXE,OAAA,IA0ELC,GAAoB,IAAI,IAAI,CAAE,QAAS,OAAQ,WAAY,CAAC,EAoB5DC,GAAgB,IAAI,IAAI,CAAE,KAAM,QAAS,QAAS,SAAU,WAAY,UAAW,CAAC,EC3H1F,SAASC,GAAUC,EAAiCC,EAAuB,CAC9E,IAAMC,EAAQF,EAAQC,CAAI,EAE1B,OAAOC,IAAU,QAAa,CAACC,GAAkB,IAAID,EAAM,KAAK,CAAC,CACrE,CAqCO,SAASE,GAAkBC,EAAcJ,EAAcK,EAA8BC,EAAwB,CAChH,GAAM,CAAE,KAAAC,EAAM,OAAAC,CAAO,EAAIH,EACnBI,EAAWF,EAAK,UAAU,CAAC,EAC3BG,EAAON,EAAK,MAAMK,EAAS,MAAOA,EAAS,GAAG,EAEpD,GAAIA,EAAS,OAAS,2BAA6BA,EAAS,OAAS,qBACjE,MAAO,GAAIH,CAAO,SAAUN,CAAK,MAAOU,CAAK,GAAIF,CAAO,IAE5D,GAAIA,EAAQ,MAAO,GAAIF,CAAO,SAAUN,CAAK,OAAQU,CAAK,IAAKF,CAAO,IAEtE,GAAM,CAAE,KAAAG,CAAK,EAAIF,EACXG,EAASH,EAAS,OAAO,IAAII,GAAST,EAAK,MAAMS,EAAM,MAAOA,EAAM,GAAG,CAAC,EAAE,KAAK,IAAI,EACnFC,EAAUL,EAAS,WAAaL,EAAK,MAAMK,EAAS,WAAW,MAAOA,EAAS,WAAW,GAAG,EAAI,GACjGM,EAAO,GAAIT,CAAO,GAAIG,EAAS,MAAQ,SAAW,EAAG,YAAaT,CAAK,IAAKY,CAAO,IAAKE,CAAQ,GAEtG,OAAKH,EACDA,EAAK,OAAS,iBAAyB,GAAII,CAAK,IAAKX,EAAK,MAAMO,EAAK,MAAOA,EAAK,GAAG,CAAE,GAEnF,GAAII,CAAK,aAAcX,EAAK,MAAMO,EAAK,MAAOA,EAAK,GAAG,CAAE,MAH7C,GAAII,CAAK,KAI/B,CAkCO,SAASC,GAAiBZ,EAAcC,EAA8BY,EAA4B,CACrG,GAAM,CAAE,KAAAV,EAAM,OAAAC,CAAO,EAAIH,EACnBI,EAAWF,EAAK,UAAU,CAAC,EAC3BG,EAAON,EAAK,MAAMK,EAAS,MAAOA,EAAS,GAAG,EAC9CS,EAAOD,EAAY,IAAM,GAE/B,GAAIR,EAAS,OAAS,2BAA6BA,EAAS,OAAS,qBACjE,MAAO,GAAIC,CAAK,GAAIF,CAAO,GAAIU,CAAK,GAExC,GAAIV,GAAU,CAACS,EAAW,MAAO,IAAKP,CAAK,IAAKF,GAAU,IAAK,GAAIU,CAAK,GAExE,GAAM,CAAE,KAAAP,CAAK,EAAIF,EACjB,OAAKE,EACDA,EAAK,OAAS,iBAAyB,GAAIP,EAAK,MAAMO,EAAK,MAAOA,EAAK,GAAG,CAAE,IAEzEP,EAAK,MAAMO,EAAK,MAAQ,EAAGA,EAAK,IAAM,CAAC,EAAE,KAAK,EAHnC,EAItB,CFlGO,SAASQ,GAAcC,EAAyBC,EAA8C,CACjG,IAAMC,EAAU,IAAI,IACdC,EAAaC,GAAOC,CAAU,EAEpC,QAAWC,KAAQN,EAAO,CACtB,IAAMO,EAAUJ,EAAW,MAAMG,CAAI,EAAE,UAAU,KAEjD,GAAI,CAACC,GAAS,SAASC,EAAa,EAAG,SACvC,GAAM,CAAE,QAAAC,CAAQ,EAAIC,GAAUJ,EAAMC,EAAS,CAAE,WAAY,QAAS,CAAC,EAErE,QAAWI,KAAQF,EAAQ,KACvB,GAAIE,EAAK,OAAS,0BACdA,EAAK,aAAa,OAAS,sBAE/B,QAAWC,KAAcD,EAAK,YAAY,aAAc,CACpD,IAAME,EAAOD,EAAW,KACxB,GAAIC,GAAM,OAAS,kBAAoBA,EAAK,OAAO,OAAS,aAAc,SAE1E,IAAMC,EAAYD,EAAK,OAAO,KAC9B,GAAIC,IAAcC,EAAO,OAASD,IAAcC,EAAO,OAAQ,SAE/D,IAAMC,EAAMH,EAAK,UAAU,CAAC,EACxBG,GAAK,OAAS,WAAa,OAAOA,EAAI,OAAU,UAChDJ,EAAW,GAAG,OAAS,cAEtBE,IAAcC,EAAO,QAAWE,GAAUhB,EAASe,EAAI,KAAK,GAC7Dd,EAAQ,IAAIU,EAAW,GAAG,IAAI,CAEtC,CAER,CAEA,OAAOV,CACX,CG/DA,OAAS,eAAAgB,OAAmB,aCR5B,OAAS,iBAAAC,OAAqB,SAC9B,OAAS,UAAAC,OAAc,wBCDvB,OAAS,UAAAC,GAAQ,iBAAAC,OAAqB,KAkDtC,eAAsBC,GAAeC,EAAcC,EAAmB,CAAC,EAAGC,EAAyB,CAAC,EAAGC,EAAc,GAAyB,CAC1I,IAAMC,EAAgC,CAAC,EACjCC,EAAoD,OAAO,0BAA0B,UAAU,EACrG,OAAOA,EAAY,WAChBF,GAAa,OAAOE,EAAY,QAEnC,OAAO,iBAAiBD,EAAMC,CAAW,EACzC,OAAO,OAAOD,EAAMH,CAAO,EAE3B,IAAMK,EAAUR,GAAcM,CAAI,EAGlC,OAAO,MAFQ,IAAIP,GAAOG,EAAME,CAAO,EAEnB,aAAaI,EAAS,CAAE,cAAe,GAAM,cAAe,EAAM,CAAC,CAC3F,CC9DA,OAAS,OAAAC,OAAW,UACpB,OAAS,SAAAC,OAAa,UACtB,OAAS,WAAAC,GAAS,YAAAC,OAAgB,qBCgB3B,IAAMC,GAAoC,CAC7C,MAAO,GACP,OAAQ,GACR,OAAQ,GACR,OAAQ,OACR,OAAQ,MACR,OAAQ,SACR,SAAU,EACV,SAAU,SACV,SAAU,UACV,UAAW,UACf,EDMA,eAAsBC,GAAuBC,EAA6B,CAAC,EAAiC,CACxG,OAAO,MAAMC,GAAM,CACf,cAAeC,GAAI,EACnB,GAAGC,GACH,GAAGH,EACH,SAAU,EACd,CAAC,CACL,CAmCA,eAAsBI,GAA4BC,EAAgBC,EAAcN,EAA6B,CAAC,EAAiC,CAC3I,OAAO,MAAMC,GAAM,CACf,cAAeC,GAAI,EACnB,GAAGC,GACH,GAAGH,EACH,MAAO,CACH,OAAQ,KACR,SAAUK,EACV,WAAYE,GAAQD,CAAI,EACxB,WAAYE,GAASF,CAAI,CAC7B,EACA,MAAO,GACP,SAAU,GACV,UAAW,UACf,CAAC,CACL,CAgCA,eAAsBG,GAAoBT,EAA6B,CAAC,EAEtE,CACE,OAAO,MAAMC,GAAM,CACf,GAAGD,EACH,MAAO,GACP,OAAQ,GACR,OAAQ,MACR,QAAS,OACT,SAAU,GACV,SAAU,WACV,SAAU,QACd,CAAC,CACL,CFpHO,SAASU,GAAUC,EAAwB,CAC9C,OAA2BA,GAAU,KAAa,YAC9C,OAAOA,GAAU,WAAmBA,EAAM,SAAS,EACnD,OAAOA,GAAU,UAAY,OAAOA,GAAU,UAAkB,OAAOA,CAAK,EAEzEC,GAAUD,CAAK,GAAK,WAC/B,CAsCA,eAAsBE,GAASC,EAA4BC,EAAsC,CAC7F,IAAMC,EAASF,EAAM,OAAS,UACxBG,EAAQH,EAAM,KAAK,MAAMC,EAAK,UAAU,CAAC,EAAE,MAAOA,EAAK,UAAU,CAAC,EAAE,GAAG,EACvE,CAAEG,EAAKC,CAAO,GAAK,MAAMC,GAAgB,qBAAsBH,CAAM,OAAQD,EAAQ,CACvF,OAAQ,MACR,SAAU,OACV,SAAU,UACd,CAAC,GAAG,YAEEK,EAAS,CAAE,QAAS,MAAU,EACpCC,GAAOC,CAAgB,EAAE,aAAaP,EAAQE,EAAI,KAAM,EAAI,EAC5D,IAAMP,EAAQ,MAAMa,GAAeL,EAAO,KAAM,CAAE,OAAAE,EAAQ,QAASI,GAAcX,EAAM,MAAM,CAAE,EAAG,CAC9F,SAAUE,CACd,CAAC,EAED,OAAON,GAAUC,GAASU,EAAO,OAAO,CAC5C,CDtDO,SAASK,GAAOC,EAA+B,CAClD,OAAO,OAAOA,GAAU,UAAYA,IAAU,MAAQ,OAAeA,EAAO,MAAS,QACzF,CAmBO,SAASC,GAAKC,EAAYC,EAAwBC,EAAsB,KAAMC,EAAM,GAAU,CACjG,GAAIF,EAAMD,EAAME,EAAQC,CAAG,EAAG,OAE9B,IAAMC,EAAkCC,GAAYL,EAAK,IAAI,EAE7D,QAAWM,KAAYF,GAAQ,CAAC,EAAG,CAC/B,IAAMN,EAA6CE,EAAMM,CAAQ,EAEjE,GAAI,MAAM,QAAQR,CAAK,EACnB,QAAWS,KAAQT,EAAWD,GAAOU,CAAI,GAAGR,GAAKQ,EAAMN,EAAOD,EAAMM,CAAQ,OACrET,GAAOC,CAAK,GAAGC,GAAKD,EAAOG,EAAOD,EAAMM,CAAQ,CAC/D,CACJ,CAoBO,SAASE,GAAOC,EAA4BC,EAAgBC,EAAqBC,EAA+B,CACnH,GAAM,CAAE,KAAAC,CAAK,EAAIJ,EACbK,EAAO,EACPC,EAAQ,EAEZ,QAASC,EAAQH,EAAK,QAAQ;AAAA,CAAI,EAAGG,IAAU,IAAMA,EAAQN,EAAQM,EAAQH,EAAK,QAAQ;AAAA,EAAMG,EAAQ,CAAC,EACrGF,IACAC,EAAQC,EAAQ,EAGpBJ,EAAQ,SAAW,CAAE,KAAMH,EAAM,OAAQ,KAAAK,EAAM,OAAQJ,EAASK,CAAM,EACtEE,GAAWR,EAAM,KAAMA,EAAM,UAAWG,EAASD,CAAK,CAC1D,CAkBO,SAASO,EAAOT,EAA4BU,EAAYC,EAAuB,CAClF,OAAAX,EAAM,MAAM,KAAK,CAAE,MAAOU,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAAC,CAAK,CAAC,EAEpD,EACX,CAqBO,SAASC,GAAMZ,EAA4BU,EAAYG,EAAqBC,EAA0C,CACzH,IAAMC,EAA4B,CAAE,MAAOL,EAAK,MAAO,IAAKA,EAAK,IAAK,KAAM,EAAG,EAE/E,OAAAV,EAAM,MAAM,KAAKe,CAAI,EACrBf,EAAM,QAAQ,KAAKgB,GAAShB,EAAOa,CAAI,EAAE,KAAKxB,GAAS,CACnD0B,EAAK,KAAOD,EAAKzB,CAAK,CAC1B,EAAI4B,GAAmB,CACnBF,EAAK,KAAOD,EAAK,WAAW,EAC5Bf,GAAOC,EAAOa,EAAK,MAAO,QAAS,CAC/B,OAAQI,EACR,GAAI,eACJ,KAAM,GAAIC,EAAO,MAAO,YAAsBD,GAAQ,SAAW,OAAOA,CAAK,CAAE,EACnF,CAAC,CACL,CAAC,CAAC,EAEK,EACX,CAiBO,SAASE,GAAY9B,EAAqC,CAC7D,GAAIA,EAAM,OAAS,kBAAoBA,EAAM,OAAO,OAAS,aAAc,MAAO,GAElF,GAAM,CAAE,KAAA+B,CAAK,EAAI/B,EAAM,OACvB,GAAI+B,IAASF,EAAO,OAAQ,OAAO7B,EAAM,UAAU,SAAW,EAC9D,GAAI+B,IAASF,EAAO,OAASE,IAASF,EAAO,QAAU7B,EAAM,UAAU,SAAW,EAAG,MAAO,GAE5F,IAAMgC,EAAOhC,EAAM,UAAU,CAAC,EAE9B,OAAOgC,EAAK,OAAS,WAAa,OAAOA,EAAK,OAAU,QAC5D,CAiBO,SAASC,GAAStB,EAA4Ba,EAA8B,CAC/E,IAAMQ,EAAOR,EAAK,UAAU,CAAC,EACvBO,EAAOC,EAAK,OAAS,UAAY,OAAOA,EAAK,KAAK,EAAI,GAE5D,OAAQR,EAAK,OAAO,OAASK,EAAO,QAAWK,GAAUvB,EAAM,QAASoB,CAAI,CAChF,CAgBO,SAASI,GAAUxB,EAA4BT,EAAqB,CACvE,OAAOA,EAAK,OAAS,kBAAoBA,EAAK,OAAO,OAAS,cAAgBS,EAAM,QAAQ,IAAIT,EAAK,OAAO,IAAI,CACpH,CAkBO,SAASkC,GAAYzB,EAA4BT,EAAsD,CAC1G,GAAKA,EACL,IAAI4B,GAAY5B,CAAI,EAAG,MAAO,CAAE,KAAMA,EAAM,OAAQ,EAAG,EACvD,GAAIA,EAAK,OAAS,iBAAkB,OAAOkC,GAAYzB,EAAOT,EAAK,UAAU,EAC7E,GAAI,EAAAA,EAAK,OAAS,kBAAoB,CAAC4B,GAAY5B,EAAK,MAAM,GAE9D,MAAO,CAAE,KAAMA,EAAK,OAAQ,OAAQS,EAAM,KAAK,MAAMT,EAAK,OAAO,IAAKA,EAAK,GAAG,CAAE,EACpF,CAiBO,SAASmC,GAAc1B,EAA4BT,EAA2C,CACjG,IAAMoC,EAAcpC,EAAK,OAAS,yBAA2BA,EAAK,YAAcA,EAChF,GAAIoC,GAAa,OAAS,uBAAyBA,EAAY,aAAa,SAAW,EAAG,OAE1F,GAAM,CAAE,GAAAC,EAAI,KAAAC,CAAK,EAAIF,EAAY,aAAa,CAAC,EAC/C,GAAIC,EAAG,OAAS,aAAc,OAE9B,IAAME,EAASL,GAAYzB,EAAO6B,CAAI,EAEtC,OAAOC,GAAU,CAAEF,EAAIE,CAAO,CAClC,CAiBO,SAASC,GAAY/B,EAA4BT,EAAkC,CACtF,IAAMyC,EAAuB,CAAC,EACxBC,EAAuB,CAAC,EAC1BC,EAAU,GAEd,QAAWC,KAAa5C,EAAK,WAAY,CACrC,IAAMoB,EAAOX,EAAM,KAAK,MAAMmC,EAAU,MAAOA,EAAU,GAAG,EAExDA,EAAU,OAAS,kBAAmBF,EAAM,KAAKtB,CAAI,EAChDX,EAAM,QAAQ,IAAImC,EAAU,MAAM,IAAI,EAAGD,EAAU,GACvDF,EAAM,KAAKrB,CAAI,CACxB,CAEA,GAAI,CAACuB,EAAS,MAAO,GACrB,IAAME,EAASpC,EAAM,KAAK,MAAMT,EAAK,OAAO,MAAOA,EAAK,OAAO,GAAG,EAGlE,OAFIyC,EAAM,OAAS,GAAGC,EAAM,KAAK,KAAMD,EAAM,KAAK,IAAI,CAAE,IAAI,EAExDC,EAAM,OAAS,EAAUxB,EAAOT,EAAOT,EAAM,UAAW6C,CAAO,GAAG,EAE/D3B,EAAOT,EAAOT,EAAM,UAAW0C,EAAM,KAAK,IAAI,CAAE,SAAUG,CAAO,GAAG,CAC/E,CAgBO,SAASC,GAAYrC,EAA4BT,EAAuC,CAC3F,GAAM,CAAE,WAAA+C,CAAW,EAAI/C,EACjBgD,EAAOD,EAAW,OACpB,CAAC,CAAE,MAAAE,CAAM,IAAM,CAACxC,EAAM,QAAQ,IAAIwC,EAAM,OAAS,UAAYA,EAAM,MAAQA,EAAM,IAAI,CACzF,EAEA,OAAID,EAAK,SAAWD,EAAW,OAAe,GAC1CC,EAAK,OAAS,EAAU9B,EAAOT,EAAOT,EAAM,EAAE,EAE3CkB,EAAOT,EAAOT,EAAM,YAAagD,EAAK,IAAIzC,GAAQE,EAAM,KAAK,MAAMF,EAAK,MAAOA,EAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAE,KAAK,CACrH,CAkBO,SAAS2C,GAAkBzC,EAA4BT,EAAqB,CAC/E,IAAMmD,EAAWhB,GAAc1B,EAAOT,CAAI,EAC1C,GAAI,CAACmD,EAAU,MAAO,GAEtB,GAAM,CAAEd,EAAIE,CAAO,EAAIY,EACjB,CAAE,KAAA7B,EAAM,OAAA8B,CAAO,EAAIb,EACnBc,EAASrD,EAAK,OAAS,yBAA2B,UAAY,GAOpE,OALKqC,EAAG,KAAK,WAAW,IAAW,GAAG7B,GAAOC,EAAO4B,EAAG,MAAO,UAAW,CACrE,GAAI,eACJ,KAAM,UAAWA,EAAG,IAAK,8BAA+B,IAAY,6BACxE,CAAC,EAEGf,EAAK,OAAO,OAASK,EAAO,OACrBN,GAAMZ,EAAOT,EAAMsB,EAAMxB,GAAS,GAAIuD,CAAO,SAAUhB,EAAG,IAAK,MAAOvC,CAAM,GAAIsD,CAAO,GAAG,EAE9FlC,EAAOT,EAAOT,EAAM+B,GAAStB,EAAOa,CAAI,EAAIgC,GAAkB7C,EAAM,KAAM4B,EAAG,KAAME,EAAQc,CAAM,EAAI,EAAE,CAClH,CAmBO,SAASE,GAAO9C,EAA4BT,EAAYuC,EAA8BiB,EAA6B,CACtH,GAAM,CAAE,KAAAlC,EAAM,OAAA8B,CAAO,EAAIb,EAEzB,OAAIjB,EAAK,OAAO,OAASK,EAAO,OACrBN,GAAMZ,EAAOT,EAAMsB,EAAMxB,GAAS0D,EAAY,GAAK,GAAI1D,CAAM,GAAIsD,CAAO,EAAE,EAEhFrB,GAAStB,EAAOa,CAAI,EAElBJ,EAAOT,EAAOT,EAAMyD,GAAiBhD,EAAM,KAAM8B,EAAQiB,CAAS,CAAC,EAFvCtC,EAAOT,EAAOT,EAAMwD,EAAY,GAAK,WAAW,CAGvF,CAyBO,SAASE,GAAWjD,EAA4BT,EAAYE,EAAqBC,EAAsB,CAC1G,OAAQH,EAAK,KAAM,CACf,IAAK,aACD,MAAI,CAACS,EAAM,QAAQ,IAAIT,EAAK,IAAI,GAAK,CAACE,EAAe,GAK9C,EAHOC,IAAQ,OAASA,IAAQ,WACjB,EAAE,aAAcD,IAAW,CAACA,EAAO,SAAWyD,GAAc,IAAIxD,CAAG,IAExEe,EAAOT,EAAOT,EAAM,WAAW,EAGpD,IAAK,oBACD,OAAOwC,GAAY/B,EAAOT,CAAI,EAElC,IAAK,yBACD,OAAIkD,GAAkBzC,EAAOT,CAAI,EAAU,GACvCA,EAAK,QAAUA,EAAK,WAAW,OAAS,EAAU,GAE/C8C,GAAYrC,EAAOT,CAAI,EAElC,IAAK,sBACD,OAAOkD,GAAkBzC,EAAOT,CAAI,EAExC,IAAK,sBAAuB,CACxB,GAAIiC,GAAUxB,EAAOT,EAAK,UAAU,EAAG,OAAOkB,EAAOT,EAAOT,EAAM,EAAE,EACpE,IAAMuC,EAASL,GAAYzB,EAAOT,EAAK,UAAU,EAEjD,OAAOuC,IAAW,QAAagB,GAAO9C,EAAOT,EAAMuC,EAAQ,EAAI,CACnE,CAEA,IAAK,iBACL,IAAK,iBAAkB,CACnB,GAAIN,GAAUxB,EAAOT,CAAI,EAAG,OAAOkB,EAAOT,EAAOT,EAAM,WAAW,EAClE,IAAMuC,EAASL,GAAYzB,EAAOT,CAAI,EAEtC,OAAOuC,IAAW,QAAagB,GAAO9C,EAAOT,EAAMuC,EAAQ,EAAK,CACpE,CACJ,CAEA,MAAO,EACX,CAgCA,eAAsBqB,GAClBC,EAAoBtB,EAAgBuB,EAAiBC,EACtC,CACf,GAAID,EAAQ,OAAS,GAAKvB,EAAO,SAAS,cAAc,EAAG,OAAOuB,EAElE,GAAM,CAAE,QAAAnB,CAAQ,EAAIoB,EAAQ,MAC5B,GAAIpB,EAAQ,KAAO,GAAK,CAACmB,EAAQ,SAAS,IAAW,EAAG,OAAOA,EAE/D,IAAMrD,EAA6B,CAC/B,OAAA8B,EACA,QAAAI,EACA,KAAMmB,EACN,KAAMC,EAAQ,KACd,MAAO,CAAC,EACR,QAAS,CAAC,EACV,QAASA,EAAQ,QAAQ,QAAU,CAAC,EACpC,UAAWA,EAAQ,SACvB,EAEA,OAAID,EAAQ,SAASE,EAAa,GAAGjE,GAAK8D,EAAM,QAAS7D,GAAQ,CAC7D,IAAMmD,EAAWhB,GAAc1B,EAAOT,CAAI,EAC1C,GAAI,CAACmD,EAAU,MAAO,GAEtB,GAAM,CAAEd,EAAI,CAAE,KAAAf,CAAK,CAAC,EAAI6B,EACxB,OAAI7B,EAAK,OAAO,OAASK,EAAO,QAAU,CAACI,GAAStB,EAAOa,CAAI,GAAGqB,EAAQ,IAAIN,EAAG,IAAI,EAE9E,EACX,CAAC,EAEDtC,GAAK8D,EAAM,QAASH,GAAW,KAAK,KAAMjD,CAAK,CAAC,EAC5CA,EAAM,QAAQ,OAAS,GAAG,MAAM,QAAQ,IAAIA,EAAM,OAAO,EAEtDwD,EAAWH,EAASrD,EAAM,KAAK,CAC1C,CK/gBA,OAAS,OAAAyD,OAAW,UACpB,OAAS,YAAAC,OAAgB,qBAqDlB,SAASC,GAAmBC,EAA0CC,EAAeC,GAAI,EAAuC,CACnI,GAAIF,IAAgB,OAAW,OAC/B,GAAI,CAAC,MAAM,QAAQA,CAAW,EAAG,CAC7B,GAAI,OAAOA,GAAgB,UAAYA,IAAgB,KAAM,MAAM,IAAI,MAAM,iCAAiC,EAE9G,OAAOA,CACX,CAEA,IAAMG,EAAiC,CAAC,EACxC,GAAIH,EAAY,OAAS,EAAG,OAAOG,EAEnC,GAAI,OAAOH,EAAY,CAAC,GAAM,SAAU,CACpC,QAAWI,KAA8CJ,EAAaG,EAAOC,EAAM,GAAG,EAAIA,EAAM,GAEhG,OAAOD,CACX,CAEA,IAAME,EAASC,GAASJ,GAAI,EAAGK,EAAiB,QAAQN,CAAI,CAAC,EACvDO,EAAQH,GAAUA,IAAW,IAAM,GAAIA,CAAO,IAAM,GAE1D,QAAWI,KAAQC,GAAaR,GAAI,EAAmBF,CAAW,EAAG,CACjE,IAAMW,EAAOH,GAASC,EAAK,WAAWD,CAAK,EAAIC,EAAK,MAAMD,EAAM,MAAM,EAAIC,EACpEG,EAAMD,EAAK,YAAY,GAAG,EAChCR,EAAOS,EAAMD,EAAK,YAAY,GAAG,EAAI,EAAIA,EAAK,MAAM,EAAGC,CAAG,EAAID,CAAI,EAAIF,CAC1E,CAEA,OAAON,CACX,CCzEO,IAAMU,GAAa,CAAE,SAAU,SAAU,QAAS,EAuB5CC,GAAmB,CAAE,UAAW,QAAS,MAAO,EC/B7D,OAAS,mBAAAC,OAAuB,sCA8BzB,SAASC,GAAeC,EAAwC,CACnE,GAAIA,IAAU,MAAQ,OAAOA,GAAU,SAAU,MAAO,GAExD,IAAMC,EAAUD,EAA+B,OAC/C,GAAI,CAAC,MAAM,QAAQC,CAAM,GAAKA,EAAO,SAAW,EAAG,MAAO,GAC1D,IAAMC,EAAQD,EAAO,CAAC,EAEtB,OAAOC,IAAU,MAAQ,OAAOA,GAAU,UAAY,WAAYA,CACtE,CAkCO,SAASC,GAAeH,EAAcI,EAAa,GAAIC,EAAe,GAAa,CACtF,IAAMC,EAAU,CAAE,OAAQN,EAAO,GAAAI,EAAI,WAAYC,CAAK,EAEhDE,EAAcT,GAAgBE,CAAK,EACnCQ,EAAQD,EAAY,MAAM,CAAC,EAEjC,OAAAD,EAAQ,KAAOC,EAAY,QACvBC,GAAO,UAAYA,EAAM,MAAQA,EAAM,SACvCF,EAAQ,SAAW,CACf,KAAME,EAAM,KACZ,KAAMA,EAAM,SACZ,OAAQA,EAAM,OACd,UAAW,MACf,GAGGF,CACX,CZlCO,IAAMG,EAAN,MAAMC,CAAe,CA+GxB,YAAqBC,EAAsBC,EAA+CC,EAAgC,CAAC,EAAG,CAAzG,UAAAF,EAAsB,aAAAC,EAA+C,UAAAC,EACtFH,EAAe,UAAU,IAAIC,EAAM,IAAI,EACvC,KAAK,kBAAoBG,GAAOC,CAAoB,EAAE,OAAOC,IAAW,CACpE,OAAQA,EAAO,OACf,QAASA,EAAO,WAAW,KAAK,IAAI,CACxC,EAAE,EAAE,UAAU,KAAK,mBAAmB,KAAK,IAAI,EAAGC,GAAS,CACvD,MAAMA,CACV,CAAC,CACL,CARqB,KAAsB,QAA+C,KApG1F,OAAwB,WAAyBH,GAAOI,CAAU,EAalE,OAAwB,UAAY,IAAI,IAYvB,kBAaT,MAAyC,CAAC,EAY1C,WAAa,GAab,iBAaA,YAqDR,OAAO,IAAIP,EAAuB,CAC9B,OAAOD,EAAe,UAAU,IAAIC,CAAI,CAC5C,CAmBA,OAAO,KAAmC,CACtC,OAAOD,EAAe,UAAU,OAAO,CAC3C,CA2BA,MAAM,OAAoC,CACtC,GAAM,CAAE,SAAAS,CAAS,EAAI,MAAMC,GAAoB,CAAE,GAAG,KAAK,YAAY,QAAS,QAAS,MAAU,CAAC,EAE5FC,EAA2B,CAAE,KAAM,CAAC,EAAG,QAAS,CAAC,EAAG,MAAO,CAAC,EAAG,QAAS,CAAC,CAAE,EACjF,YAAK,YAAY,KAAK,iBAAiB,MAAM,IAAI,IAAI,OAAO,KAAKF,EAAS,MAAM,CAAC,CAAC,EAAGE,CAAI,EAElFA,CACX,CAyBA,MAAM,OAAuC,CACzC,GAAI,KAAK,WAAY,MAAM,IAAIC,EAAY,WAAY,KAAK,IAAK,cAAc,EAE/E,IAAMD,EAA0B,CAAE,KAAM,CAAC,EAAG,QAAS,CAAC,EAAG,MAAO,CAAC,EAAG,QAAS,CAAC,CAAE,EAC1EE,EAAS,MAAMC,GAAW,CAC5B,GAAG,KAAK,YAAY,QACpB,QAAS,CAAE,KAAK,UAAUH,CAAI,CAAE,EAChC,SAAU,EACV,SAAU,QACd,CAAC,EAAE,MAAM,KAAoB,CAAC,EAAC,EAE/B,OAAO,KAAK,SAASE,EAAQF,CAAI,CACrC,CAoBA,SAAgB,CACZ,KAAK,WAAa,GAClB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,UAAU,EACjCX,EAAe,UAAU,OAAO,KAAK,IAAI,CAC7C,CAmBA,CAAC,OAAO,OAAO,GAAU,CACrB,KAAK,QAAQ,CACjB,CAkBQ,QAAQW,EAAyBI,EAA6CC,EAAqBf,EAAqB,CACxHc,GAAU,QAAQE,GAAYN,EAAM,KAAK,YAAY,YAAcI,EAAUC,EAAOf,CAAI,CAChG,CAiBQ,KAAKU,EAAyBJ,EAAgBN,EAAe,KAAK,KAAY,CAClFU,EAAK,MAAM,KAAKO,GAAeX,aAAiB,MAAQA,EAAQ,IAAI,MAAM,OAAOA,CAAK,CAAC,EAAG,GAAIN,CAAI,CAAC,CACvG,CAkBQ,SAASY,EAAqBF,EAA+C,CACjF,OAAO,OAAO,OAAyBE,EAAQ,CAC3C,KAAMF,EAAK,KACX,OAAQA,EAAK,MACb,QAASA,EAAK,QACd,SAAUA,EAAK,OACnB,CAAC,CACL,CAuBA,MAAc,SAAYA,EAAyBQ,EAAgBC,EAAwB,IAAM,GAA+B,CAC5H,QAAWC,KAAQ,KAAK,MACpB,GAAI,CACA,IAAMR,EAAyC,MAAMM,EAAKE,CAAI,EAC9D,GAAI,CAACR,EAAQ,SAIb,GAFA,KAAK,QAAQF,EAAME,EAAO,OAAQ,QAASQ,EAAK,IAAI,EACpD,KAAK,QAAQV,EAAME,EAAO,SAAU,UAAWQ,EAAK,IAAI,EACpDD,EAAOP,CAAM,EAAG,OAAOA,CAC/B,OAASN,EAAO,CACZ,KAAK,KAAKI,EAAMJ,EAAOc,EAAK,IAAI,CACpC,CAER,CAgBA,MAAc,aAAaC,EAAmD,CAC1E,GAAM,CAAE,YAAAC,CAAY,EAAI,KAAK,YACvBC,EAAuCF,EAAQ,QAAQ,YACvDG,GAAU,OAAOF,GAAgB,SAAWA,EAAY,OAAS,SAAcD,EAAQ,QAAQ,OAEjGA,EAAQ,QAAQ,OAAQ,MAAM,KAAK,iBAAiB,WAAWE,EAAaC,CAAM,EACjF,MAAM,KAAK,iBAAiB,KAAKD,EAAaC,CAAM,CAC7D,CAmBQ,mBAAmB,CAAE,OAAAC,EAAQ,QAAAC,CAAQ,EAAuC,CAChF,GAAI,CAACA,EAAS,OAAO,KAAK,QAAQ,EAElC,IAAMC,EAAW,KAAK,iBAChBtB,EAASuB,EAA0C,CAAC,EAAGH,GAAU,CAAC,EAAGC,CAAO,EAElF,KAAK,iBAAmBvB,GAAO0B,EAAYxB,EAAO,QAAQ,QAAQ,EAClEA,EAAO,QAAQ,YAAcyB,GAAmBzB,EAAO,QAAQ,WAAW,EAC1EA,EAAO,cAAgB,CAAC,EACxBsB,GAAU,QAAQ,EAElB,KAAK,YAActB,EACnB,KAAK,MAAQ,CAAE,GAAGA,EAAO,SAAW,CAAC,EAAG,CAAE,KAAM,KAAK,KAAM,GAAGA,EAAO,SAAU,CAAC,CACpF,CAkBQ,gBAAgB0B,EAAuBC,EAA4C,CACvF,IAAMC,EAAS,KAAK,YAAYD,CAAI,EACpC,GAAI,CAACC,EAAQ,OAEb,IAAMC,EAASH,EAAQC,CAAI,IAAM,CAAC,EAClC,OAAW,CAAEG,EAAKC,CAAM,IAAK,OAAO,QAAQH,CAAM,EAAG,CACjD,IAAMI,EAAU,OAAOD,GAAU,WAAaA,EAAM,KAAK,KAAM,KAAK,IAAI,EAAIA,EAC/CC,GAAY,OAAMH,EAAOC,CAAG,EAAIG,GAAUD,CAAO,EAClF,CACJ,CA0BQ,YAAYE,EAAyC7B,EAAyB8B,EAAuB,GAAY,CACrH,OAAW,CAAE,SAAAC,EAAU,KAAAC,EAAM,QAASC,EAAM,KAAAC,EAAM,KAAAC,EAAM,OAAAC,CAAO,IAAKP,EAAa,CAC7E,IAAMQ,EAA0B,CAAE,KAAAJ,CAAK,EACnCD,IAAS,SAAWK,EAAQ,GAAK,KAAML,CAAK,IAC5CE,IAAMG,EAAQ,SAAW,CAAE,KAAAH,EAAM,KAAAC,EAAM,OAAAC,CAAO,GAElD,IAAM/B,EAAwBiC,GAAiBP,CAAQ,GAAK,UAC5DM,EAAQ,OAAS,CAAE,KAAAL,EAAM,SAAAD,EAAU,QAASE,CAAK,EAEjD,KAAK,QAAQjC,EAAM,CAAEqC,CAAQ,EAAGhC,IAAU,SAAW,CAACyB,EAAc,UAAYzB,EAAO,YAAY,CACvG,CACJ,CAsBA,MAAc,MAAMM,EAAoC4B,EAAyD,CAC7G,GAAM,CAAE,KAAAvC,CAAK,EAAIW,EAEjB,GADA,MAAM,KAAK,SAASX,EAAMU,GAAQA,EAAK,UAAU,CAAE,QAAAC,EAAS,QAAA4B,CAAQ,CAAC,CAAC,EAClE,KAAK,YAAY,OAASvC,EAAK,MAAM,OAAS,EAAG,CACjD,IAAMwC,EAAQ,KAAK,YAAY,MACzBV,EAAc,OAAOU,GAAU,SAAWA,EAAM,YAAc,GACpE,KAAK,YAAY,KAAK,iBAAiB,MAAM7B,EAAQ,MAAM,cAAc,EAAGA,EAAQ,KAAMmB,CAAW,CACzG,CAEA,MAAO,CAAE,OAAQ9B,EAAK,KAAM,CAChC,CAkBA,MAAc,QAAQW,EAAoC8B,EAAkE,CAKxH,OAJe,MAAM,KAAK,SACtB9B,EAAQ,KAAMD,GAAQA,EAAK,YAAY,CAAE,QAAAC,EAAS,KAAA8B,CAAK,CAAC,EAAG,IAAM,EACrE,GAEiB,CAAE,OAAQ9B,EAAQ,KAAK,KAAM,CAClD,CAqBA,MAAc,KAAKA,EAAoC8B,EAA4D,CAC/G,IAAMC,EAAOrD,EAAe,WAAW,QAAQoD,EAAK,IAAI,EAEpDE,EAAiB,UACjBC,EAAWvD,EAAe,WAAW,MAAMqD,CAAI,EAAE,UAAU,MAAQ,GAEvE,GAAI,CACA,IAAMG,EAASC,GAAUJ,EAAME,EAAU,CAAE,WAAY,QAAS,CAAC,EAGjE,GAFAA,EAAW,MAAMG,GAAgBF,EAAQH,EAAME,EAAUjC,CAAO,EAE5D,CAACA,EAAQ,QAAQ,OAAQ,CACzB,IAAMkC,EAASC,GAAUJ,EAAME,EAAU,CAAE,WAAY,QAAS,CAAC,EACjEA,EAAWI,GAAcH,EAAQH,EAAME,EAAU,KAAK,gBAAgB,CAC1E,CACJ,OAAShD,EAAO,CACZ,KAAK,KAAKe,EAAQ,KAAMf,CAAK,CACjC,CAEA,IAAIqD,EAAuB,CAAC,EAC5B,aAAM,KAAK,SAAuBtC,EAAQ,KACtCD,GAAQA,EAAK,SAAS,CAAE,QAAAC,EAAS,SAAAiC,EAAU,OAAAD,EAAQ,KAAAF,CAAK,CAAC,EACzDvC,IACI+C,EAAS,CAAE,GAAGA,EAAQ,GAAG/C,CAAO,EAChCyC,EAASzC,EAAO,QAAUyC,EAEtBzC,EAAO,WAAa,SACpB0C,EAAW,OAAO1C,EAAO,UAAa,SAAWA,EAAO,SAAW,OAAO,KAAKA,EAAO,QAAQ,EAAE,SAAS,GAEtG,GAEf,EAEO,CAAE,GAAG+C,EAAQ,SAAAL,EAAU,OAAAD,EAAQ,OAAQ,CAAC,EAAG,SAAU,CAAC,CAAE,CACnE,CAmBA,MAAc,IAAIhC,EAAoCuC,EAAyC,CAC3F,KAAK,QAAQvC,EAAQ,KAAMuC,EAAY,OAAO,OAAOb,GAAW,CAACA,EAAQ,UAAU,EAAG,OAAO,EAC7F,KAAK,QAAQ1B,EAAQ,KAAMuC,EAAY,SAAS,OAAOb,GAAW,CAACA,EAAQ,UAAU,EAAG,SAAS,EAEjG,IAAMc,EAAQ,CACV,QAAAxC,EACA,SAAU,KAAK,IAAI,EAAIA,EAAQ,MAAM,UAAU,QAAQ,EACvD,YAAa,KAAK,SAASuC,EAAavC,EAAQ,IAAI,CACxD,EAEA,GAAIA,EAAQ,KAAK,MAAM,OAAS,EAC5B,GAAI,CACI,KAAK,YAAY,aAAa,MAAM,KAAK,aAAaA,CAAO,CACrE,OAASf,EAAO,CACZW,GAAeX,EAAgB,GAAI,KAAK,IAAI,CAChD,CAGJ,MAAM,KAAK,SAASe,EAAQ,KAAM,MAAMD,GAAQ,CACxCyC,EAAM,YAAY,OAAO,OAAS,GAAG,MAAMzC,EAAK,YAAYyC,CAAK,EACrE,MAAMzC,EAAK,QAAQyC,CAAK,CAC5B,CAAC,EAED,KAAK,QAAQ,KAAK,CAAE,GAAGA,EAAO,KAAM,KAAM,CAAC,CAC/C,CAqBA,MAAc,MAAMxC,EAAoCyC,EAAmC,CACvF,IAAM/B,EAAU+B,EAAM,eAEtB,GAAI,CACA,QAAWC,KAASC,GAAY,KAAK,gBAAgBjC,EAASgC,CAAK,EAEnE,IAAME,EAAQ,MAAM,KAAK,mBAAmB,EAC5C5C,EAAQ,MAAM,eAAiB,IAAI,IAAI,OAAO,OAAO4C,CAAK,CAAC,EACtDlC,EAAQ,SAAQA,EAAQ,YAAckC,GAC3C5C,EAAQ,MAAM,QAAU6C,GAAc7C,EAAQ,MAAM,eAAgBU,EAAQ,QAAU,CAAC,CAAC,CAC5F,OAASzB,EAAO,CACT6D,GAAe7D,CAAK,GAAKA,EAAM,OAC9Be,EAAQ,KAAK,MAAM,KAAK,GAAGf,EAAM,MAAM,EAEvC,KAAK,KAAKe,EAAQ,KAAMf,EAAO,EAAE,CAEzC,CAEA,MAAM,KAAK,SAASe,EAAQ,KAAMD,GAAQA,EAAK,UAAUC,CAAO,CAAC,CACrE,CAgBA,MAAc,oBAAsD,CAChE,IAAM+C,EAAU,KAAK,iBAAiB,OAAO,QAAQ,QAC/C,CAAE,SAAA5D,CAAS,EAAI,MAAMC,GAAoB,CAAE,GAAG,KAAK,YAAY,QAAS,QAAS,MAAU,CAAC,EAElG,OAAO,OAAO,YAAY,OAAO,KAAKD,EAAS,MAAM,EAAE,IAAIoC,GAAQ,CAC/D,IAAMQ,EAAOiB,GAASD,EAASrE,EAAe,WAAW,QAAQ6C,CAAI,CAAC,EAChE0B,EAAMlB,EAAK,YAAY,GAAG,EAEhC,MAAO,CAAEkB,EAAM,EAAIlB,EAAK,MAAM,EAAGkB,CAAG,EAAIlB,EAAMR,CAAK,CACvD,CAAC,CAAC,CACN,CAoBQ,UAAUlC,EAAiC,CAC/C,MAAO,CACH,KAAM,KAAK,KACX,MAAO,MAAOoD,GAAsC,CAChD,IAAMzC,EAAqC,CACvC,KAAAX,EACA,KAAM,KAAK,KACX,QAASoD,EAAM,eACf,UAAW,KAAK,YAAY,YAC5B,YAAa,KAAK,KAClB,MAAO,CACH,UAAW,IAAI,KACf,QAAS,IAAI,IACb,eAAgB,IAAI,GACxB,CACJ,EAEAA,EAAM,MAAM,KAAK,IAAI,KAAK,KAAMzC,CAAO,CAAC,EACxCyC,EAAM,QAAQ,KAAK,MAAM,KAAK,KAAMzC,EAASyC,EAAM,OAAO,CAAC,EAC3DA,EAAM,OAAO,CAAE,OAAQ,IAAK,EAAG,KAAK,KAAK,KAAK,KAAMzC,CAAO,CAAC,EAC5DyC,EAAM,UAAU,CAAE,OAAQ,IAAK,EAAG,KAAK,QAAQ,KAAK,KAAMzC,CAAO,CAAC,EAClE,MAAM,KAAK,MAAMA,EAASyC,CAAK,EAE/B,KAAK,QAAQ,KAAK,CAAE,QAAAzC,EAAS,QAASyC,EAAM,QAAS,KAAM,OAAQ,CAAC,CACxE,CACJ,CACJ,CACJ,EFlxBO,IAAMS,GAAN,KAAmB,CAmDtB,YAAYC,EAAwCC,EAAgC,CAAC,EAAG,CAApC,UAAAA,EAChD,KAAK,QAAQ,MAAMD,CAAM,EACzB,KAAK,QAAQ,UAAU,KAAK,cAAc,KAAK,IAAI,CAAC,CACxD,CAHoD,KArCnC,QAAU,IAAIE,GAad,QAAUC,GAAOC,CAAoB,EA8CtD,IAAI,MAAiC,CACjC,OAAO,KAAK,QAAQ,KAAK,KAAK,KAAK,OAAO,CAC9C,CAmBA,IAAI,WAA2C,CAC3C,OAAO,KAAK,QAAQ,UAAU,KAAK,KAAK,OAAO,CACnD,CAuBA,IAAI,cAAcJ,EAAiD,CAC/D,KAAK,QAAQ,OAAOA,CAAM,CAC9B,CAqCA,MAAM,MAAMK,EAA6D,CACrE,IAAMC,EAAW,IAAI,IAAI,MAAM,KAAKC,EAAe,IAAI,EAAGC,GAAW,CAAEA,EAAQ,KAAMA,CAAQ,CAAU,CAAC,EAClGC,EAAQ,IAAI,IACZC,EAAQ,QAAQ,cAAoB,EAEpCC,EAAM,CAACC,EAAcC,EAAsB,CAAC,IAAqC,CACnF,GAAIA,EAAK,SAASD,CAAI,EAClB,MAAM,IAAIE,EAAY,iCAAkC,CAAE,GAAGD,EAAMD,CAAK,EAAE,KAAK,UAAK,CAAE,EAAE,EAC5F,GAAI,CAACN,EAAS,IAAIM,CAAI,EAClB,MAAM,IAAIE,EAAY,YAAaD,EAAK,GAAG,EAAE,CAAE,iBAAkBD,CAAK,2BAA2B,EAErG,GAAI,CAACH,EAAM,IAAIG,CAAI,EAAG,CAClB,IAAMG,EAAW,KAAK,YAAYH,CAAI,EAEtCH,EAAM,IAAIG,EAAM,QACX,IAAI,CAAEF,EAAM,QAAS,GAAGK,EAAS,IAAIC,GAAcL,EAAIK,EAAY,CAAE,GAAGH,EAAMD,CAAK,CAAC,CAAC,CAAE,CAAC,EACxF,KAAK,CAAC,CAAE,CAAK,GAAAK,CAAQ,IAAM,CACxB,IAAMC,EAASH,EAAS,OAAO,CAACI,EAAGC,IAAU,OAAO,KAAKH,EAAQG,CAAK,GAAG,UAAU,SAAW,CAAC,CAAC,EAAE,OAAS,CAAC,EAC5G,OAAIF,EAAO,OAAe,KAAK,QAAQN,EAAMM,CAAM,EAE5CZ,EAAS,IAAIM,CAAI,EAAG,MAAM,CACrC,CAAC,CACL,CACJ,CAEA,OAAOH,EAAM,IAAIG,CAAI,CACzB,EAEMK,EAAU,MAAM,KAAKZ,GAAO,OAAOO,GAAQN,EAAS,IAAIM,CAAI,CAAC,GAAKN,EAAS,KAAK,EAAGM,GAAQD,EAAIC,CAAI,CAAC,EAC1G,OAAAF,EAAM,QAAQ,EAEP,QAAQ,IAAIO,CAAO,CAC9B,CAmCA,MAAM,UAAUZ,EAAmE,CAC/E,IAAMgB,EAA4C,CAAC,EAEnD,QAAWb,KAAWD,EAAe,IAAI,GACjC,CAACF,GAASA,EAAM,SAASG,EAAQ,IAAI,KAAGa,EAAOb,EAAQ,IAAI,EAAI,MAAMA,EAAQ,MAAM,GAG3F,OAAOa,CACX,CAoBA,MAAM,QAAwB,CAC1BC,EAAkB,OAAO,CAC7B,CAmBQ,cAActB,EAAsC,CACxD,GAAI,CAACA,EACD,MAAM,IAAIc,EAAY,+CAA+C,EAEzE,QAAWF,KAAQ,OAAO,KAAKZ,EAAO,UAAY,CAAC,CAAC,EAC5CO,EAAe,IAAIK,CAAI,GAC3B,IAAIL,EAAeK,EAAM,KAAK,QAAS,KAAK,IAAI,CAExD,CAkCQ,QAAQA,EAAcW,EAAmD,CAC7E,IAAML,EAASK,EAAa,IAAIP,GAAc,IAAKA,CAAW,GAAG,EAAE,KAAK,IAAI,EACtEQ,EAAyB,CAC3B,CACI,GAAI,oBACJ,KAAM,YAAaZ,CAAK,4BAA6BM,CAAO,UAC5D,MAAO,CAAC,EACR,OAAQ,OACR,SAAU,KACV,WAAYN,CAChB,CACJ,EAEMJ,EAAU,KAAK,QAAQ,SAAS,EAAE,WAAWI,CAAI,EACjDa,EAA0B,CAAE,KAAM,CAAC,EAAG,QAAS,CAAC,EAAG,MAAOD,EAAQ,QAAS,CAAC,CAAE,EAC9EE,EAA+C,CACjD,KAAMD,EAAK,KAAM,QAASA,EAAK,QAAS,OAAQA,EAAK,MAAO,SAAUA,EAAK,OAC/E,EAEA,YAAK,QAAQ,KAAK,CACd,KAAM,MACN,SAAU,EACV,QAAS,CACL,KAAM,KAAK,KACX,KAAAA,EACA,QAASjB,GAAS,SAAW,CAAC,EAC9B,UAAWA,GAAS,aAAe,CAAC,EACpC,YAAaI,EACb,MAAO,CACH,UAAW,IAAI,KACf,QAAS,IAAI,IACb,eAAgB,IAAI,GACxB,CACJ,EACA,YAAAc,CACJ,CAAC,EAEMA,CACX,CAgBQ,YAAYd,EAA6B,CAC7C,MAAO,CAAE,KAAK,QAAQ,SAAS,EAAE,WAAWA,CAAI,GAAG,UAAY,CAAC,CAAE,EAAE,KAAK,CAC7E,CACJ,EepZA,OAAS,cAAAe,OAAkB,wBAC3B,OAAS,WAAAC,OAAe,4BAGxB,OAAS,WAAAC,GAAS,QAAAC,GAAM,YAAAC,OAAgB,qBACxC,OAAS,SAAAC,GAAO,gBAAAC,GAAc,eAAAC,GAAa,aAAAC,GAAW,YAAAC,OAAgB,KA2C/D,IAAMC,EAAN,cAA2BC,EAAwB,CAmEtD,YAAYC,EAAsBC,EAAiC,CAC/D,MAAM,EADwB,aAAAA,EAG9B,KAAK,KAAOC,GAAQF,CAAI,EACxB,KAAK,QAAUG,GAAc,KAAK,SAAS,QAAU,CAAC,EAAG,CACrD,IAAK,KAAK,SAAS,KAAO,EAC9B,CAAC,CACL,CAPkC,QA5DjB,KAQA,QAQA,SAAW,IAAI,IAQf,QAAU,IAAI,IAQvB,cAAgB,EAQhB,MAwDC,UAAUC,EAA+BC,EAAmBC,EAA0C,CAC3G,IAAMC,EAAc,MAAM,UAAUH,EAAgBC,EAAOC,CAAQ,EACnE,MAAI,EAAE,KAAK,gBAAkB,GAAG,KAAK,MAAM,EAEpC,KAAK,cAAc,IAAM,CAC5BC,EAAY,EACR,EAAE,KAAK,gBAAkB,GAAG,KAAK,KAAK,CAC9C,CAAC,CACL,CAQA,IAAY,UAAmB,CAC3B,OAAO,KAAK,SAAS,UAAY,GACrC,CAWQ,OAAc,CAClB,KAAK,MAAM,KAAK,KAAM,KAAK,QAAQ,KAAK,IAAI,EAAG,KAAK,SAAS,SAAS,EAClE,KAAK,SAAS,gBAAgB,KAAK,cAAc,KAAK,IAAI,CAClE,CAYQ,MAAa,CACb,KAAK,OAAO,aAAa,KAAK,KAAK,EACvC,QAAWC,KAAW,KAAK,SAAS,OAAO,EAAGA,EAAQ,MAAM,EAE5D,KAAK,MAAQ,OACb,KAAK,QAAQ,MAAM,EACnB,KAAK,SAAS,MAAM,CACxB,CAcQ,OAAc,CAElB,GADA,KAAK,MAAQ,OACT,KAAK,QAAQ,OAAS,EAAG,OAE7B,IAAMC,EAAQ,OAAO,YAAY,KAAK,OAAO,EAC7C,KAAK,QAAQ,MAAM,EAEnB,GAAI,CACA,KAAK,KAAKA,CAAK,CACnB,MAAQ,CAER,CACJ,CAUQ,aAAaC,EAAoB,CACrC,IAAMF,EAAU,KAAK,SAAS,IAAIE,CAAI,EACjCF,IAELA,EAAQ,MAAM,EACd,KAAK,SAAS,OAAOE,CAAI,EAC7B,CAoBQ,aAAaC,EAAeD,EAAoB,CACpD,IAAME,EAAeC,GAAS,KAAK,KAAMH,CAAI,EACvCI,EAAOC,GAAUL,EAAM,CAAE,eAAgB,EAAM,CAAC,EAChDM,EAAQF,GAAM,eAAe,EAAIG,GAASP,EAAM,CAAE,eAAgB,EAAM,CAAC,EAAII,EAEnF,GAAIA,GAAM,eAAe,EAAG,CACxB,GAAI,CAACE,EAAO,OACRL,IAAU,UAAU,KAAK,aAAaD,CAAI,EAE1CM,EAAM,OAAO,GAAK,KAAK,QAAQN,CAAI,EAAG,KAAK,MAAMA,CAAI,EAChDM,EAAM,YAAY,GAAK,KAAK,SAAS,WAC1C,KAAK,MAAMN,EAAM,KAAK,QAAQ,KAAK,IAAI,EAAG,EAAI,CACtD,CAEA,GAAI,CAAC,KAAK,QAAQE,CAAY,EAAG,OAC7B,KAAK,MAAO,KAAK,MAAM,QAAQ,EAC9B,KAAK,MAAQ,WAAW,KAAK,MAAM,KAAK,IAAI,EAAG,KAAK,QAAQ,EAEjE,IAAIM,EACCF,EAIDE,EAAOF,EAAM,cAAgBA,EAAM,aAHnC,KAAK,aAAaN,CAAI,EACtBQ,EAAO,GAKX,KAAK,QAAQ,IAAIN,EAAc,CAAE,KAAAM,EAAM,MAAAF,CAAM,CAAC,CAClD,CAgBQ,MAAMN,EAAcS,EAAwCC,EAAqB,GAAa,CAClG,GAAI,KAAK,SAAS,IAAIV,CAAI,GAAK,KAAK,QAAQA,CAAI,EAAG,OACnD,IAAMF,EAAUa,GAAMC,GAAaZ,CAAI,EAAG,CAAE,UAAAU,EAAW,OAAAD,CAAO,EAAG,CAACR,EAAOY,IAAa,CAClF,GAAI,CAACA,EAAU,OACf,IAAMC,EAASd,EAAK,SAASa,CAAQ,EAAIb,EAAOe,GAAKf,EAAMa,CAAQ,EACnE,KAAK,aAAaZ,EAAOa,CAAM,CACnC,CAAC,EAEDhB,EAAQ,GAAG,QAAUH,GAAiB,CAClC,KAAK,aAAaK,CAAI,EACtB,KAAK,MAAML,CAAK,CACpB,CAAC,EAED,KAAK,SAAS,IAAIK,EAAMF,CAAO,CACnC,CAWQ,QAAQgB,EAAyB,CAErC,MADI,IAACA,GAAUA,EAAO,SAAS,GAAG,GAC9B,CAAC,KAAK,SAAS,KACXA,GAAUA,EAAO,MAAM,OAAO,EAAE,KAChCE,GAAOA,EAAI,WAAW,GAAG,CAAC,EAKtC,CAeQ,cAAcC,EAAoB,CACtC,IAAMC,EAAuB,CAAED,CAAK,EAEpC,KAAOC,EAAM,QAAQ,CACjB,IAAMC,EAAMD,EAAM,IAAI,EAElBE,EACJ,GAAI,CACAA,EAAUC,GAAYF,EAAK,CAAE,cAAe,EAAK,CAAC,CACtD,MAAQ,CACJ,QACJ,CAEA,QAAWG,KAASF,EAAS,CACzB,IAAMG,EAAOR,GAAKO,EAAM,YAAcH,EAAKG,EAAM,IAAI,EACjD,KAAK,QAAQC,CAAI,IAEjBD,EAAM,eAAe,EACrB,KAAK,MAAMC,EAAM,KAAK,QAAQ,KAAK,IAAI,EAAG,KAAK,SAAS,SAAS,EAC1D,KAAK,SAAS,WAAaD,EAAM,YAAY,GACpDJ,EAAM,KAAKK,CAAI,EAEvB,CACJ,CACJ,CACJ,EA7UanC,EAANoC,EAAA,CAHNC,GAAW,CACR,MAAO,WACX,CAAC,GACYrC,GCnDb,OAAS,WAAAsC,OAAe,OACxB,OAAOC,OAAa,eACpB,OAAS,iBAAAC,OAAqB,SAC9B,OAAS,WAAAC,OAAe,qBAExB,OAAS,UAAAC,OAAc,wBAyCvB,eAAsBC,GAAkBC,EAAcC,EAAcC,EAAQ,CAAC,EAAGC,EAAY,GAAmB,CAC3G,IAAMC,EAAS,CAAE,QAAS,CAAE,OAAQ,CAAC,EAAG,QAAS,CAAC,CAAE,CAAE,EACtD,aAAMC,GAAeL,EAAM,CAAE,QAASM,GAAcC,GAAQN,CAAI,CAAC,EAAG,OAAAG,EAAQ,MAAAF,CAAM,EAAG,CAAE,SAAUD,CAAK,EAAGE,CAAS,EACnGC,EAAO,QAAQ,QAAUA,EAAO,QAAQ,SAErC,CAAC,CACvB,CAsDA,eAAsBI,GAAoDP,EAAcQ,EAAgC,CAAC,EAAe,CAEpI,IAAMC,EADaC,GAAOC,CAAU,EAAE,MAAMX,CAAI,EACxB,UAAU,KAClC,GAAI,CAACS,EAAM,MAAW,CAAC,EAEvB,GAAM,CAAEG,EAAKb,CAAK,GAAK,MAAMc,GAAgBJ,EAAMT,EAAM,CACrD,OAAQ,GACR,OAAQ,MACR,OAAQc,GAAQd,CAAI,EACpB,SAAU,OACV,SAAU,SACV,SAAU,WACV,aAAc,GACd,iBAAkB,GAClB,kBAAmB,EACvB,CAAC,GAAG,YAEEe,EAAcL,GAAOM,CAAU,EACrCN,GAAOO,CAAgB,EAAE,aAAajB,EAAMY,EAAI,KAAM,EAAI,EAE1D,IAAMM,EAAY,MAAMpB,GAAkBC,EAAK,KAAMC,EAAM,CAAC,EAAG,EAAI,EAC7DmB,EAAOJ,EAAY,cAAcK,GAAQ,KAAMF,EAAU,UAAY,CAAC,CAAC,EAE7E,OAAO,OAAOV,EAAMW,CAAI,EACxB,IAAME,EAAS,MAAMvB,GAAkBC,EAAK,KAAMC,EAAMmB,CAAI,EAE5D,OAAOG,EAAU,CAAC,EAAQ,CACtB,MAAO,CACH,OAAQ,CAAE,oBAAqB,YAAa,EAC5C,UAAW,EACf,CACJ,EAAGD,CAAW,CAClB,C1CrGO,SAASE,GAAqBC,EAA+BC,EAAgC,CAC3FA,EAAK,cAEVD,EAAO,SAAW,CACd,KAAM,CACF,QAAS,CACL,YAAaC,EAAK,WACtB,CACJ,CACJ,EACJ,CAyBO,SAASC,GAA0BF,EAA+BC,EAAgC,CACrG,IAAME,EAAeH,EAAO,QAAQ,SAAS,QAAU,OACjDI,EAAW,OAAO,OAAOJ,EAAO,UAAY,CAAC,CAAC,EACjDG,GACCH,EAAO,OAAO,QAAQ,KAAK,IAAKG,CAAa,KAAK,EAGtD,QAAWE,KAAWD,EACdH,EAAK,QAAU,SAAWI,EAAQ,MAAQJ,EAAK,OAC/CA,EAAK,SAAW,SAAWI,EAAQ,QAAQ,OAASJ,EAAK,QACzDA,EAAK,SAAW,SAAWI,EAAQ,QAAQ,OAASJ,EAAK,QACzDA,EAAK,SAAW,SAAWI,EAAQ,QAAQ,OAASJ,EAAK,QACzDA,EAAK,WAAa,SAAWI,EAAQ,QAAQ,SAAWJ,EAAK,UAC7DA,EAAK,WAAa,SAAWI,EAAQ,QAAQ,SAAWJ,EAAK,UAC7DA,EAAK,cAAgB,SAAWI,EAAQ,YAAcJ,EAAK,aAC3DA,EAAK,cAAgB,SACrBI,EAAQ,MAAQ,CAAE,YAAaJ,EAAK,WAAY,GAGjDI,EAAQ,QAAQ,QAAUA,EAAQ,QAAQ,SAAWF,GACpDH,EAAO,OAAO,QAAQ,KAAK,IAAKK,EAAQ,QAAQ,MAAO,KAAK,CAGxE,CAkBA,eAAeC,GAAaC,EAAqBN,EAAyC,CAClFA,EAAK,OAAOO,GAAO,OAAQ,CAAE,UAAW,GAAM,MAAO,EAAK,CAAC,EAE/D,MAAMD,EAAM,MAAMN,EAAK,KAAK,CAChC,CA4BA,eAAsBQ,GAAYT,EAA+BC,EAA0BS,EAA+B,CAEtH,GAAI,GADuBT,EAAK,OAAS,MAAW,IAASD,EAAO,OAAO,OACnD,OAExB,IAAMW,EAAWX,EAAO,OAAO,KAAOC,EAAK,OAAS,OAC9CW,EAAS,IAAIC,GAA4C,CAAE,GAAGb,EAAO,KAAM,EAAGW,CAAQ,EAC5FC,EAAO,UAAUF,EAAO,YAAY,KAAKA,CAAM,CAAC,EAEhD,MAAME,EAAO,MAAM,CACvB,CAoCA,eAAsBE,GAClBC,EAA4Bf,EAA+BC,EAA0BS,EACxE,CAEb,GAAI,EADgBT,EAAK,OAASA,EAAK,QAAU,QAAaD,EAAO,OAAO,OAC1D,OAElB,IAAMgB,EAAQC,GAAOC,CAAU,EAC3BC,EAAgBH,EAAM,MAAMf,EAAK,MAAO,EAAE,QAEzB,IAAImB,EAAa,QAAQ,IAAI,EAAGpB,EAAO,KAAK,EACpD,UAAU,MAAOqB,GAAiB,CAG3C,GAFAL,EAAM,WAAW,EAEdG,IAAkBH,EAAM,MAAMf,EAAK,MAAO,EAAE,QAAS,CACpDkB,EAAgBH,EAAM,MAAMf,EAAK,MAAO,EAAE,QAC1C,IAAMD,EAAS,MAAMsB,GAAmBrB,EAAK,MAAO,EACpDC,GAA0BF,EAAQC,CAAI,EACtCc,EAAa,cAAgBf,CACjC,CAEA,IAAMuB,EAAQ,OAAO,KAAKF,CAAY,EAAE,OACxC,MAAMX,EAAO,QAAQ,GAAIa,CAAM,IAAKA,IAAU,EAAI,OAAS,OAAQ,UAAU,CACjF,CAAC,EAED,MAAMC,GAAiBd,CAAM,CACjC,CAkBA,eAAee,IAAsB,CACjC,QAAQ,IAAIC,GAAS,CAAC,EAItB,IAAMC,EADcV,GAAOW,CAAU,EACP,gBAAgB,QAAQ,IAAI,EAEpD3B,EAAO,CAAC,EACRD,EAAS,MAAMsB,GAAmBK,EAAU,OAAQ1B,CAAI,EAG9DF,GAAqBC,EAAQC,CAAI,EACjCC,GAA0BF,EAAQC,CAAI,EAEtC,IAAMc,EAAe,IAAIc,GAAa7B,EAAkCC,CAAI,EACtES,EAASO,GAAOa,EAAQxB,GAAa,KAAK,CAAC,EAAGS,EAAcd,CAAI,CAAC,EACvEc,EAAa,UAAUL,EAAO,WAAW,KAAKA,CAAM,CAAC,EAEjDT,EAAK,WACLS,EAAO,YAAY,MAAMK,EAAa,UAAUd,EAAK,KAAK,CAAC,EAI/D,MAAMQ,GAAYT,EAAQC,EAAMS,CAAM,EACtC,MAAMI,GAAeC,EAAcf,EAAQC,EAAMS,CAAM,EACvD,MAAMJ,GAAaS,EAAcd,CAAI,CACzC,CAEA,MAAMwB,GAAK","names":["rmSync","process","inject","readFileSync","statSync","resolve","Injectable","FilesModel","path","encoding","target","stats","paths","pathList","resolve","info","entry","readFileSync","oldText","newText","oldLength","newLength","max","prefix","suffix","text","start","end","previous","statSync","__decorateClass","Injectable","resolveError","xterm","cwd","readFileSync","inject","Injectable","normalize","SourceService","FRAMEWORK_PATH_REGEX","EMPTY_MAPPINGS_REGEX","FrameworkService","normalize","cwd","path","inject","FilesModel","position","source","force","key","readFileSync","error","SourceService","__publicField","__decorateClass","Injectable","parseErrorStack","formatErrorCode","highlightCode","getSource","fileName","mapped","inject","FrameworkService","snapshot","FilesModel","code","lines","line","column","_bias","options","after","before","startLine","endLine","getErrorStack","raw","getErrorMetadata","verbose","framework","parsed","resolved","resolveError","path","frame","xterm","formatStack","metadata","name","message","notes","parts","note","stack","xBuildBaseError","message","name","error","options","getErrorMetadata","formatStack","formatErrors","reason","err","xBuildBaseError","metadata","getErrorMetadata","formatStack","process","exit","exec","readline","resolve","stdout","xterm","asciiLogo","bannerUi","prefix","relative","inject","stripAnsi","cursorTo","clearScreenDown","xterm","xterm","okColor","textColor","infoColor","warnColor","pathColor","errorColor","keywordColor","mutedColor","Levels","createActionPrefix","action","symbol","infoColor","prefix","visible","text","stripAnsi","pad","size","sourcePath","file","absolute","resolve","inject","FrameworkService","relative","formatLocation","line","column","separator","mutedColor","pathColor","warnColor","formatDetail","metadata","indent","root","lines","xterm","frame","describeMessage","message","code","typescript","getErrorMetadata","point","printGroup","messages","title","color","left","middle","rows","row","index","id","location","detail","tag","clearScreen","stdout","cursorTo","clearScreenDown","width","formatSize","bytes","printOutputs","metafile","limit","outputs","a","b","listed","sizes","right","total","sum","room","header","okColor","path","rest","more","platform","stdin","stdout","exit","xterm","ANSI","moveCursor","writeRaw","ShadowRenderer","OpenCommands","Keys","session","activity","row","repaint","cursorRow","resolve","answer","data","reported","stdin","writeRaw","stdout","openInBrowser","url","exec","platform","helpMenu","lines","keywordColor","key","describe","server","mutedColor","xterm","drawStatusBar","force","parts","infoColor","pathColor","ANSI","setActivity","text","startInteractive","screen","printed","claimRow","_","handleKey","stopInteractive","moveCursor","anchor","last","back","ShadowRenderer","width","exit","clearScreen","Injectable","inject","Injectable","BehaviorSubject","isObject","item","isPlainObject","prototype","deepMerge","target","sources","source","key","sourceValue","targetValue","equals","a","b","strictCheck","deepEquals","hasKey","obj","val","i","aKeys","bKeys","stringify","value","_","entry","map","distinctUntilChanged","DefaultsCommonConfig","ConfigurationService","initialConfig","DefaultsCommonConfig","BehaviorSubject","deepMerge","selector","observer","map","distinctUntilChanged","prev","curr","equals","partial","mergedConfig","config","__decorateClass","Injectable","ts","Injectable","normalize","relative","dirname","existsSync","parseSync","inject","mkdir","writeFile","join","dirname","relative","removeNode","node","content","edits","cursor","code","applyEdits","left","right","parts","index","i","edit","rewrite","source","target","ts","resolved","extension","relativeFileName","path","resolveSource","parse","statement","HeaderDeclarationBundle","DeclarationModel","ts","inject","FilesModel","path","target","file","cached","entry","entryPoints","outdir","outputs","contents","visited","names","name","pending","dependency","output","existsSync","options","base","join","node","directories","dirname","directory","mkdir","index","writeFile","source","declarationDir","outDir","rootDir","root","relative","closure","nested","exports","statements","binding","module","bindings","star","merged","clauses","surface","parts","HeaderDeclarationBundle","imports","content","service","version","declaration","context","parseSync","kept","body","statement","applyEdits","removeNode","moduleReference","named","exposed","local","bundleEdits","inner","comment","resolved","extension","relativeFileName","resolvedFileName","alias","start","end","code","ts","relative","inject","readdirSync","join","RegexCloser","lit","char","at","glob","index","isGlobstar","group","body","classEnd","openIndex","scan","lead","findClose","cursor","depth","braceClose","comma","compileClass","end","out","segmentEnd","from","compileFragment","isSegmentStart","alt","options","dot","wasStart","guard","DS","GLOBSTAR","nChar","RegexCloser","close","inner","tailEnd","tail","root","src","next","globToRegExp","createMatcher","globs","include","exclude","neg","path","r","collectFiles","base","FrameworkService","matcher","dotted","files","stack","directory","entries","readdirSync","join","entry","LanguageHostService","config","inject","FilesModel","file","path","paths","ts","encoding","extensions","exclude","include","depth","options","globs","createMatcher","target","excluded","relative","TypescriptService","configPath","LanguageHostService","ts","DeclarationModel","file","encoding","force","reloaded","path","entry","reachable","program","ignore","skip","affected","diagnostic","entryPoints","outdir","files","specifier","containingFile","container","dirname","cached","result","relative","key","normalize","instance","version","name","diagnostics","line","character","config","__publicField","__decorateClass","Injectable","Screen","build","inject","ConfigurationService","value","event","infoColor","mutedColor","keywordColor","createActionPrefix","errors","warnings","info","notes","metafile","failed","printOutputs","symbol","errorColor","okColor","name","warnColor","pathColor","diagnostics","logs","total","exit","reason","force","clearScreen","TypescriptService","activity","line","setActivity","lowest","Levels","code","printGroup","__decorateClass","Injectable","yargs","hideBin","Injectable","ArgsConfigPath","ArgsDefaultOptions","ArgsUsageExamples","ArgvModule","argv","yargs","ArgsDefaultOptions","userExtensions","parser","hideBin","originalShowHelp","consoleFunction","ArgsUsageExamples","command","description","__decorateClass","Injectable","inject","http","https","extname","readFileSync","server_default","join","inject","Subject","readdir","stat","readFile","ServerModule","config","dir","FrameworkService","Subject","inject","resolve","reject","err","address","req","res","options","readFileSync","join","defaultHandler","error","ext","requestPath","fullPath","stats","stat","fileList","readdir","file","extname","activePath","segments","path","htmlResult","server_default","contentType","data","readFile","inject","xBuildError","xBuildBaseError","message","options","Subject","parseSync","relative","inject","resolveLevel","overrides","id","level","key","collectLog","logs","message","resolved","collectLogs","messages","name","parseSync","inject","MacroPrefix","MacroScanHint","Macros","MacroFalsyDefines","MacroNameKeys","isDefined","defines","name","value","MacroFalsyDefines","defineDeclaration","code","target","prefix","call","suffix","callback","text","body","params","param","returns","head","defineExpression","statement","tail","analyzeMacros","files","defines","dropped","filesModel","inject","FilesModel","file","content","MacroScanHint","program","parseSync","node","declarator","call","directive","Macros","arg","isDefined","visitorKeys","createRequire","inject","Script","createContext","sandboxExecute","code","sandbox","options","isolateLogs","base","descriptors","context","cwd","build","dirname","basename","DefaultBuildOptions","buildFiles","buildOptions","build","cwd","DefaultBuildOptions","buildFromString","source","path","dirname","basename","analyzeDependencies","serialize","value","stringify","evaluate","state","call","target","thunk","map","output","buildFromString","module","inject","FrameworkService","sandboxExecute","createRequire","isNode","value","walk","node","visit","parent","key","keys","visitorKeys","childKey","item","report","state","offset","level","message","code","line","start","index","collectLog","record","span","text","defer","call","wrap","edit","evaluate","error","Macros","isMacroCall","name","flag","isActive","isDefined","isDropped","macroTarget","declaredMacro","declaration","id","init","target","pruneImport","named","parts","dropped","specifier","source","pruneExport","specifiers","kept","local","expandDeclaration","declared","suffix","prefix","defineDeclaration","expand","statement","defineExpression","expandNode","MacroNameKeys","transformMacros","parse","content","context","MacroScanHint","applyEdits","cwd","relative","extractEntryPoints","entryPoints","root","cwd","result","entry","prefix","relative","FrameworkService","scope","file","collectFiles","name","dot","TextBlocks","DiagnosticLevels","parseErrorStack","isEsbuildError","error","errors","first","errorToMessage","id","name","message","parsedStack","frame","VariantService","_VariantService","name","events$","argv","inject","ConfigurationService","config","error","FilesModel","metafile","analyzeDependencies","logs","xBuildError","result","buildFiles","messages","level","collectLogs","errorToMessage","call","handle","hook","context","declaration","entryPoints","outdir","common","variant","previous","deepMerge","TypescriptService","extractEntryPoints","options","type","source","target","key","value","content","stringify","diagnostics","failOnError","category","code","text","file","line","column","message","DiagnosticLevels","esbuild","types","args","path","loader","contents","parsed","parseSync","transformMacros","resolveSource","merged","buildResult","event","build","block","TextBlocks","files","analyzeMacros","isEsbuildError","rootDir","relative","dot","BuildService","config","argv","Subject","inject","ConfigurationService","names","variants","VariantService","variant","cache","start","run","name","path","xBuildError","dependOn","dependency","results","failed","_","index","result","TypescriptService","dependencies","errors","logs","buildResult","Injectable","Subject","resolve","join","relative","watch","realpathSync","readdirSync","lstatSync","statSync","WatchService","Subject","base","options","resolve","createMatcher","observerOrNext","error","complete","unsubscribe","watcher","batch","path","event","relativePath","relative","link","lstatSync","stats","statSync","type","ignore","recursive","watch","realpathSync","filename","target","join","seg","root","stack","dir","entries","readdirSync","entry","full","__decorateClass","Injectable","resolve","process","createRequire","dirname","inject","execConfigFile","code","path","$argv","isolation","module","sandboxExecute","createRequire","resolve","configFileProvider","argv","text","inject","FilesModel","map","buildFromString","dirname","argvService","ArgvModule","FrameworkService","preConfig","args","process","config","deepMerge","configureEntryPoints","config","args","applyCommandLineOverrides","commonOutDir","variants","variant","executeBuild","build","rmSync","startServer","screen","serveDir","server","ServerModule","startWatchMode","buildService","files","inject","FilesModel","configVersion","WatchService","changedFiles","configFileProvider","count","startInteractive","main","bannerUi","preConfig","ArgvModule","BuildService","Screen"]}
|