@bragduck/cli 2.9.1 → 2.9.2
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/dist/bin/bragduck.js +14 -0
- package/dist/bin/bragduck.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/bragduck.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/constants.ts","../../src/utils/env-loader.ts","../../src/utils/errors.ts","../../src/utils/config-loader.ts","../../src/services/storage.service.ts","../../src/utils/logger.ts","../../src/utils/oauth-server.ts","../../src/utils/browser.ts","../../src/services/auth.service.ts","../../src/utils/version.ts","../../src/services/api.service.ts","../../src/cli.ts","../../src/commands/auth.ts","../../src/services/github.service.ts","../../src/services/git.service.ts","../../src/utils/validators.ts","../../src/ui/theme.ts","../../src/commands/sync.ts","../../node_modules/@inquirer/core/dist/esm/lib/errors.mjs","../../src/sync/adapter-factory.ts","../../src/sync/github-adapter.ts","../../src/sync/bitbucket-adapter.ts","../../src/services/bitbucket.service.ts","../../src/sync/gitlab-adapter.ts","../../src/services/gitlab.service.ts","../../src/sync/jira-adapter.ts","../../src/services/jira.service.ts","../../src/sync/confluence-adapter.ts","../../src/services/confluence.service.ts","../../src/utils/auth-helper.ts","../../src/commands/init.ts","../../src/ui/prompts.ts","../../src/ui/formatters.ts","../../src/ui/spinners.ts","../../src/commands/logout.ts","../../src/commands/scan.ts","../../src/commands/list.ts","../../src/commands/config.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","// Load environment variables\nimport { config } from 'dotenv';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\n\n// Get the directory of this file\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Load .env from the project root (silently)\n// In production, this file is bundled into dist/bin/bragduck.js, so we need to go up 2 levels\n// In development (src/), we'd need to go up 1 level, but the build is what matters\nconfig({ path: join(__dirname, '..', '..', '.env'), debug: false, quiet: true } as any);\n\n// App-wide constants for Bragduck CLI\n\n/**\n * Application name used for storage and configuration\n */\nexport const APP_NAME = 'bragduck';\n\n/**\n * Storage keys for credentials and configuration\n */\nexport const STORAGE_KEYS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n USER_INFO: 'user_info',\n OAUTH_STATE: 'oauth_state',\n} as const;\n\n/**\n * Configuration keys\n */\nexport const CONFIG_KEYS = {\n DEFAULT_COMMIT_DAYS: 'defaultCommitDays',\n AUTO_VERSION_CHECK: 'autoVersionCheck',\n DEFAULT_SOURCE: 'defaultSource',\n SOURCE_PRIORITY: 'sourcePriority',\n JIRA_INSTANCE: 'jiraInstance',\n CONFLUENCE_INSTANCE: 'confluenceInstance',\n GITLAB_INSTANCE: 'gitlabInstance',\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n defaultCommitDays: 30,\n autoVersionCheck: true,\n defaultSource: undefined,\n sourcePriority: undefined,\n jiraInstance: undefined,\n confluenceInstance: undefined,\n gitlabInstance: undefined,\n} as const;\n\n/**\n * OAuth configuration\n */\nexport const OAUTH_CONFIG = {\n CLIENT_ID: 'bragduck-cli',\n CALLBACK_PATH: '/callback',\n TIMEOUT_MS: 120000, // 2 minutes\n MIN_PORT: 8000,\n MAX_PORT: 9000,\n} as const;\n\n/**\n * API endpoints\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n INITIATE: '/v1/auth/cli/initiate',\n TOKEN: '/v1/auth/cli/token',\n },\n BRAGS: {\n CREATE: '/v1/brags',\n LIST: '/v1/brags',\n REFINE: '/v1/brags/refine',\n },\n SUBSCRIPTION: {\n STATUS: '/v1/subscriptions/status',\n },\n ORGANISATIONS: {\n LIST: '/v1/users/{userId}/organisations',\n },\n VERSION: '/v1/cli/version',\n /**\n * @deprecated Use BRAGS.REFINE instead\n */\n COMMITS: {\n REFINE: '/v1/commits/refine',\n },\n} as const;\n\n/**\n * Encryption configuration for file-based credential storage\n */\nexport const ENCRYPTION_CONFIG = {\n ALGORITHM: 'aes-256-gcm',\n KEY_LENGTH: 32,\n IV_LENGTH: 16,\n AUTH_TAG_LENGTH: 16,\n SALT_LENGTH: 32,\n} as const;\n\n/**\n * File paths for credential storage fallback\n */\nexport const STORAGE_PATHS = {\n CREDENTIALS_DIR: '.bragduck',\n CREDENTIALS_FILE: 'credentials.enc',\n CONFIG_FILE: 'config.json',\n} as const;\n\n/**\n * Error codes\n */\nexport const ERROR_CODES = {\n AUTH_FAILED: 'AUTH_FAILED',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n NETWORK_ERROR: 'NETWORK_ERROR',\n GIT_ERROR: 'GIT_ERROR',\n API_ERROR: 'API_ERROR',\n STORAGE_ERROR: 'STORAGE_ERROR',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n} as const;\n\n/**\n * HTTP status codes\n */\nexport const HTTP_STATUS = {\n OK: 200,\n CREATED: 201,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n INTERNAL_SERVER_ERROR: 500,\n} as const;\n\n/**\n * GitHub configuration\n */\nexport const GITHUB_CONFIG = {\n MIN_GH_VERSION: '2.0.0',\n PR_SEARCH_FIELDS: 'number,title,body,author,mergedAt,additions,deletions,changedFiles,url,labels',\n MAX_BODY_LENGTH: 5000,\n} as const;\n\n/**\n * Environment variable names for configuration\n */\nexport const ENV_VARS = {\n SOURCE: 'BRAGDUCK_SOURCE',\n JIRA_INSTANCE: 'BRAGDUCK_JIRA_INSTANCE',\n CONFLUENCE_INSTANCE: 'BRAGDUCK_CONFLUENCE_INSTANCE',\n GITLAB_INSTANCE: 'BRAGDUCK_GITLAB_INSTANCE',\n DEFAULT_COMMIT_DAYS: 'BRAGDUCK_DEFAULT_COMMIT_DAYS',\n AUTO_VERSION_CHECK: 'BRAGDUCK_AUTO_VERSION_CHECK',\n SOURCE_PRIORITY: 'BRAGDUCK_SOURCE_PRIORITY',\n\n // Credentials (for CI/CD)\n JIRA_TOKEN: 'BRAGDUCK_JIRA_TOKEN',\n CONFLUENCE_TOKEN: 'BRAGDUCK_CONFLUENCE_TOKEN',\n GITLAB_TOKEN: 'BRAGDUCK_GITLAB_TOKEN',\n} as const;\n\n/**\n * Project config file names to search for (in order of priority)\n */\nexport const CONFIG_FILES = ['.bragduckrc', '.bragduck/config.json', '.bragduckrc.json'] as const;\n","import type { SourceType } from '../types/source.types.js';\nimport type { EnvironmentConfig } from '../types/config.types.js';\n\n/**\n * Parse a number from environment variable\n */\nfunction parseEnvNumber(key: string): number | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Parse a boolean from environment variable\n * Accepts: true/false, yes/no, 1/0 (case-insensitive)\n */\nfunction parseEnvBoolean(key: string): boolean | undefined {\n const value = process.env[key]?.toLowerCase();\n if (!value) return undefined;\n\n if (['true', 'yes', '1'].includes(value)) return true;\n if (['false', 'no', '0'].includes(value)) return false;\n return undefined;\n}\n\n/**\n * Parse an array from environment variable (comma-separated)\n */\nfunction parseEnvArray(key: string): SourceType[] | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const items = value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n return items.length > 0 ? (items as SourceType[]) : undefined;\n}\n\n/**\n * Validate source type from environment variable\n */\nfunction parseEnvSource(key: string): SourceType | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n return validSources.includes(value as SourceType) ? (value as SourceType) : undefined;\n}\n\n/**\n * Load configuration from environment variables\n * Environment variables follow the pattern: BRAGDUCK_*\n */\nexport function loadEnvConfig(): EnvironmentConfig {\n return {\n // Source configuration\n source: parseEnvSource('BRAGDUCK_SOURCE'),\n jiraInstance: process.env.BRAGDUCK_JIRA_INSTANCE,\n confluenceInstance: process.env.BRAGDUCK_CONFLUENCE_INSTANCE,\n gitlabInstance: process.env.BRAGDUCK_GITLAB_INSTANCE,\n\n // Behavior configuration\n defaultCommitDays: parseEnvNumber('BRAGDUCK_DEFAULT_COMMIT_DAYS'),\n autoVersionCheck: parseEnvBoolean('BRAGDUCK_AUTO_VERSION_CHECK'),\n sourcePriority: parseEnvArray('BRAGDUCK_SOURCE_PRIORITY'),\n\n // Credential overrides (for CI/CD)\n jiraToken: process.env.BRAGDUCK_JIRA_TOKEN,\n confluenceToken: process.env.BRAGDUCK_CONFLUENCE_TOKEN,\n gitlabToken: process.env.BRAGDUCK_GITLAB_TOKEN,\n };\n}\n\n/**\n * Get a specific environment config value\n */\nexport function getEnvConfigValue<K extends keyof EnvironmentConfig>(key: K): EnvironmentConfig[K] {\n const config = loadEnvConfig();\n return config[key];\n}\n\n/**\n * Check if any environment configuration is set\n */\nexport function hasEnvConfig(): boolean {\n const config = loadEnvConfig();\n return Object.values(config).some((value) => value !== undefined);\n}\n","// Custom error classes for Bragduck CLI\n\n/**\n * Base error class for all Bragduck errors\n */\nexport class BragduckError extends Error {\n public code: string;\n public details?: Record<string, any>;\n\n constructor(message: string, code: string, details?: Record<string, any>) {\n super(message);\n this.name = 'BragduckError';\n this.code = code;\n this.details = details;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Authentication-related errors\n */\nexport class AuthenticationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'AUTH_ERROR', details);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Git operation errors\n */\nexport class GitError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GIT_ERROR', details);\n this.name = 'GitError';\n }\n}\n\n/**\n * API communication errors\n */\nexport class ApiError extends BragduckError {\n public statusCode?: number;\n\n constructor(message: string, statusCode?: number, details?: Record<string, any>) {\n super(message, 'API_ERROR', details);\n this.name = 'ApiError';\n this.statusCode = statusCode;\n }\n}\n\n/**\n * Network-related errors\n */\nexport class NetworkError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'NETWORK_ERROR', details);\n this.name = 'NetworkError';\n }\n}\n\n/**\n * Storage-related errors\n */\nexport class StorageError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'STORAGE_ERROR', details);\n this.name = 'StorageError';\n }\n}\n\n/**\n * Validation errors\n */\nexport class ValidationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * OAuth-specific errors\n */\nexport class OAuthError extends AuthenticationError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, details);\n this.name = 'OAuthError';\n }\n}\n\n/**\n * Token expiration error\n */\nexport class TokenExpiredError extends AuthenticationError {\n constructor(message = 'Authentication token has expired') {\n super(message);\n this.name = 'TokenExpiredError';\n this.code = 'TOKEN_EXPIRED';\n }\n}\n\n/**\n * GitHub-related errors\n */\nexport class GitHubError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITHUB_ERROR', details);\n this.name = 'GitHubError';\n }\n}\n\n/**\n * Bitbucket-related errors\n */\nexport class BitbucketError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'BITBUCKET_ERROR', details);\n this.name = 'BitbucketError';\n }\n}\n\n/**\n * GitLab-related errors\n */\nexport class GitLabError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITLAB_ERROR', details);\n this.name = 'GitLabError';\n }\n}\n\n/**\n * Jira-related errors\n */\nexport class JiraError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'JIRA_ERROR', details);\n this.name = 'JiraError';\n }\n}\n\n/**\n * Confluence-related errors\n */\nexport class ConfluenceError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'CONFLUENCE_ERROR', details);\n this.name = 'ConfluenceError';\n }\n}\n\n/**\n * Atlassian-related errors (for shared Atlassian services)\n */\nexport class AtlassianError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'ATLASSIAN_ERROR', details);\n this.name = 'AtlassianError';\n }\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { CONFIG_FILES } from '../constants.js';\nimport { ValidationError } from './errors.js';\nimport type { SourceType } from '../types/source.types.js';\nimport type { ProjectConfig } from '../types/config.types.js';\n\n/**\n * Cache for project config to avoid repeated file system reads\n */\nlet configCache: Map<string, ProjectConfig | null> = new Map();\n\n/**\n * Find and load project config file in the current directory\n */\nexport async function findProjectConfig(): Promise<ProjectConfig | null> {\n const cwd = process.cwd();\n\n // Check cache first\n if (configCache.has(cwd)) {\n return configCache.get(cwd) || null;\n }\n\n // Search for config files in order of priority\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(cwd, filename);\n\n try {\n await fs.access(configPath);\n const config = await loadAndValidateConfig(configPath);\n configCache.set(cwd, config);\n return config;\n } catch {\n // File doesn't exist or is not readable, continue to next\n continue;\n }\n }\n\n // No config file found\n configCache.set(cwd, null);\n return null;\n}\n\n/**\n * Load and validate a project config file\n */\nexport async function loadAndValidateConfig(configPath: string): Promise<ProjectConfig> {\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const config = JSON.parse(content);\n\n // Validate the config structure\n validateProjectConfig(config);\n\n return config as ProjectConfig;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ValidationError(`Invalid JSON in config file: ${configPath}`, {\n originalError: error.message,\n });\n }\n throw error;\n }\n}\n\n/**\n * Validate project config structure\n */\nfunction validateProjectConfig(config: unknown): void {\n if (typeof config !== 'object' || config === null) {\n throw new ValidationError('Config must be a JSON object');\n }\n\n const cfg = config as Record<string, unknown>;\n\n // Validate defaultCommitDays\n if (cfg.defaultCommitDays !== undefined) {\n if (typeof cfg.defaultCommitDays !== 'number') {\n throw new ValidationError('defaultCommitDays must be a number');\n }\n if (cfg.defaultCommitDays < 1 || cfg.defaultCommitDays > 365) {\n throw new ValidationError('defaultCommitDays must be between 1 and 365');\n }\n }\n\n // Validate autoVersionCheck\n if (cfg.autoVersionCheck !== undefined) {\n if (typeof cfg.autoVersionCheck !== 'boolean') {\n throw new ValidationError('autoVersionCheck must be a boolean');\n }\n }\n\n // Validate defaultSource\n if (cfg.defaultSource !== undefined) {\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n if (!validSources.includes(cfg.defaultSource as SourceType)) {\n throw new ValidationError(\n `Invalid defaultSource: ${cfg.defaultSource}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n\n // Validate sourcePriority\n if (cfg.sourcePriority !== undefined) {\n if (!Array.isArray(cfg.sourcePriority)) {\n throw new ValidationError('sourcePriority must be an array');\n }\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n for (const source of cfg.sourcePriority) {\n if (!validSources.includes(source)) {\n throw new ValidationError(\n `Invalid source in sourcePriority: ${source}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n }\n\n // Validate instance URLs\n const instanceFields = ['jiraInstance', 'confluenceInstance', 'gitlabInstance'];\n for (const field of instanceFields) {\n if (cfg[field] !== undefined) {\n if (typeof cfg[field] !== 'string') {\n throw new ValidationError(`${field} must be a string`);\n }\n // Basic hostname/URL validation\n const value = cfg[field] as string;\n if (!value.match(/^[a-zA-Z0-9.-]+(:[0-9]+)?(\\/.*)?$/)) {\n throw new ValidationError(`Invalid ${field}: ${value}`);\n }\n }\n }\n\n // Validate boolean flags\n const booleanFields = ['requireAuthentication', 'skipSourceDetection'];\n for (const field of booleanFields) {\n if (cfg[field] !== undefined && typeof cfg[field] !== 'boolean') {\n throw new ValidationError(`${field} must be a boolean`);\n }\n }\n}\n\n/**\n * Clear the config cache (useful for testing)\n */\nexport function clearConfigCache(): void {\n configCache.clear();\n}\n\n/**\n * Get config value from project config\n */\nexport async function getProjectConfigValue<K extends keyof ProjectConfig>(\n key: K\n): Promise<ProjectConfig[K] | undefined> {\n const config = await findProjectConfig();\n return config?.[key];\n}\n\n/**\n * Check if a project config file exists\n */\nexport async function hasProjectConfig(): Promise<boolean> {\n const config = await findProjectConfig();\n return config !== null;\n}\n","import Conf from 'conf';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { APP_NAME, ENCRYPTION_CONFIG, STORAGE_PATHS, DEFAULT_CONFIG } from '../constants.js';\nimport { loadEnvConfig } from '../utils/env-loader.js';\nimport { findProjectConfig } from '../utils/config-loader.js';\nimport type {\n StoredCredentials,\n ServiceCredentials,\n ServiceType,\n UserInfo,\n OAuthState,\n StorageBackend,\n EncryptedData,\n BragduckConfig,\n} from '../types/config.types.js';\n\n/**\n * Storage service for managing credentials and configuration\n * Uses encrypted file storage for credentials\n *\n * NOTE: OS keychain support (via cross-keychain or similar) can be added in the future.\n * For now, we use secure encrypted file storage with machine-specific keys.\n */\nexport class StorageService {\n private config: Conf<BragduckConfig>;\n private storageBackend: StorageBackend;\n private credentialsDir: string;\n private credentialsFilePath: string;\n\n constructor() {\n // Initialize config management\n this.config = new Conf<BragduckConfig>({\n projectName: APP_NAME,\n defaults: DEFAULT_CONFIG,\n });\n\n // Set up credentials directory and file path\n this.credentialsDir = join(homedir(), STORAGE_PATHS.CREDENTIALS_DIR);\n this.credentialsFilePath = join(this.credentialsDir, STORAGE_PATHS.CREDENTIALS_FILE);\n\n // Use file storage for now (keychain support can be added later)\n this.storageBackend = 'file';\n this.ensureCredentialsDir();\n }\n\n /**\n * Ensure credentials directory exists\n */\n private ensureCredentialsDir(): void {\n if (!existsSync(this.credentialsDir)) {\n mkdirSync(this.credentialsDir, { recursive: true, mode: 0o700 });\n }\n }\n\n /**\n * Encrypt data for file storage\n */\n private encrypt(data: string, key: Buffer): EncryptedData {\n const iv = randomBytes(ENCRYPTION_CONFIG.IV_LENGTH);\n const cipher = createCipheriv(ENCRYPTION_CONFIG.ALGORITHM, key, iv, {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n });\n\n let encrypted = cipher.update(data, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n\n const authTag = cipher.getAuthTag();\n\n return {\n encrypted,\n iv: iv.toString('hex'),\n authTag: authTag.toString('hex'),\n salt: '', // Salt is stored separately\n };\n }\n\n /**\n * Decrypt data from file storage\n */\n private decrypt(encryptedData: EncryptedData, key: Buffer): string {\n const decipher = createDecipheriv(\n ENCRYPTION_CONFIG.ALGORITHM,\n key,\n Buffer.from(encryptedData.iv, 'hex'),\n {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n }\n );\n\n decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));\n\n let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n return decrypted;\n }\n\n /**\n * Derive encryption key from machine-specific data\n */\n private deriveEncryptionKey(salt: Buffer): Buffer {\n // Use machine ID and app name as password\n const password = `${APP_NAME}-${homedir()}-${process.platform}`;\n return scryptSync(password, salt, ENCRYPTION_CONFIG.KEY_LENGTH);\n }\n\n /**\n * Store credentials using encrypted file storage\n */\n async setCredentials(credentials: StoredCredentials): Promise<void> {\n const data = JSON.stringify(credentials);\n\n // Encrypt and store credentials\n const salt = randomBytes(ENCRYPTION_CONFIG.SALT_LENGTH);\n const key = this.deriveEncryptionKey(salt);\n const encrypted = this.encrypt(data, key);\n encrypted.salt = salt.toString('hex');\n\n writeFileSync(this.credentialsFilePath, JSON.stringify(encrypted), {\n mode: 0o600,\n encoding: 'utf8',\n });\n }\n\n /**\n * Retrieve credentials from encrypted file storage\n */\n async getCredentials(): Promise<StoredCredentials | null> {\n if (!existsSync(this.credentialsFilePath)) {\n return null;\n }\n\n try {\n const encryptedData: EncryptedData = JSON.parse(\n readFileSync(this.credentialsFilePath, 'utf8')\n );\n const salt = Buffer.from(encryptedData.salt, 'hex');\n const key = this.deriveEncryptionKey(salt);\n const decrypted = this.decrypt(encryptedData, key);\n return JSON.parse(decrypted);\n } catch (error) {\n console.error('Failed to decrypt credentials:', error);\n return null;\n }\n }\n\n /**\n * Delete credentials from file storage\n */\n async deleteCredentials(): Promise<void> {\n // Delete file if it exists\n if (existsSync(this.credentialsFilePath)) {\n try {\n unlinkSync(this.credentialsFilePath);\n } catch (error) {\n console.error('Failed to delete credentials file:', error);\n }\n }\n }\n\n /**\n * Check if user is authenticated (checks bragduck service)\n */\n async isAuthenticated(): Promise<boolean> {\n // Use the service-aware authentication check to support both legacy and multi-service formats\n return this.isServiceAuthenticated('bragduck');\n }\n\n /**\n * Get credentials for a specific service\n */\n async getServiceCredentials(service: ServiceType): Promise<ServiceCredentials | null> {\n const credentials = await this.getCredentials();\n if (!credentials) return null;\n\n // Handle legacy format for bragduck service\n if (service === 'bragduck' && credentials.accessToken && !credentials.services) {\n return {\n accessToken: credentials.accessToken,\n refreshToken: credentials.refreshToken,\n expiresAt: credentials.expiresAt,\n };\n }\n\n return credentials.services?.[service] || null;\n }\n\n /**\n * Set credentials for a specific service\n */\n async setServiceCredentials(service: ServiceType, creds: ServiceCredentials): Promise<void> {\n let existing = await this.getCredentials();\n\n // Migrate legacy format on first new service addition\n if (existing && existing.accessToken && !existing.services) {\n existing = {\n services: {\n bragduck: {\n accessToken: existing.accessToken,\n refreshToken: existing.refreshToken,\n expiresAt: existing.expiresAt,\n },\n },\n };\n }\n\n const updated: StoredCredentials = {\n ...existing,\n services: {\n ...existing?.services,\n [service]: creds,\n },\n };\n\n await this.setCredentials(updated);\n }\n\n /**\n * Delete credentials for a specific service\n */\n async deleteServiceCredentials(service: ServiceType): Promise<void> {\n const existing = await this.getCredentials();\n if (!existing?.services?.[service]) return;\n\n delete existing.services[service];\n await this.setCredentials(existing);\n }\n\n /**\n * Check if a specific service is authenticated\n */\n async isServiceAuthenticated(service: ServiceType): Promise<boolean> {\n const creds = await this.getServiceCredentials(service);\n if (!creds?.accessToken) return false;\n\n // Check expiration\n if (creds.expiresAt && creds.expiresAt < Date.now()) return false;\n\n return true;\n }\n\n /**\n * List all authenticated services\n */\n async getAuthenticatedServices(): Promise<ServiceType[]> {\n const credentials = await this.getCredentials();\n if (!credentials) return [];\n\n // Handle legacy format\n if (credentials.accessToken && !credentials.services) {\n return ['bragduck'];\n }\n\n if (!credentials.services) return [];\n\n const services: ServiceType[] = [];\n for (const [service, creds] of Object.entries(credentials.services)) {\n if (creds?.accessToken) {\n services.push(service as ServiceType);\n }\n }\n\n return services;\n }\n\n /**\n * Store user information\n */\n setUserInfo(userInfo: UserInfo): void {\n this.config.set('userInfo' as keyof BragduckConfig, userInfo as any);\n }\n\n /**\n * Get user information\n */\n getUserInfo(): UserInfo | null {\n return (this.config.get('userInfo' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete user information\n */\n deleteUserInfo(): void {\n this.config.delete('userInfo' as keyof BragduckConfig);\n }\n\n /**\n * Store OAuth state for CSRF protection\n */\n setOAuthState(state: OAuthState): void {\n this.config.set('oauthState' as keyof BragduckConfig, state as any);\n }\n\n /**\n * Get OAuth state\n */\n getOAuthState(): OAuthState | null {\n return (this.config.get('oauthState' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete OAuth state\n */\n deleteOAuthState(): void {\n this.config.delete('oauthState' as keyof BragduckConfig);\n }\n\n /**\n * Get configuration value with hierarchy resolution\n * Priority: env vars > project config > user config > defaults\n */\n async getConfigWithHierarchy<K extends keyof BragduckConfig>(key: K): Promise<BragduckConfig[K]> {\n // 1. Check environment variable\n const envConfig = loadEnvConfig();\n const envKey = key === 'defaultSource' ? 'source' : key;\n if (envConfig[envKey as keyof typeof envConfig] !== undefined) {\n return envConfig[envKey as keyof typeof envConfig] as BragduckConfig[K];\n }\n\n // 2. Check project config\n const projectConfig = await findProjectConfig();\n if (projectConfig && projectConfig[key] !== undefined) {\n return projectConfig[key] as BragduckConfig[K];\n }\n\n // 3. Check user config\n const userValue = this.config.get(key);\n if (userValue !== undefined) {\n return userValue;\n }\n\n // 4. Return default\n return DEFAULT_CONFIG[key] as BragduckConfig[K];\n }\n\n /**\n * Get configuration value (uses hierarchy resolution)\n */\n getConfig<K extends keyof BragduckConfig>(key: K): BragduckConfig[K] {\n return this.config.get(key);\n }\n\n /**\n * Set configuration value\n */\n setConfig<K extends keyof BragduckConfig>(key: K, value: BragduckConfig[K]): void {\n this.config.set(key, value);\n }\n\n /**\n * Get all configuration (merges all layers)\n * Priority: env vars > project config > user config > defaults\n */\n async getAllConfigWithHierarchy(): Promise<BragduckConfig> {\n const envConfig = loadEnvConfig();\n const projectConfig = await findProjectConfig();\n const userConfig = this.config.store;\n\n // Merge all layers with proper priority\n return {\n ...DEFAULT_CONFIG,\n ...userConfig,\n ...projectConfig,\n ...(envConfig.source && { defaultSource: envConfig.source }),\n ...(envConfig.jiraInstance && { jiraInstance: envConfig.jiraInstance }),\n ...(envConfig.confluenceInstance && { confluenceInstance: envConfig.confluenceInstance }),\n ...(envConfig.gitlabInstance && { gitlabInstance: envConfig.gitlabInstance }),\n ...(envConfig.defaultCommitDays !== undefined && {\n defaultCommitDays: envConfig.defaultCommitDays,\n }),\n ...(envConfig.autoVersionCheck !== undefined && {\n autoVersionCheck: envConfig.autoVersionCheck,\n }),\n ...(envConfig.sourcePriority && { sourcePriority: envConfig.sourcePriority }),\n };\n }\n\n /**\n * Get all configuration (user config only)\n */\n getAllConfig(): BragduckConfig {\n return this.config.store;\n }\n\n /**\n * Reset configuration to defaults\n */\n resetConfig(): void {\n this.config.clear();\n // Re-apply defaults (skip undefined values)\n Object.entries(DEFAULT_CONFIG).forEach(([key, value]) => {\n if (value !== undefined) {\n this.config.set(key as keyof BragduckConfig, value as any);\n }\n });\n }\n\n /**\n * Get current storage backend\n */\n getStorageBackend(): StorageBackend {\n return this.storageBackend;\n }\n\n /**\n * Clear all stored data (credentials + config)\n */\n async clearAll(): Promise<void> {\n await this.deleteCredentials();\n this.deleteUserInfo();\n this.deleteOAuthState();\n this.resetConfig();\n }\n}\n\n// Export singleton instance\nexport const storageService = new StorageService();\n","import chalk from 'chalk';\n\n/**\n * Logger utility for consistent console output\n */\nexport const logger = {\n /**\n * Debug message (only shown when DEBUG env var is set)\n */\n debug: (message: string, ...args: any[]): void => {\n if (process.env.DEBUG) {\n console.log(chalk.gray(`[DEBUG] ${message}`), ...args);\n }\n },\n\n /**\n * Info message\n */\n info: (message: string): void => {\n console.log(chalk.blue(`ℹ ${message}`));\n },\n\n /**\n * Success message\n */\n success: (message: string): void => {\n console.log(chalk.green(`✓ ${message}`));\n },\n\n /**\n * Warning message\n */\n warning: (message: string): void => {\n console.warn(chalk.yellow(`⚠ ${message}`));\n },\n\n /**\n * Error message\n */\n error: (message: string): void => {\n console.error(chalk.red(`✗ ${message}`));\n },\n\n /**\n * Plain log without formatting\n */\n log: (message: string): void => {\n console.log(message);\n },\n};\n","import { createServer, type Server, type IncomingMessage, type ServerResponse } from 'http';\nimport { parse } from 'url';\nimport { OAUTH_CONFIG } from '../constants.js';\nimport { OAuthError } from './errors.js';\nimport { logger } from './logger.js';\n\n/**\n * OAuth callback result\n */\nexport interface OAuthCallbackResult {\n code: string;\n state: string;\n port: number;\n}\n\n/**\n * Find an available port in the configured range\n */\nasync function findAvailablePort(): Promise<number> {\n const { MIN_PORT, MAX_PORT } = OAUTH_CONFIG;\n\n for (let port = MIN_PORT; port <= MAX_PORT; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n const testServer = createServer();\n testServer.once('error', reject);\n testServer.once('listening', () => {\n testServer.close(() => resolve());\n });\n testServer.listen(port, '127.0.0.1');\n });\n return port;\n } catch {\n // Port is in use, try next one\n continue;\n }\n }\n\n throw new OAuthError(`No available ports found in range ${MIN_PORT}-${MAX_PORT}`);\n}\n\n/**\n * Success HTML page to show after authentication\n */\nconst SUCCESS_HTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Successful</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .checkmark {\n font-size: 4rem;\n animation: scale-in 0.3s ease-out;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n @keyframes scale-in {\n from { transform: scale(0); }\n to { transform: scale(1); }\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"checkmark\">✓</div>\n <h1>Authentication Successful!</h1>\n <p>You can now close this window and return to your terminal.</p>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Error HTML page to show on authentication failure\n */\nconst ERROR_HTML = (error: string) => `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Failed</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .error-icon {\n font-size: 4rem;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n .error-details {\n background: rgba(0, 0, 0, 0.2);\n padding: 1rem;\n border-radius: 0.5rem;\n font-family: monospace;\n font-size: 0.9rem;\n margin-top: 1rem;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"error-icon\">✗</div>\n <h1>Authentication Failed</h1>\n <p>Please return to your terminal and try again.</p>\n <div class=\"error-details\">${error}</div>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Start OAuth callback server and wait for callback\n */\nexport async function startOAuthCallbackServer(\n expectedState: string\n): Promise<OAuthCallbackResult> {\n const port = await findAvailablePort();\n const timeout = OAUTH_CONFIG.TIMEOUT_MS;\n\n return new Promise<OAuthCallbackResult>((resolve, reject) => {\n let server: Server | null = null;\n let timeoutId: ReturnType<typeof globalThis.setTimeout> | null = null;\n\n const cleanup = () => {\n if (timeoutId) {\n globalThis.clearTimeout(timeoutId);\n }\n if (server) {\n // Close all connections immediately (Node.js 18+)\n if (typeof (server as any).closeAllConnections === 'function') {\n (server as any).closeAllConnections();\n }\n server.close(() => {\n logger.debug('OAuth server closed');\n });\n server.unref(); // Allow process to exit even if server is still running\n }\n };\n\n const handleRequest = (req: IncomingMessage, res: ServerResponse) => {\n const parsedUrl = parse(req.url || '', true);\n\n logger.debug(`OAuth callback received: ${req.url}`);\n\n // Handle callback request\n if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {\n const { code, state, error, error_description } = parsedUrl.query;\n\n // Check for OAuth errors\n if (error) {\n const errorMsg = error_description || error;\n logger.debug(`OAuth error: ${errorMsg}`);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(String(errorMsg)));\n\n cleanup();\n reject(new OAuthError(`OAuth error: ${errorMsg}`));\n return;\n }\n\n // Validate required parameters\n if (!code || !state) {\n const errorMsg = 'Missing code or state parameter';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Verify state matches (CSRF protection)\n if (state !== expectedState) {\n const errorMsg = 'Invalid state parameter (possible CSRF attack)';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Success!\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(SUCCESS_HTML);\n\n // Give the response time to be sent before closing\n globalThis.setTimeout(() => {\n cleanup();\n resolve({\n code: String(code),\n state: String(state),\n port,\n });\n }, 100);\n return;\n }\n\n // Handle other requests (404)\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n };\n\n // Create server\n server = createServer(handleRequest);\n\n // Handle server errors\n server.on('error', (error) => {\n logger.debug(`OAuth server error: ${error.message}`);\n cleanup();\n reject(new OAuthError(`OAuth server error: ${error.message}`));\n });\n\n // Start server\n server.listen(port, '127.0.0.1', () => {\n logger.debug(\n `OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`\n );\n });\n\n // Set timeout\n timeoutId = globalThis.setTimeout(() => {\n logger.debug('OAuth callback timeout');\n cleanup();\n reject(new OAuthError('Authentication timeout - no callback received within 2 minutes'));\n }, timeout);\n });\n}\n\n/**\n * Get the callback URL for the OAuth flow\n */\nexport async function getCallbackUrl(): Promise<string> {\n const port = await findAvailablePort();\n return `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { logger } from './logger.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Open a URL in the default browser\n */\nexport async function openBrowser(url: string): Promise<void> {\n const platform = process.platform;\n let command: string;\n\n // Determine the command based on the platform\n switch (platform) {\n case 'darwin': // macOS\n command = `open \"${url}\"`;\n break;\n case 'win32': // Windows\n command = `start \"\" \"${url}\"`;\n break;\n default: // Linux and others\n command = `xdg-open \"${url}\"`;\n break;\n }\n\n try {\n logger.debug(`Opening browser with command: ${command}`);\n await execAsync(command);\n logger.debug('Browser opened successfully');\n } catch (error) {\n logger.debug(`Failed to open browser: ${error}`);\n throw new Error(`Failed to open browser automatically. Please open this URL manually:\\n${url}`);\n }\n}\n","import { randomBytes } from 'crypto';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath, URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { ofetch } from 'ofetch';\nimport { OAUTH_CONFIG, API_ENDPOINTS } from '../constants.js';\nimport { storageService } from './storage.service.js';\nimport { startOAuthCallbackServer, getCallbackUrl } from '../utils/oauth-server.js';\nimport { openBrowser } from '../utils/browser.js';\nimport { AuthenticationError, NetworkError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type { ServiceCredentials, UserInfo } from '../types/config.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version and User-Agent string\n */\nfunction getUserAgent(): string {\n try {\n // In production (dist/services/auth.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const version = packageJson.version;\n const platform = process.platform;\n const arch = process.arch;\n return `BragDuck-CLI/${version} (${platform}-${arch})`;\n } catch {\n logger.debug('Failed to read package.json version');\n return 'BragDuck-CLI/2.0.0';\n }\n}\n\n/**\n * Token exchange response from the backend\n */\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type: string;\n user?: UserInfo;\n}\n\n/**\n * Authentication service for managing OAuth flow and tokens\n */\nexport class AuthService {\n private apiBaseUrl: string;\n\n constructor() {\n // Use environment variable or default API URL\n this.apiBaseUrl = process.env.API_BASE_URL || 'https://api.bragduck.com';\n }\n\n /**\n * Generate a random state string for CSRF protection\n */\n private generateState(): string {\n return randomBytes(32).toString('hex');\n }\n\n /**\n * Build the OAuth authorization URL\n */\n private async buildAuthUrl(state: string, callbackUrl: string): Promise<string> {\n const params = new URLSearchParams({\n client_id: OAUTH_CONFIG.CLIENT_ID,\n redirect_uri: callbackUrl,\n state,\n });\n\n return `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.INITIATE}?${params.toString()}`;\n }\n\n /**\n * Exchange authorization code for access token\n */\n private async exchangeCodeForToken(code: string, callbackUrl: string): Promise<TokenResponse> {\n try {\n logger.debug('Exchanging authorization code for token');\n\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n code,\n redirect_uri: callbackUrl,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'authorization_code',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n logger.debug('Token exchange successful');\n return response;\n } catch (error: any) {\n logger.debug(`Token exchange failed: ${error.message}`);\n\n if (error.response) {\n throw new AuthenticationError(\n `Token exchange failed: ${error.response.statusText || 'Unknown error'}`,\n {\n statusCode: error.response.status,\n body: error.response._data,\n }\n );\n }\n\n throw new NetworkError('Failed to connect to authentication server', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Complete OAuth flow: start server, open browser, wait for callback, exchange token\n */\n async login(): Promise<UserInfo> {\n logger.debug('Starting OAuth login flow');\n\n // Generate state for CSRF protection\n const state = this.generateState();\n const callbackUrl = await getCallbackUrl();\n\n // Store state temporarily\n storageService.setOAuthState({\n state,\n createdAt: Date.now(),\n });\n\n logger.debug(`OAuth state: ${state}`);\n logger.debug(`Callback URL: ${callbackUrl}`);\n\n // Build authorization URL\n const authUrl = await this.buildAuthUrl(state, callbackUrl);\n logger.debug(`Authorization URL: ${authUrl}`);\n\n // Start callback server (this will wait for the callback)\n const serverPromise = startOAuthCallbackServer(state);\n\n // Open browser\n try {\n await openBrowser(authUrl);\n } catch {\n // If browser opening fails, show the URL for manual opening\n logger.warning('Could not open browser automatically');\n logger.info(`Please open this URL in your browser:`);\n logger.log(authUrl);\n }\n\n // Wait for callback\n let callbackResult;\n try {\n callbackResult = await serverPromise;\n } catch (error: any) {\n storageService.deleteOAuthState();\n throw error;\n }\n\n // Clear OAuth state\n storageService.deleteOAuthState();\n\n // Exchange code for token\n const tokenResponse = await this.exchangeCodeForToken(callbackResult.code, callbackUrl);\n\n // Calculate expiration time\n const expiresAt = tokenResponse.expires_in\n ? Date.now() + tokenResponse.expires_in * 1000\n : undefined;\n\n // Store credentials for bragduck service\n const credentials: ServiceCredentials = {\n accessToken: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresAt,\n };\n await storageService.setServiceCredentials('bragduck', credentials);\n\n // Store user info if provided\n if (tokenResponse.user) {\n storageService.setUserInfo(tokenResponse.user);\n }\n\n logger.debug('Login successful');\n\n return tokenResponse.user || { id: 'unknown', email: 'unknown', name: 'Unknown User' };\n }\n\n /**\n * Logout: clear all stored credentials and user info\n */\n async logout(): Promise<void> {\n logger.debug('Logging out');\n\n await storageService.deleteCredentials();\n storageService.deleteUserInfo();\n storageService.deleteOAuthState();\n\n logger.debug('Logout complete');\n }\n\n /**\n * Check if user is authenticated\n */\n async isAuthenticated(): Promise<boolean> {\n return storageService.isAuthenticated();\n }\n\n /**\n * Get current access token\n */\n async getAccessToken(): Promise<string | null> {\n const credentials = await storageService.getServiceCredentials('bragduck');\n return credentials?.accessToken || null;\n }\n\n /**\n * Get current user info\n */\n getUserInfo(): UserInfo | null {\n return storageService.getUserInfo();\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refreshToken(): Promise<void> {\n logger.debug('Refreshing access token');\n\n const credentials = await storageService.getServiceCredentials('bragduck');\n if (!credentials?.refreshToken) {\n throw new AuthenticationError('No refresh token available');\n }\n\n try {\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n refresh_token: credentials.refreshToken,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'refresh_token',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n // Calculate expiration time\n const expiresAt = response.expires_in ? Date.now() + response.expires_in * 1000 : undefined;\n\n // Update stored credentials for bragduck service\n const newCredentials: ServiceCredentials = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token || credentials.refreshToken,\n expiresAt,\n };\n await storageService.setServiceCredentials('bragduck', newCredentials);\n\n logger.debug('Token refresh successful');\n } catch (error: any) {\n logger.debug(`Token refresh failed: ${error.message}`);\n\n // If refresh fails, user needs to re-authenticate\n await this.logout();\n throw new AuthenticationError(\n 'Bragduck platform token refresh failed. Please run \"bragduck auth login\" to re-authenticate.'\n );\n }\n }\n}\n\n// Export singleton instance\nexport const authService = new AuthService();\n","import { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport chalk from 'chalk';\nimport boxen from 'boxen';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from './logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get current CLI version from package.json\n */\nexport function getCurrentVersion(): string {\n try {\n // In production (dist/utils/version.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '1.0.0'; // Fallback version\n }\n}\n\n/**\n * Export current version\n */\nexport const version = getCurrentVersion();\n\n/**\n * Compare two semantic versions\n * Returns:\n * 1 if v1 > v2\n * 0 if v1 === v2\n * -1 if v1 < v2\n */\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map((p) => parseInt(p, 10));\n const parts2 = v2.split('.').map((p) => parseInt(p, 10));\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 > part2) return 1;\n if (part1 < part2) return -1;\n }\n\n return 0;\n}\n\n/**\n * Check if a newer version is available\n */\nexport async function checkForUpdates(\n options: {\n silent?: boolean;\n force?: boolean;\n } = {}\n): Promise<{ updateAvailable: boolean; latestVersion: string; currentVersion: string }> {\n const { silent = false, force = false } = options;\n\n try {\n // Skip version check if disabled in config (unless forced)\n if (!force) {\n const autoVersionCheck = storageService.getConfig('autoVersionCheck');\n if (!autoVersionCheck) {\n logger.debug('Version check disabled in config');\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n }\n\n logger.debug('Checking for CLI updates...');\n\n // Check via API service\n const response = await apiService.checkVersion();\n const latestVersion = response.latest_version;\n const currentVersion = version;\n\n logger.debug(`Current version: ${currentVersion}, Latest version: ${latestVersion}`);\n\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;\n\n // Display update notification if not silent and update is available\n if (!silent && updateAvailable) {\n displayUpdateNotification(currentVersion, latestVersion, response.critical_update);\n }\n\n return {\n updateAvailable,\n latestVersion,\n currentVersion,\n };\n } catch (error: any) {\n logger.debug(`Version check failed: ${error.message}`);\n // Don't throw error - version check is non-critical\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n}\n\n/**\n * Display update notification\n */\nfunction displayUpdateNotification(\n currentVersion: string,\n latestVersion: string,\n critical: boolean = false\n): void {\n const urgency = critical\n ? chalk.red.bold('CRITICAL UPDATE')\n : chalk.yellow.bold('Update Available');\n const message =\n `${urgency}\\n\\n` +\n `Current version: ${chalk.dim(currentVersion)}\\n` +\n `Latest version: ${chalk.green(latestVersion)}\\n\\n` +\n `Update with: ${chalk.cyan('npm install -g @bragduck/cli@latest')}`;\n\n console.log('');\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 0, right: 1, bottom: 0, left: 1 },\n borderStyle: 'round',\n borderColor: critical ? 'red' : 'yellow',\n })\n );\n console.log('');\n\n if (critical) {\n logger.warning('This is a critical update. Please update as soon as possible.');\n console.log('');\n }\n}\n\n/**\n * Format version for display\n */\nexport function formatVersion(includePrefix: boolean = true): string {\n const prefix = includePrefix ? 'v' : '';\n return `${prefix}${version}`;\n}\n","import { ofetch, type FetchOptions } from 'ofetch';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { authService } from './auth.service.js';\nimport { API_ENDPOINTS, HTTP_STATUS } from '../constants.js';\nimport { ApiError, NetworkError, TokenExpiredError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type {\n RefineCommitsRequest,\n RefineCommitsResponse,\n RefineBragsRequest,\n RefineBragsResponse,\n CreateBragsRequest,\n CreateBragsResponse,\n ListBragsParams,\n ListBragsResponse,\n GetSubscriptionStatusResponse,\n VersionCheckResponse,\n ApiErrorResponse,\n ListOrganisationsResponse,\n} from '../types/api.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version from package.json\n */\nfunction getCliVersion(): string {\n try {\n // In production (dist/services/api.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '2.0.0'; // Fallback version\n }\n}\n\n/**\n * Get platform information for User-Agent\n */\nfunction getPlatformInfo(): string {\n const platform = process.platform; // darwin, linux, win32, etc.\n const arch = process.arch; // arm64, x64, etc.\n return `${platform}-${arch}`;\n}\n\n/**\n * API service for communicating with the Bragduck backend\n */\nexport class ApiService {\n private baseURL: string;\n private client: typeof ofetch;\n\n constructor() {\n // Use environment variable or default API URL\n this.baseURL = process.env.API_BASE_URL || 'https://api.bragduck.com';\n\n // Create ofetch client with interceptors\n this.client = ofetch.create({\n baseURL: this.baseURL,\n\n // Request interceptor\n onRequest: async ({ request, options }) => {\n logger.debug(`API Request: ${options.method || 'GET'} ${request}`);\n\n // Add User-Agent header for CLI identification\n const cliVersion = getCliVersion();\n const platform = getPlatformInfo();\n const userAgent = `BragDuck-CLI/${cliVersion} (${platform})`;\n\n // Add authentication header\n const token = await authService.getAccessToken();\n\n // Create new headers object\n const newHeaders: Record<string, string> = {\n 'User-Agent': userAgent,\n };\n\n // Copy existing headers if any\n if (options.headers) {\n if (typeof options.headers === 'object' && !Array.isArray(options.headers)) {\n Object.entries(options.headers).forEach(([key, value]) => {\n if (typeof value === 'string') {\n newHeaders[key] = value;\n }\n });\n }\n }\n\n if (token) {\n newHeaders.Authorization = `Bearer ${token}`;\n }\n\n // Ensure Content-Type is set for POST/PUT requests\n if (options.method && ['POST', 'PUT', 'PATCH'].includes(options.method)) {\n newHeaders['Content-Type'] = 'application/json';\n }\n\n options.headers = newHeaders as any;\n },\n\n // Response interceptor for success\n onResponse: ({ response }) => {\n logger.debug(`API Response: ${response.status} ${response.statusText}`);\n },\n\n // Response interceptor for errors\n onResponseError: async ({ request, response }) => {\n const status = response.status;\n\n logger.debug(`API Error: ${status} ${response.statusText} - ${request}`);\n\n // Handle 401 Unauthorized - token expired\n if (status === HTTP_STATUS.UNAUTHORIZED) {\n logger.debug('Token expired, attempting refresh');\n\n try {\n // Try to refresh the token\n await authService.refreshToken();\n\n // Retry the request once with the new token\n logger.debug('Token refreshed, retrying request');\n throw new Error('RETRY_WITH_NEW_TOKEN');\n } catch (error: any) {\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n throw error;\n }\n // If refresh fails, throw TokenExpiredError\n throw new TokenExpiredError(\n 'Your Bragduck platform session has expired. Please run \"bragduck auth login\" to re-authenticate.'\n );\n }\n }\n\n // Parse error response\n let errorMessage = 'An unexpected error occurred';\n let errorDetails: Record<string, any> | undefined;\n\n try {\n const errorData = response._data as ApiErrorResponse;\n if (errorData && errorData.message) {\n errorMessage = errorData.message;\n errorDetails = errorData.details;\n }\n } catch {\n // If we can't parse error, use status text\n errorMessage = response.statusText || errorMessage;\n }\n\n throw new ApiError(errorMessage, status, errorDetails);\n },\n\n // Retry configuration\n retry: 2,\n retryDelay: 1000,\n retryStatusCodes: [408, 409, 425, 429, 500, 502, 503, 504],\n\n // Timeout\n timeout: 30000, // 30 seconds\n });\n }\n\n /**\n * Make API request with retry for token refresh\n */\n private async makeRequest<T>(url: string, options: FetchOptions = {}): Promise<T> {\n try {\n return (await this.client(url, options)) as Promise<T>;\n } catch (error: any) {\n // If we got the special retry signal, retry the request once\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n logger.debug('Retrying request with refreshed token');\n return (await this.client(url, options)) as Promise<T>;\n }\n\n // Handle network errors\n if (error.name === 'FetchError' || error.code === 'ECONNREFUSED') {\n throw new NetworkError('Failed to connect to Bragduck API', {\n originalError: error.message,\n baseURL: this.baseURL,\n });\n }\n\n throw error;\n }\n }\n\n /**\n * Refine brags using AI\n */\n async refineBrags(request: RefineBragsRequest): Promise<RefineBragsResponse> {\n const MAX_TEXT_LENGTH = 10000;\n\n const trimmedRequest = {\n ...request,\n brags: request.brags.map((brag: RefineBragsRequest['brags'][number]) => ({\n ...brag,\n text:\n brag.text && brag.text.length > MAX_TEXT_LENGTH\n ? brag.text.substring(0, MAX_TEXT_LENGTH)\n : brag.text,\n })),\n };\n\n logger.debug(`Refining ${trimmedRequest.brags.length} brags`);\n\n try {\n const response = await this.makeRequest<RefineBragsResponse>(API_ENDPOINTS.BRAGS.REFINE, {\n method: 'POST',\n body: trimmedRequest,\n });\n\n logger.debug(`Successfully refined ${response.refined_brags.length} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine brags');\n throw _error;\n }\n }\n\n /**\n * @deprecated Use refineBrags() instead. Will be removed in v3.0.0\n * Refine commits using AI (legacy endpoint)\n */\n async refineCommits(request: RefineCommitsRequest): Promise<RefineCommitsResponse> {\n logger.debug(`[DEPRECATED] Using legacy refineCommits - migrate to refineBrags`);\n logger.debug(`Refining ${request.commits.length} commits`);\n\n try {\n const response = await this.makeRequest<RefineCommitsResponse>(API_ENDPOINTS.COMMITS.REFINE, {\n method: 'POST',\n body: request,\n });\n\n logger.debug(`Successfully refined ${response.refined_commits.length} commits`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine commits');\n throw _error;\n }\n }\n\n /**\n * Create brags from refined commits\n */\n async createBrags(request: CreateBragsRequest): Promise<CreateBragsResponse> {\n logger.debug(`Creating ${request.brags.length} brags`);\n logger.debug(`Request body: ${JSON.stringify(request, null, 2)}`);\n\n try {\n const response = await this.makeRequest<CreateBragsResponse>(API_ENDPOINTS.BRAGS.CREATE, {\n method: 'POST',\n body: request,\n });\n logger.debug(`Response: ${JSON.stringify(response, null, 2)}`);\n\n logger.debug(`Successfully created ${response.created} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to create brags');\n throw _error;\n }\n }\n\n /**\n * List existing brags\n */\n async listBrags(params: ListBragsParams = {}): Promise<ListBragsResponse> {\n const { limit = 50, offset = 0, tags, search } = params;\n\n logger.debug(`Listing brags: limit=${limit}, offset=${offset}`);\n\n try {\n // Build query parameters\n const queryParams = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (search) {\n queryParams.append('search', search);\n }\n\n if (tags && tags.length > 0) {\n tags.forEach((tag) => queryParams.append('tags[]', tag));\n }\n\n const url = `${API_ENDPOINTS.BRAGS.LIST}?${queryParams.toString()}`;\n\n const response = await this.makeRequest<ListBragsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(\n `Successfully fetched ${response.brags.length} brags (total: ${response.total})`\n );\n return response;\n } catch (_error) {\n logger.debug('Failed to list brags');\n throw _error;\n }\n }\n\n /**\n * List user's organisations\n */\n async listUserOrganisations(userId: string): Promise<ListOrganisationsResponse> {\n logger.debug(`Listing organisations for user: ${userId}`);\n\n try {\n const url = API_ENDPOINTS.ORGANISATIONS.LIST.replace('{userId}', userId);\n\n const response = await this.makeRequest<ListOrganisationsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(`Successfully fetched ${response.items.length} organisations`);\n return response;\n } catch (_error) {\n logger.debug('Failed to list organisations');\n throw _error;\n }\n }\n\n /**\n * Get user's subscription status\n */\n async getSubscriptionStatus(): Promise<GetSubscriptionStatusResponse> {\n logger.debug(`Fetching subscription status from ${API_ENDPOINTS.SUBSCRIPTION.STATUS}`);\n\n try {\n const response = await this.makeRequest<{\n status: string;\n data: GetSubscriptionStatusResponse;\n }>(API_ENDPOINTS.SUBSCRIPTION.STATUS, {\n method: 'GET',\n });\n\n logger.debug(`Subscription API response: ${JSON.stringify(response)}`);\n\n // Unwrap the response - API returns { status: \"success\", data: {...} }\n const subscriptionData = response.data;\n\n logger.debug(\n `Subscription tier: ${subscriptionData.tier}, status: ${subscriptionData.status}`\n );\n return subscriptionData;\n } catch (error) {\n logger.debug(`Failed to fetch subscription status: ${error}`);\n logger.debug(`Error details: ${JSON.stringify(error, null, 2)}`);\n throw error;\n }\n }\n\n /**\n * Check for CLI updates\n */\n async checkVersion(): Promise<VersionCheckResponse> {\n logger.debug('Checking for CLI updates');\n\n try {\n const response = await this.makeRequest<VersionCheckResponse>(API_ENDPOINTS.VERSION, {\n method: 'GET',\n });\n\n logger.debug(`Latest version: ${response.latest_version}`);\n return response;\n } catch {\n logger.debug('Failed to check version');\n // Don't throw error for version check failures\n // Return current version as fallback\n const { version } = await import('../utils/version.js');\n return {\n latest_version: version,\n critical_update: false,\n };\n }\n }\n\n /**\n * Test API connectivity\n */\n async testConnection(): Promise<boolean> {\n try {\n await this.checkVersion();\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Update base URL\n */\n setBaseURL(url: string): void {\n this.baseURL = url;\n // Recreate client with new base URL\n this.client = ofetch.create({\n baseURL: url,\n });\n }\n\n /**\n * Get current base URL\n */\n getBaseURL(): string {\n return this.baseURL;\n }\n}\n\n// Export singleton instance\nexport const apiService = new ApiService();\n","import { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { authCommand } from './commands/auth.js';\nimport { syncCommand } from './commands/sync.js';\nimport { initCommand } from './commands/init.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { scanCommand } from './commands/scan.js';\nimport { listCommand } from './commands/list.js';\nimport { configCommand } from './commands/config.js';\nimport { checkForUpdates } from './utils/version.js';\nimport { logger } from './utils/logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read package.json for version (go up two levels from dist/bin/)\nconst packageJsonPath = join(__dirname, '../../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('bragduck')\n .description('CLI tool for managing developer achievements and brags\\nAliases: bd, duck, brag')\n .version(packageJson.version, '-v, --version', 'Display version number')\n .helpOption('-h, --help', 'Display help information')\n .option('--skip-version-check', 'Skip automatic version check on startup')\n .option('--debug', 'Enable debug mode (shows detailed logs)');\n\n// Auth command - Unified authentication (NEW)\nprogram\n .command('auth [subcommand]')\n .description('Manage authentication (subcommands: login, status, bitbucket, gitlab)')\n .action(async (subcommand) => {\n try {\n await authCommand(subcommand);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Sync command - Unified work item sync (NEW)\nprogram\n .command('sync')\n .description('Sync work items and create brags')\n .option('-d, --days <number>', 'Number of days to scan', (val) => parseInt(val, 10))\n .option('-a, --all', 'Include all items (not just current user)')\n .option('-s, --source <type>', 'Explicit source type (github)')\n .action(async (options) => {\n try {\n await syncCommand(options);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Init command - OAuth authentication (DEPRECATED)\nprogram\n .command('init')\n .description('Authenticate with Bragduck')\n .action(async () => {\n try {\n await initCommand();\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Scan command - Interactive commit selection and brag creation (DEPRECATED)\nprogram\n .command('scan')\n .description('Scan git commits and create brags (deprecated, use sync)')\n .option('-d, --days <number>', 'Number of days to scan', (val) => parseInt(val, 10))\n .option('-a, --all', 'Include all commits (not just current user)')\n .action(async (options) => {\n try {\n await scanCommand(options);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// List command - Display existing brags\nprogram\n .command('list')\n .description('List your existing brags')\n .option('-l, --limit <number>', 'Number of brags to display', (val) => parseInt(val, 10), 50)\n .option('-o, --offset <number>', 'Number of brags to skip', (val) => parseInt(val, 10), 0)\n .option('-t, --tags <tags>', 'Filter by tags (comma-separated)')\n .option('-s, --search <query>', 'Search brags by keyword')\n .option('--oneline', 'Show only date and title for each brag')\n .action(async (options) => {\n try {\n await listCommand(options);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Logout command - Clear credentials\nprogram\n .command('logout')\n .description('Clear stored credentials')\n .action(async () => {\n try {\n await logoutCommand();\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Config command - Manage CLI configuration\nprogram\n .command('config [subcommand] [key] [value]')\n .description('Manage CLI configuration (subcommands: list, get, set)')\n .action(async (subcommand, key, value) => {\n try {\n await configCommand(subcommand, key, value);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Hook to run before any command execution\nprogram.hook('preAction', async () => {\n const options = program.opts();\n\n // Enable debug mode if --debug flag is set\n if (options.debug) {\n process.env.DEBUG = 'true';\n logger.debug('Debug mode enabled');\n }\n\n // Check for updates (unless --skip-version-check is set or --version/--help is used)\n const isVersionOrHelp =\n process.argv.includes('--version') ||\n process.argv.includes('-v') ||\n process.argv.includes('--help') ||\n process.argv.includes('-h');\n\n if (!options.skipVersionCheck && !isVersionOrHelp) {\n try {\n await checkForUpdates({ silent: false });\n } catch {\n // Non-critical, continue execution\n logger.debug('Version check failed, continuing...');\n }\n }\n});\n\n// Parse command line arguments\nprogram.parse(process.argv);\n\n// Show help if no command is provided\nif (!process.argv.slice(2).length) {\n program.outputHelp();\n}\n","import boxen from 'boxen';\nimport chalk from 'chalk';\nimport { input } from '@inquirer/prompts';\nimport { authService } from '../services/auth.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { githubService } from '../services/github.service.js';\nimport { logger } from '../utils/logger.js';\nimport { theme, colors, boxStyles } from '../ui/theme.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport type { ServiceCredentials } from '../types/config.types.js';\nimport type { BitbucketUser } from '../types/bitbucket.types.js';\nimport type { GitLabUser } from '../types/gitlab.types.js';\n\n/**\n * Auth command: Unified authentication management\n */\nexport async function authCommand(subcommand?: string): Promise<void> {\n // Default to login if no subcommand\n if (!subcommand || subcommand === 'login') {\n await authLogin();\n } else if (subcommand === 'status') {\n await authStatus();\n } else if (subcommand === 'bitbucket') {\n await authBitbucket();\n } else if (subcommand === 'gitlab') {\n await authGitLab();\n } else if (subcommand === 'atlassian') {\n await authAtlassian();\n } else {\n logger.error(`Unknown auth subcommand: ${subcommand}`);\n logger.info('Available subcommands: login, status, bitbucket, gitlab, atlassian');\n process.exit(1);\n }\n}\n\n/**\n * Auth login: Authenticate with Bragduck\n */\nasync function authLogin(): Promise<void> {\n logger.log('');\n logger.info('Authenticating with Bragduck...');\n logger.log('');\n\n // Check if already authenticated\n const isAuthenticated = await storageService.isServiceAuthenticated('bragduck');\n if (isAuthenticated) {\n const userInfo = authService.getUserInfo();\n if (userInfo) {\n logger.log(\n boxen(\n `${chalk.yellow('Already authenticated!')}\\n\\n` +\n `${chalk.gray('User:')} ${userInfo.name}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('Run')} ${chalk.cyan('bragduck logout')} ${chalk.dim('to sign out')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n }\n )\n );\n logger.log('');\n return;\n }\n }\n\n // Perform OAuth login\n try {\n const userInfo = await authService.login();\n\n logger.log('');\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Successfully authenticated!')}\\n\\n` +\n `${chalk.gray('Welcome,')} ${chalk.cyan(userInfo.name)}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('Use')} ${chalk.cyan('bragduck sync')} ${chalk.dim('to create brags')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(`${chalk.red.bold('✗ Authentication Failed')}\\n\\n` + `${err.message}`, {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'red',\n })\n );\n process.exit(1);\n }\n}\n\n/**\n * Auth status: Show authentication status for all services\n */\nasync function authStatus(): Promise<void> {\n logger.log('');\n logger.info('Authentication Status:');\n logger.log('');\n\n const services = await storageService.getAuthenticatedServices();\n\n // Show Bragduck status\n const bragduckAuth = await storageService.isServiceAuthenticated('bragduck');\n if (bragduckAuth) {\n const userInfo = authService.getUserInfo();\n logger.info(`${colors.success('✓')} Bragduck: ${userInfo?.name || 'Authenticated'}`);\n } else {\n logger.info(`${colors.error('✗')} Bragduck: Not authenticated`);\n }\n\n // Show GitHub CLI status (external tool)\n const ghStatus = await githubService.getAuthStatus();\n if (ghStatus.installed) {\n if (ghStatus.authenticated) {\n logger.info(`${colors.success('✓')} GitHub CLI (gh): Authenticated`);\n } else {\n logger.info(`${colors.error('✗')} GitHub CLI (gh): Not authenticated`);\n logger.info(theme.secondary(' Run: gh auth login'));\n }\n } else {\n logger.info(`${colors.error('✗')} GitHub CLI (gh): Not installed`);\n logger.info(theme.secondary(' Install from: https://cli.github.com'));\n }\n\n // Show other services (GitHub, etc.)\n for (const service of services) {\n if (service !== 'bragduck') {\n logger.info(`${colors.success('✓')} ${service}: Authenticated`);\n }\n }\n\n logger.log('');\n\n // Show help message if no services authenticated\n if (services.length === 0) {\n logger.info(`Run ${theme.command('bragduck auth login')} to authenticate with Bragduck`);\n logger.log('');\n }\n}\n\n/**\n * Auth Bitbucket: Authenticate with Bitbucket using API Token\n */\nasync function authBitbucket(): Promise<void> {\n logger.log('');\n logger.log(\n boxen(\n theme.info('Bitbucket API Token Authentication') +\n '\\n\\n' +\n 'Create an API Token at:\\n' +\n colors.highlight('https://bitbucket.org/account/settings/api-token/new') +\n '\\n\\n' +\n 'Required scopes:\\n' +\n ' • pullrequest:read\\n' +\n ' • repository:read\\n' +\n ' • account:read\\n\\n' +\n theme.warning('Note: API tokens expire (max 1 year)'),\n boxStyles.info\n )\n );\n logger.log('');\n\n try {\n const email = await input({\n message: 'Atlassian account email:',\n validate: (value) => (value.includes('@') ? true : 'Please enter a valid email address'),\n });\n\n const apiToken = await input({\n message: 'API Token:',\n validate: (value) => (value.length > 0 ? true : 'API token cannot be empty'),\n });\n\n const tokenExpiry = await input({\n message: 'Token expiry date (YYYY-MM-DD, optional):',\n default: '',\n validate: (value) => {\n if (!value) return true; // Optional\n const date = new Date(value);\n return !isNaN(date.getTime()) ? true : 'Please enter a valid date (YYYY-MM-DD)';\n },\n });\n\n // Test credentials by fetching user info\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n const response = await fetch('https://api.bitbucket.org/2.0/user', {\n headers: { Authorization: `Basic ${auth}` },\n });\n\n if (!response.ok) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + 'Invalid email or API token',\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n\n const user = (await response.json()) as BitbucketUser;\n\n // Store credentials\n const credentials: ServiceCredentials = {\n accessToken: apiToken,\n username: email, // Store email in username field\n };\n\n // Add expiry if provided\n if (tokenExpiry) {\n const expiryDate = new Date(tokenExpiry);\n credentials.expiresAt = expiryDate.getTime();\n }\n\n await storageService.setServiceCredentials('bitbucket', credentials);\n\n logger.log('');\n logger.log(\n boxen(\n theme.success('✓ Successfully authenticated with Bitbucket') +\n '\\n\\n' +\n `Email: ${email}\\n` +\n `User: ${user.display_name}\\n` +\n (tokenExpiry ? `Expires: ${tokenExpiry}` : ''),\n boxStyles.success\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + (err.message || 'Unknown error'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n\n/**\n * Auth GitLab: Authenticate with GitLab using Personal Access Token\n */\nasync function authGitLab(): Promise<void> {\n logger.log('');\n logger.log(\n boxen(\n theme.info('GitLab Personal Access Token Authentication') +\n '\\n\\n' +\n 'Create a Personal Access Token at:\\n' +\n colors.highlight('https://gitlab.com/-/profile/personal_access_tokens') +\n '\\n\\n' +\n 'Required scopes:\\n' +\n ' • api (full API access)\\n' +\n ' • read_api (read API)\\n' +\n ' • read_user (read user info)\\n\\n' +\n theme.warning('For self-hosted GitLab, check your instance docs'),\n boxStyles.info\n )\n );\n logger.log('');\n\n try {\n const instanceUrl = await input({\n message: 'GitLab instance URL (press Enter for gitlab.com):',\n default: 'https://gitlab.com',\n });\n\n const accessToken = await input({\n message: 'Personal Access Token:',\n validate: (value) => (value.length > 0 ? true : 'Token cannot be empty'),\n });\n\n // Test credentials by fetching user info\n const testUrl = `${instanceUrl.replace(/\\/$/, '')}/api/v4/user`;\n const response = await fetch(testUrl, {\n headers: { 'PRIVATE-TOKEN': accessToken },\n });\n\n if (!response.ok) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + 'Invalid instance URL or access token',\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n\n const user = (await response.json()) as GitLabUser;\n\n // Store credentials\n const credentials: ServiceCredentials = {\n accessToken,\n instanceUrl: instanceUrl === 'https://gitlab.com' ? undefined : instanceUrl,\n };\n\n await storageService.setServiceCredentials('gitlab', credentials);\n\n logger.log('');\n logger.log(\n boxen(\n theme.success('✓ Successfully authenticated with GitLab') +\n '\\n\\n' +\n `Instance: ${instanceUrl}\\n` +\n `User: ${user.name} (@${user.username})`,\n boxStyles.success\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + (err.message || 'Unknown error'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n\n/**\n * Auth Atlassian: Authenticate with Atlassian services (Jira, Confluence, Bitbucket)\n */\nasync function authAtlassian(): Promise<void> {\n logger.log('');\n logger.log(\n boxen(\n theme.info('Atlassian API Token Authentication') +\n '\\n\\n' +\n 'This token works for Jira, Confluence, and Bitbucket\\n\\n' +\n 'Create an API Token at:\\n' +\n colors.highlight('https://id.atlassian.com/manage-profile/security/api-tokens') +\n '\\n\\n' +\n 'Required access:\\n' +\n ' • Jira: Read issues\\n' +\n ' • Confluence: Read pages\\n' +\n ' • Bitbucket: Read repositories',\n boxStyles.info\n )\n );\n logger.log('');\n\n try {\n const instanceUrl = await input({\n message: 'Atlassian instance URL (e.g., company.atlassian.net):',\n validate: (value) => (value.length > 0 ? true : 'Instance URL cannot be empty'),\n });\n\n const email = await input({\n message: 'Atlassian account email:',\n validate: (value) => (value.includes('@') ? true : 'Please enter a valid email address'),\n });\n\n const apiToken = await input({\n message: 'API Token:',\n validate: (value) => (value.length > 0 ? true : 'API token cannot be empty'),\n });\n\n // Test credentials with Jira API\n const testInstanceUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n const response = await fetch(`${testInstanceUrl}/rest/api/2/myself`, {\n headers: { Authorization: `Basic ${auth}` },\n });\n\n if (!response.ok) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') +\n '\\n\\n' +\n 'Invalid instance URL, email, or API token\\n' +\n 'Make sure the instance URL is correct (e.g., company.atlassian.net)',\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n\n const user = (await response.json()) as { displayName: string; emailAddress: string };\n\n // Store credentials for all Atlassian services\n const credentials: ServiceCredentials = {\n accessToken: apiToken,\n username: email,\n instanceUrl: instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`,\n };\n\n await storageService.setServiceCredentials('jira', credentials);\n await storageService.setServiceCredentials('confluence', credentials);\n // Also update bitbucket credentials if needed (for consistency)\n await storageService.setServiceCredentials('bitbucket', {\n ...credentials,\n instanceUrl: 'https://api.bitbucket.org', // Bitbucket uses different API base\n });\n\n logger.log('');\n logger.log(\n boxen(\n theme.success('✓ Successfully authenticated with Atlassian') +\n '\\n\\n' +\n `Instance: ${instanceUrl}\\n` +\n `User: ${user.displayName}\\n` +\n `Email: ${user.emailAddress}\\n\\n` +\n 'Services configured:\\n' +\n ' • Jira\\n' +\n ' • Confluence\\n' +\n ' • Bitbucket',\n boxStyles.success\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + (err.message || 'Unknown error'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { GitHubError, GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type { GitHubPR, FetchPRsOptions, GitHubRepositoryInfo } from '../types/github.types.js';\nimport type { GitCommit } from '../types/git.types.js';\nimport { gitService } from './git.service.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * GitHub service for interacting with GitHub via gh CLI\n */\nexport class GitHubService {\n private readonly MAX_BODY_LENGTH = 5000;\n private readonly PR_SEARCH_FIELDS =\n 'number,title,body,author,mergedAt,additions,deletions,changedFiles,url,labels';\n\n /**\n * Check if GitHub CLI is installed and available\n */\n private async checkGitHubCLI(): Promise<boolean> {\n try {\n await execAsync('command gh --version');\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Validate that GitHub CLI is installed\n */\n private async ensureGitHubCLI(): Promise<void> {\n const isInstalled = await this.checkGitHubCLI();\n if (!isInstalled) {\n throw new GitHubError('GitHub CLI (gh) is not installed', {\n hint: 'Install from https://cli.github.com/',\n });\n }\n }\n\n /**\n * Check if user is authenticated with GitHub CLI\n */\n private async checkAuthentication(): Promise<boolean> {\n try {\n await execAsync('command gh auth status');\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Ensure user is authenticated with GitHub CLI\n */\n private async ensureAuthentication(): Promise<void> {\n const isAuthenticated = await this.checkAuthentication();\n if (!isAuthenticated) {\n throw new GitHubError('Not authenticated with GitHub', {\n hint: 'Run \"gh auth login\" to authenticate',\n });\n }\n }\n\n /**\n * Check GitHub CLI authentication status\n * Returns object with installation and authentication status\n */\n async getAuthStatus(): Promise<{ installed: boolean; authenticated: boolean }> {\n const installed = await this.checkGitHubCLI();\n if (!installed) {\n return { installed: false, authenticated: false };\n }\n\n const authenticated = await this.checkAuthentication();\n return { installed, authenticated };\n }\n\n /**\n * Validate that the current repository is hosted on GitHub\n */\n async validateGitHubRepository(): Promise<void> {\n try {\n await this.ensureGitHubCLI();\n await this.ensureAuthentication();\n\n // Check if current directory is a git repo\n await gitService.validateRepository();\n\n // Try to get GitHub repo info using gh CLI\n const { stdout } = await execAsync('command gh repo view --json url');\n const data = JSON.parse(stdout);\n\n if (!data.url) {\n throw new GitHubError('This repository is not hosted on GitHub', {\n hint: 'Only GitHub repositories are currently supported for PR scanning',\n });\n }\n } catch (error: any) {\n if (error instanceof GitHubError || error instanceof GitError) {\n throw error;\n }\n\n // Handle gh CLI errors\n if (error.message?.includes('not a git repository')) {\n throw new GitHubError('Not a git repository', {\n hint: 'Navigate to a git repository directory',\n });\n }\n\n if (error.message?.includes('Could not resolve to a Repository')) {\n throw new GitHubError('This repository is not hosted on GitHub', {\n hint: 'Only GitHub repositories are currently supported for PR scanning',\n });\n }\n\n throw new GitHubError('Failed to validate GitHub repository', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Get GitHub repository information\n */\n async getRepositoryInfo(): Promise<GitHubRepositoryInfo> {\n try {\n await this.ensureGitHubCLI();\n\n // Get repo info from gh CLI\n const { stdout } = await execAsync(\n 'command gh repo view --json owner,name,url,nameWithOwner'\n );\n const data = JSON.parse(stdout);\n\n return {\n owner: data.owner.login,\n name: data.name,\n fullName: data.nameWithOwner,\n url: data.url,\n isGitHub: true,\n };\n } catch (error: any) {\n if (error instanceof GitHubError || error instanceof GitError) {\n throw error;\n }\n throw new GitHubError('Failed to get GitHub repository information', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Get the current authenticated GitHub user\n */\n async getCurrentGitHubUser(): Promise<string | null> {\n try {\n const { stdout } = await execAsync('command gh api user --jq .login');\n return stdout.trim() || null;\n } catch {\n logger.debug('Failed to get GitHub user');\n return null;\n }\n }\n\n /**\n * Fetch merged PRs from GitHub\n */\n async getMergedPRs(options: FetchPRsOptions = {}): Promise<GitHubPR[]> {\n const { days = 30, limit, author } = options;\n\n try {\n await this.ensureGitHubCLI();\n await this.ensureAuthentication();\n\n logger.debug(`Fetching merged PRs from the last ${days} days`);\n\n // Calculate date for filtering\n const since = new Date();\n since.setDate(since.getDate() - days);\n const sinceDate = since.toISOString().split('T')[0]; // YYYY-MM-DD\n\n // Build search query with date and optional author filter\n let searchQuery = `merged:>=${sinceDate}`;\n if (author) {\n searchQuery += ` author:${author}`;\n }\n\n // Build gh pr list command\n const limitArg = limit ? `--limit ${limit}` : '';\n const command = `command gh pr list --state merged --json ${this.PR_SEARCH_FIELDS} --search \"${searchQuery}\" ${limitArg}`;\n\n logger.debug(`Running: ${command}`);\n\n const { stdout } = await execAsync(command);\n const prs: GitHubPR[] = JSON.parse(stdout);\n\n logger.debug(`Found ${prs.length} merged PRs`);\n\n return prs;\n } catch (error: any) {\n if (error instanceof GitHubError || error instanceof GitError) {\n throw error;\n }\n throw new GitHubError('Failed to fetch PRs from GitHub', {\n originalError: error.message,\n days,\n });\n }\n }\n\n /**\n * Get merged PRs by current user (PRs authored by the current user)\n */\n async getPRsByCurrentUser(options: FetchPRsOptions = {}): Promise<GitHubPR[]> {\n const currentUser = await this.getCurrentGitHubUser();\n\n if (!currentUser) {\n logger.warning('Could not determine GitHub user, returning all PRs');\n return this.getMergedPRs(options);\n }\n\n logger.debug(`Filtering PRs by author: ${currentUser}`);\n\n // Pass author to getMergedPRs to filter server-side\n return this.getMergedPRs({\n ...options,\n author: currentUser,\n });\n }\n\n /**\n * Transform a GitHub PR into a GitCommit structure\n * This allows PR data to work with existing commit-based UI and API\n */\n transformPRToCommit(pr: GitHubPR): GitCommit {\n // Construct message from PR title and body\n const title = pr.title;\n const body = pr.body || '';\n\n // Truncate body if too long\n const truncatedBody =\n body.length > this.MAX_BODY_LENGTH\n ? body.substring(0, this.MAX_BODY_LENGTH) + '...[truncated]'\n : body;\n\n const message = truncatedBody ? `${title}\\n\\n${truncatedBody}` : title;\n\n return {\n sha: `pr-${pr.number}`,\n message,\n author: pr.author.login,\n authorEmail: '', // Not available from gh PR API\n date: pr.mergedAt,\n url: pr.url,\n diffStats: {\n filesChanged: pr.changedFiles,\n insertions: pr.additions,\n deletions: pr.deletions,\n },\n };\n }\n}\n\n// Export singleton instance\nexport const githubService = new GitHubService();\n","import simpleGit, { SimpleGit, LogResult, DefaultLogFields } from 'simple-git';\nimport { validateGitRepository } from '../utils/validators.js';\nimport { GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type {\n GitCommit,\n DiffStats,\n FetchCommitsOptions,\n GitRepositoryInfo,\n} from '../types/git.types.js';\n\n/**\n * Git service for interacting with git repositories\n */\nexport class GitService {\n private git: SimpleGit;\n private repoPath: string;\n\n constructor(repoPath: string = process.cwd()) {\n this.repoPath = repoPath;\n this.git = simpleGit(repoPath);\n }\n\n /**\n * Validate that the current directory is a git repository\n */\n async validateRepository(): Promise<void> {\n try {\n validateGitRepository(this.repoPath);\n const isRepo = await this.git.checkIsRepo();\n\n if (!isRepo) {\n throw new GitError('Not a valid git repository', {\n path: this.repoPath,\n });\n }\n } catch (error: any) {\n if (error instanceof GitError) {\n throw error;\n }\n throw new GitError('Failed to validate git repository', {\n originalError: error.message,\n path: this.repoPath,\n });\n }\n }\n\n /**\n * Get repository information\n */\n async getRepositoryInfo(): Promise<GitRepositoryInfo> {\n try {\n await this.validateRepository();\n\n const status = await this.git.status();\n const remotes = await this.git.getRemotes(true);\n const primaryRemote = remotes.find((r) => r.name === 'origin');\n\n return {\n path: this.repoPath,\n currentBranch: status.current || 'unknown',\n remoteUrl: primaryRemote?.refs?.fetch || primaryRemote?.refs?.push,\n isClean: status.isClean(),\n };\n } catch (error: any) {\n if (error instanceof GitError) {\n throw error;\n }\n throw new GitError('Failed to get repository information', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Fetch recent commits\n */\n async getRecentCommits(options: FetchCommitsOptions = {}): Promise<GitCommit[]> {\n const { days = 30, limit, author } = options;\n\n try {\n await this.validateRepository();\n\n logger.debug(`Fetching commits from last ${days} days`);\n\n // Calculate date for filtering\n const since = new Date();\n since.setDate(since.getDate() - days);\n\n // Build log options\n const logOptions: any = {\n '--since': since.toISOString(),\n '--no-merges': null,\n };\n\n if (limit) {\n logOptions.maxCount = limit;\n }\n\n if (author) {\n logOptions['--author'] = author;\n }\n\n // Fetch commits\n const log: LogResult<DefaultLogFields> = await this.git.log(logOptions);\n\n logger.debug(`Found ${log.all.length} commits`);\n\n // Convert to our GitCommit format\n const commits: GitCommit[] = log.all.map((commit) => ({\n sha: commit.hash,\n message: commit.message,\n author: commit.author_name,\n authorEmail: commit.author_email,\n date: commit.date,\n }));\n\n return commits;\n } catch (error: any) {\n if (error instanceof GitError) {\n throw error;\n }\n throw new GitError('Failed to fetch commits', {\n originalError: error.message,\n days,\n });\n }\n }\n\n /**\n * Get diff statistics for a specific commit\n */\n async getCommitStats(sha: string): Promise<DiffStats> {\n try {\n logger.debug(`Getting stats for commit ${sha}`);\n\n // Get diff summary for the commit\n const diffSummary = await this.git.diffSummary([`${sha}^`, sha]);\n\n const stats: DiffStats = {\n filesChanged: diffSummary.files.length,\n insertions: diffSummary.insertions,\n deletions: diffSummary.deletions,\n };\n\n logger.debug(\n `Commit ${sha}: ${stats.filesChanged} files, +${stats.insertions} -${stats.deletions}`\n );\n\n return stats;\n } catch (error: any) {\n // If this is the first commit, there's no parent to diff against\n if (error.message && error.message.includes('unknown revision')) {\n logger.debug(`Commit ${sha} has no parent (first commit)`);\n // Try to get stats for first commit\n try {\n const diffSummary = await this.git.diffSummary([sha]);\n return {\n filesChanged: diffSummary.files.length,\n insertions: diffSummary.insertions,\n deletions: diffSummary.deletions,\n };\n } catch {\n // Return zeros if we can't get stats\n return {\n filesChanged: 0,\n insertions: 0,\n deletions: 0,\n };\n }\n }\n\n throw new GitError('Failed to get commit statistics', {\n originalError: error.message,\n sha,\n });\n }\n }\n\n /**\n * Get commits with their diff statistics\n */\n async getCommitsWithStats(options: FetchCommitsOptions = {}): Promise<GitCommit[]> {\n const commits = await this.getRecentCommits(options);\n\n logger.debug(`Fetching diff stats for ${commits.length} commits`);\n\n // Fetch stats for each commit in parallel\n const commitsWithStats = await Promise.all(\n commits.map(async (commit) => {\n try {\n const stats = await this.getCommitStats(commit.sha);\n return {\n ...commit,\n diffStats: stats,\n };\n } catch {\n logger.debug(`Failed to get stats for commit ${commit.sha}, continuing without stats`);\n return commit;\n }\n })\n );\n\n return commitsWithStats;\n }\n\n /**\n * Get the current git user email\n */\n async getCurrentUserEmail(): Promise<string | null> {\n try {\n const email = await this.git.raw(['config', 'user.email']);\n return email.trim() || null;\n } catch {\n logger.debug('Failed to get git user email');\n return null;\n }\n }\n\n /**\n * Get the current git user name\n */\n async getCurrentUserName(): Promise<string | null> {\n try {\n const name = await this.git.raw(['config', 'user.name']);\n return name.trim() || null;\n } catch {\n logger.debug('Failed to get git user name');\n return null;\n }\n }\n\n /**\n * Filter commits by current user\n */\n async getCommitsByCurrentUser(options: FetchCommitsOptions = {}): Promise<GitCommit[]> {\n const userEmail = await this.getCurrentUserEmail();\n\n if (!userEmail) {\n logger.warning('Could not determine git user email, returning all commits');\n return this.getCommitsWithStats(options);\n }\n\n logger.debug(`Filtering commits by user: ${userEmail}`);\n\n return this.getCommitsWithStats({\n ...options,\n author: userEmail,\n });\n }\n}\n\n// Export singleton instance for the current working directory\nexport const gitService = new GitService();\n","import { existsSync } from 'fs';\nimport { join } from 'path';\nimport { GitError, ValidationError } from './errors.js';\n\n/**\n * Validate that a directory is a git repository\n */\nexport function validateGitRepository(path: string): void {\n const gitDir = join(path, '.git');\n\n if (!existsSync(gitDir)) {\n throw new GitError(\n 'Not a git repository. Please run this command from within a git repository.',\n {\n path,\n hint: 'Run \"git init\" to initialize a git repository, or navigate to an existing one',\n }\n );\n }\n}\n\n/**\n * Validate email format\n */\nexport function validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n\n/**\n * Validate that a value is not empty\n */\nexport function validateNotEmpty(value: string, fieldName: string): void {\n if (!value || value.trim().length === 0) {\n throw new ValidationError(`${fieldName} cannot be empty`);\n }\n}\n\n/**\n * Validate date is in valid format\n */\nexport function validateDate(dateString: string): boolean {\n const date = new Date(dateString);\n return !isNaN(date.getTime());\n}\n\n/**\n * Validate number is positive\n */\nexport function validatePositiveNumber(value: number, fieldName: string): void {\n if (value <= 0) {\n throw new ValidationError(`${fieldName} must be a positive number`);\n }\n}\n\n/**\n * Validate commit SHA format (40 character hex string or pr-{number} format)\n */\nexport function validateCommitSha(sha: string): boolean {\n const sha40Regex = /^[a-f0-9]{40}$/i;\n const prFormatRegex = /^pr-\\d+$/i;\n return sha40Regex.test(sha) || prFormatRegex.test(sha);\n}\n","import chalk from 'chalk';\n\n/**\n * Color scheme for consistent UI theming across the CLI\n */\nexport const colors = {\n // Primary colors for main actions and interactive elements\n primary: chalk.cyan,\n\n // Success states\n success: chalk.green,\n successBold: chalk.green.bold,\n\n // Warning states\n warning: chalk.yellow,\n warningBold: chalk.yellow.bold,\n\n // Error states\n error: chalk.red,\n errorBold: chalk.red.bold,\n\n // Info and metadata\n info: chalk.gray,\n infoDim: chalk.dim,\n\n // Highlighted/important data\n highlight: chalk.yellow.bold,\n highlightCyan: chalk.cyan.bold,\n\n // Text emphasis\n bold: chalk.bold,\n dim: chalk.dim,\n\n // Special purpose\n white: chalk.white,\n gray: chalk.gray,\n\n // Links and URLs\n link: chalk.blue.underline,\n} as const;\n\n/**\n * Themed formatting functions for consistent UI elements\n */\nexport const theme = {\n /**\n * Format command names and CLI actions\n */\n command: (text: string) => colors.primary(text),\n\n /**\n * Format success messages\n */\n success: (text: string) => colors.success(`✓ ${text}`),\n successBold: (text: string) => colors.successBold(`✓ ${text}`),\n\n /**\n * Format error messages\n */\n error: (text: string) => colors.error(`✗ ${text}`),\n errorBold: (text: string) => colors.errorBold(`✗ ${text}`),\n\n /**\n * Format warning messages\n */\n warning: (text: string) => colors.warning(`⚠ ${text}`),\n\n /**\n * Format info messages\n */\n info: (text: string) => colors.info(text),\n\n /**\n * Format labels (e.g., \"User:\", \"Email:\")\n */\n label: (text: string) => colors.gray(`${text}:`),\n\n /**\n * Format values\n */\n value: (text: string) => colors.highlight(text),\n\n /**\n * Format counts and numbers\n */\n count: (num: number) => colors.highlightCyan(num.toString()),\n\n /**\n * Format file paths\n */\n path: (text: string) => colors.info(text),\n\n /**\n * Format step indicators (e.g., \"Step 1/5:\")\n */\n step: (current: number, total: number) => colors.primary(`[${current}/${total}]`),\n\n /**\n * Format progress text\n */\n progress: (text: string) => colors.infoDim(text),\n\n /**\n * Format emphasized text\n */\n emphasis: (text: string) => colors.bold(text),\n\n /**\n * Format de-emphasized/secondary text\n */\n secondary: (text: string) => colors.dim(text),\n\n /**\n * Format interactive elements (prompts, selections)\n */\n interactive: (text: string) => colors.primary(text),\n\n /**\n * Format keys in key-value pairs\n */\n key: (text: string) => colors.white(text),\n} as const;\n\n/**\n * Box styles for different message types\n */\nexport const boxStyles = {\n success: {\n borderColor: 'green',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n error: {\n borderColor: 'red',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n warning: {\n borderColor: 'yellow',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n info: {\n borderColor: 'cyan',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n plain: {\n borderColor: 'gray',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n} as const;\n\n/**\n * Table styles for consistent table formatting\n */\nexport const tableStyles = {\n default: {\n style: {\n head: [] as string[],\n border: ['gray'] as string[],\n },\n },\n\n compact: {\n style: {\n head: [] as string[],\n border: ['dim'] as string[],\n compact: true,\n },\n },\n} as const;\n\n/**\n * Size indicators for visual representation\n */\nexport const sizeIndicators = {\n small: colors.success('●'),\n medium: colors.warning('●'),\n large: colors.error('●'),\n} as const;\n\n/**\n * Helper to format size indicator based on lines changed\n */\nexport function getSizeIndicator(insertions: number, deletions: number): string {\n const total = insertions + deletions;\n\n if (total < 50) {\n return `${sizeIndicators.small} Small`;\n } else if (total < 200) {\n return `${sizeIndicators.medium} Medium`;\n } else {\n return `${sizeIndicators.large} Large`;\n }\n}\n\n/**\n * Helper to format diff stats with colors\n */\nexport function formatDiffStats(insertions: number, deletions: number): string {\n return `${colors.success(`+${insertions}`)} ${colors.error(`-${deletions}`)}`;\n}\n","import { CancelPromptError } from '@inquirer/core';\nimport { select } from '@inquirer/prompts';\nimport boxen from 'boxen';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { authService } from '../services/auth.service.js';\nimport { loadEnvConfig } from '../utils/env-loader.js';\nimport { findProjectConfig } from '../utils/config-loader.js';\nimport { AdapterFactory } from '../sync/adapter-factory.js';\nimport { logger } from '../utils/logger.js';\nimport { ensureAuthenticated } from '../utils/auth-helper.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport {\n promptSelectCommits,\n promptDaysToScan,\n promptSortOption,\n promptReviewBrags,\n promptSelectOrganisation,\n} from '../ui/prompts.js';\nimport { createStepSpinner, succeedStepSpinner, failStepSpinner } from '../ui/spinners.js';\nimport {\n formatRefinedCommitsTable,\n formatSuccessMessage,\n formatErrorMessage,\n formatCommitStats,\n formatSelectionSummary,\n} from '../ui/formatters.js';\nimport { theme, colors, boxStyles } from '../ui/theme.js';\nimport type { CreateBragItem, RefinedBrag } from '../types/api.types.js';\nimport type { SourceType } from '../types/source.types.js';\n\n/**\n * Sync command options\n */\nexport interface SyncCommandOptions {\n days?: number;\n all?: boolean;\n source?: string; // Explicit source override\n}\n\n/**\n * Sync results for a single service\n */\ninterface SyncResult {\n created: number;\n skipped: number;\n}\n\n/**\n * Prompt user to select a service to sync\n */\nasync function promptSelectService(): Promise<SourceType | 'all'> {\n // Define all supported services in order\n const allServices: SourceType[] = [\n 'github',\n 'gitlab',\n 'bitbucket',\n 'atlassian',\n 'jira',\n 'confluence',\n ];\n\n // Get authenticated services\n const authenticatedServices = await storageService.getAuthenticatedServices();\n\n // Filter to only include sync-supported services (exclude 'bragduck')\n const authenticatedSyncServices = authenticatedServices.filter(\n (service): service is SourceType =>\n service !== 'bragduck' && allServices.includes(service as SourceType)\n );\n\n // Create choices for each service with auth status\n const serviceChoices = await Promise.all(\n allServices.map(async (service) => {\n const isAuth = await storageService.isServiceAuthenticated(service);\n const indicator = isAuth ? '✓' : '✗';\n const serviceLabel = service.charAt(0).toUpperCase() + service.slice(1);\n\n return {\n name: `${indicator} ${serviceLabel}`,\n value: service,\n description: isAuth ? 'Authenticated' : 'Not authenticated',\n };\n })\n );\n\n // Add \"All authenticated services\" option if there are any\n if (authenticatedSyncServices.length > 0) {\n const serviceNames = authenticatedSyncServices\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join(', ');\n\n serviceChoices.push({\n name: `✓ All authenticated services (${serviceNames})`,\n value: 'all' as SourceType | 'all',\n description: `Sync all ${authenticatedSyncServices.length} authenticated service${authenticatedSyncServices.length > 1 ? 's' : ''}`,\n });\n }\n\n const selected = await select({\n message: 'Select a service to sync:',\n choices: serviceChoices,\n });\n\n return selected;\n}\n\n/**\n * Sync a single service\n */\nasync function syncSingleService(\n sourceType: SourceType,\n options: SyncCommandOptions,\n TOTAL_STEPS: number\n): Promise<SyncResult> {\n // Step 3: Get adapter and validate\n const adapter = AdapterFactory.getAdapter(sourceType);\n const repoSpinner = createStepSpinner(2, TOTAL_STEPS, 'Validating repository');\n repoSpinner.start();\n\n await adapter.validate();\n const repoInfo = await adapter.getRepositoryInfo();\n\n succeedStepSpinner(repoSpinner, 2, TOTAL_STEPS, `Repository: ${theme.value(repoInfo.fullName)}`);\n logger.log('');\n\n // Step 4: Prompt for days\n let days = options.days;\n if (!days) {\n const defaultDays = storageService.getConfig('defaultCommitDays');\n days = await promptDaysToScan(defaultDays);\n logger.log('');\n }\n\n // Step 5: Fetch work items\n const fetchSpinner = createStepSpinner(\n 3,\n TOTAL_STEPS,\n `Fetching work items from the last ${days} days`\n );\n fetchSpinner.start();\n\n const workItems = await adapter.fetchWorkItems({\n days,\n author: options.all ? undefined : (await adapter.getCurrentUser()) || undefined,\n });\n\n if (workItems.length === 0) {\n failStepSpinner(fetchSpinner, 3, TOTAL_STEPS, `No work items found in the last ${days} days`);\n logger.log('');\n logger.info('Try increasing the number of days or check your activity');\n return { created: 0, skipped: 0 };\n }\n\n succeedStepSpinner(\n fetchSpinner,\n 3,\n TOTAL_STEPS,\n `Found ${theme.count(workItems.length)} work item${workItems.length > 1 ? 's' : ''}`\n );\n logger.log('');\n\n // Show commit statistics\n logger.log(formatCommitStats(workItems));\n logger.log('');\n\n // Step 6: Sort and select work items\n let sortedCommits = [...workItems];\n if (workItems.length > 1) {\n const sortOption = await promptSortOption();\n logger.log('');\n\n // Sort commits based on user preference\n if (sortOption === 'date') {\n sortedCommits.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());\n } else if (sortOption === 'size') {\n sortedCommits.sort((a, b) => {\n const sizeA = (a.diffStats?.insertions || 0) + (a.diffStats?.deletions || 0);\n const sizeB = (b.diffStats?.insertions || 0) + (b.diffStats?.deletions || 0);\n return sizeB - sizeA;\n });\n } else if (sortOption === 'files') {\n sortedCommits.sort((a, b) => {\n const filesA = a.diffStats?.filesChanged || 0;\n const filesB = b.diffStats?.filesChanged || 0;\n return filesB - filesA;\n });\n }\n }\n\n const selectedShas = await promptSelectCommits(sortedCommits);\n\n if (selectedShas.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No work items selected. Sync cancelled.'));\n logger.log('');\n return { created: 0, skipped: 0 };\n }\n\n const selectedCommits = sortedCommits.filter((c) => selectedShas.includes(c.sha));\n\n // Show selection summary\n logger.log(formatSelectionSummary(selectedCommits.length, selectedCommits));\n logger.log('');\n\n // Check for duplicates\n const existingBrags = await apiService.listBrags({ limit: 100 });\n logger.debug(`Fetched ${existingBrags.brags.length} existing brags`);\n\n const existingUrls = new Set(existingBrags.brags.flatMap((b) => b.attachments || []));\n logger.debug(`Existing URLs in attachments: ${existingUrls.size}`);\n\n const duplicates = selectedCommits.filter((c) => c.url && existingUrls.has(c.url));\n const newCommits = selectedCommits.filter((c) => !c.url || !existingUrls.has(c.url));\n\n logger.debug(`Duplicates: ${duplicates.length}, New: ${newCommits.length}`);\n\n if (duplicates.length > 0) {\n logger.log('');\n logger.info(\n colors.warning(\n `${duplicates.length} work item${duplicates.length > 1 ? 's' : ''} already added to Bragduck - skipping`\n )\n );\n logger.log('');\n }\n\n if (newCommits.length === 0) {\n logger.log('');\n logger.info(\n theme.secondary('All selected work items already exist in Bragduck. Nothing to refine.')\n );\n logger.log('');\n return { created: 0, skipped: duplicates.length };\n }\n\n // Step 7: Refine with AI\n const refineSpinner = createStepSpinner(\n 4,\n TOTAL_STEPS,\n `Refining ${theme.count(newCommits.length)} work item${newCommits.length > 1 ? 's' : ''} with AI`\n );\n refineSpinner.start();\n\n const refineRequest = {\n brags: newCommits.map((c) => ({\n text: c.message,\n date: c.date,\n title: c.message.split('\\n')[0],\n })),\n };\n\n const refineResponse = await apiService.refineBrags(refineRequest);\n let refinedBrags = refineResponse.refined_brags;\n\n succeedStepSpinner(refineSpinner, 4, TOTAL_STEPS, 'Work items refined successfully');\n logger.log('');\n\n // Step 8: Review and edit brags\n logger.info('Preview of refined brags:');\n logger.log('');\n logger.log(formatRefinedCommitsTable(refinedBrags, newCommits));\n logger.log('');\n\n const acceptedBrags = await promptReviewBrags(refinedBrags, newCommits);\n\n if (acceptedBrags.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No brags selected for creation. Sync cancelled.'));\n logger.log('');\n return { created: 0, skipped: duplicates.length };\n }\n\n logger.log('');\n\n // Step 9: Select organisation (if user has any)\n let selectedOrgId: string | null = null;\n const userInfo = authService.getUserInfo();\n if (userInfo?.id) {\n try {\n const orgsResponse = await apiService.listUserOrganisations(userInfo.id);\n if (orgsResponse.items.length > 0) {\n selectedOrgId = await promptSelectOrganisation(orgsResponse.items);\n logger.log('');\n }\n } catch {\n logger.debug('Failed to fetch organisations, skipping org selection');\n }\n }\n\n // Step 10: Create brags\n const createSpinner = createStepSpinner(\n 5,\n TOTAL_STEPS,\n `Creating ${theme.count(acceptedBrags.length)} brag${acceptedBrags.length > 1 ? 's' : ''}`\n );\n createSpinner.start();\n\n const createRequest = {\n brags: acceptedBrags.map((refined: RefinedBrag, index: number): CreateBragItem => {\n const originalCommit = newCommits[index];\n return {\n commit_sha: originalCommit?.sha || `brag-${index}`,\n title: refined.refined_title,\n description: refined.refined_description,\n tags: refined.suggested_tags,\n repository: repoInfo.url,\n date: originalCommit?.date || '',\n commit_url: originalCommit?.url || '',\n impact_score: refined.suggested_impactLevel,\n impact_description: refined.impact_description,\n attachments: originalCommit?.url ? [originalCommit.url] : [],\n orgId: selectedOrgId || undefined,\n // External fields for non-git sources (Jira, Confluence, etc.)\n externalId: originalCommit?.externalId,\n externalType: originalCommit?.externalType,\n externalSource: originalCommit?.externalSource,\n externalUrl: originalCommit?.externalUrl,\n };\n }),\n };\n\n const createResponse = await apiService.createBrags(createRequest);\n\n succeedStepSpinner(\n createSpinner,\n 5,\n TOTAL_STEPS,\n `Created ${theme.count(createResponse.created)} brag${createResponse.created > 1 ? 's' : ''}`\n );\n logger.log('');\n\n return { created: createResponse.created, skipped: duplicates.length };\n}\n\n/**\n * Sync all authenticated services\n */\nasync function syncAllAuthenticatedServices(options: SyncCommandOptions): Promise<void> {\n const TOTAL_STEPS = 5;\n const allServices: SourceType[] = [\n 'github',\n 'gitlab',\n 'bitbucket',\n 'atlassian',\n 'jira',\n 'confluence',\n ];\n\n // Get authenticated services\n const authenticatedServices = await storageService.getAuthenticatedServices();\n\n // Filter to only include sync-supported services (exclude 'bragduck')\n const servicesToSync = authenticatedServices.filter(\n (service): service is SourceType =>\n service !== 'bragduck' && allServices.includes(service as SourceType)\n );\n\n if (servicesToSync.length === 0) {\n logger.log('');\n logger.error('No authenticated services found.');\n logger.log('');\n logger.info('Authenticate a service first:');\n logger.info(` ${theme.command('bragduck auth github')}`);\n logger.info(` ${theme.command('bragduck auth atlassian')}`);\n return;\n }\n\n logger.info(\n theme.highlight(\n `Syncing ${servicesToSync.length} authenticated service${servicesToSync.length > 1 ? 's' : ''}...`\n )\n );\n logger.log('');\n\n const results: Array<{ service: SourceType; created: number; skipped: number; error?: string }> =\n [];\n\n // Sync each service\n for (let i = 0; i < servicesToSync.length; i++) {\n const service = servicesToSync[i];\n const serviceLabel = service.charAt(0).toUpperCase() + service.slice(1);\n\n logger.log(\n colors.highlight(`━━━ Syncing ${i + 1}/${servicesToSync.length}: ${serviceLabel} ━━━`)\n );\n logger.log('');\n\n try {\n const result = await syncSingleService(service, options, TOTAL_STEPS);\n results.push({ service, created: result.created, skipped: result.skipped });\n logger.log('');\n } catch (error) {\n const err = error as Error;\n logger.log('');\n logger.warn(`Failed to sync ${serviceLabel}: ${err.message}`);\n logger.log('');\n results.push({ service, created: 0, skipped: 0, error: err.message });\n }\n }\n\n // Show final summary\n logger.log('');\n logger.log(colors.highlight('━━━ Sync Summary ━━━'));\n logger.log('');\n\n const successful = results.filter((r) => !r.error);\n const failed = results.filter((r) => r.error);\n const totalCreated = successful.reduce((sum, r) => sum + r.created, 0);\n\n if (successful.length > 0) {\n logger.log(\n theme.success(\n `✓ Successfully synced ${successful.length}/${servicesToSync.length} service${servicesToSync.length > 1 ? 's' : ''}:`\n )\n );\n for (const result of successful) {\n const serviceLabel = result.service.charAt(0).toUpperCase() + result.service.slice(1);\n logger.info(\n ` • ${serviceLabel}: ${result.created} brag${result.created !== 1 ? 's' : ''} created${result.skipped > 0 ? `, ${result.skipped} skipped` : ''}`\n );\n }\n logger.log('');\n }\n\n if (failed.length > 0) {\n logger.log(\n colors.warning(`✗ Failed to sync ${failed.length} service${failed.length > 1 ? 's' : ''}:`)\n );\n for (const result of failed) {\n const serviceLabel = result.service.charAt(0).toUpperCase() + result.service.slice(1);\n logger.info(` • ${serviceLabel}: ${result.error}`);\n }\n logger.log('');\n }\n\n if (totalCreated > 0) {\n logger.log(boxen(formatSuccessMessage(totalCreated), boxStyles.success));\n } else if (successful.length > 0) {\n logger.log(\n boxen(\n theme.secondary('No new brags created (all items already exist or were skipped)'),\n boxStyles.info\n )\n );\n }\n}\n\n/**\n * Sync command: Unified work item sync across all sources\n */\nexport async function syncCommand(options: SyncCommandOptions = {}): Promise<void> {\n logger.log('');\n\n const TOTAL_STEPS = 5;\n let sourceType: SourceType | undefined;\n\n try {\n // Step 1: Check authentication\n const isAuthenticated = await ensureAuthenticated();\n if (!isAuthenticated) {\n process.exit(1);\n }\n\n // Step 1.5: Check subscription plan\n logger.debug('Fetching subscription status...');\n const subscriptionStatus = await apiService.getSubscriptionStatus();\n\n logger.debug('Subscription status response:', JSON.stringify(subscriptionStatus, null, 2));\n\n if (subscriptionStatus.tier === 'FREE') {\n logger.debug('FREE tier detected - blocking sync command');\n logger.log('');\n logger.log(\n boxen(\n theme.warning('CLI Access Requires Subscription') +\n '\\n\\n' +\n 'The Bragduck CLI is available for Plus and Pro subscribers.\\n' +\n 'Upgrade now to unlock:\\n\\n' +\n ' • Automatic work item scanning\\n' +\n ' • AI-powered brag generation\\n' +\n ' • Unlimited brags\\n\\n' +\n colors.highlight('Start your free trial today'),\n {\n ...boxStyles.warning,\n padding: 1,\n margin: 1,\n }\n )\n );\n logger.log('');\n return;\n }\n\n logger.debug(`Subscription tier \"${subscriptionStatus.tier}\" - proceeding with sync`);\n\n // Step 2: Select or detect source\n let selectedSource: SourceType | 'all';\n\n if (options.source) {\n // Use explicit --source flag (skip menu)\n sourceType = options.source as SourceType;\n\n // Validate source is supported\n if (!AdapterFactory.isSupported(sourceType)) {\n logger.log('');\n logger.error(`Unsupported source: ${options.source}`);\n logger.log('');\n logger.info('Supported sources: github, gitlab, bitbucket, atlassian, jira, confluence');\n return;\n }\n\n selectedSource = sourceType;\n } else {\n // Show interactive service selection menu\n logger.log('');\n selectedSource = await promptSelectService();\n logger.log('');\n }\n\n // Handle selection\n if (selectedSource === 'all') {\n // Multi-service sync\n await syncAllAuthenticatedServices(options);\n } else {\n // Single service sync\n const detectionSpinner = createStepSpinner(1, TOTAL_STEPS, 'Preparing sync');\n detectionSpinner.start();\n\n sourceType = selectedSource;\n\n // Early validation for Jira/Confluence credentials\n if (sourceType === 'jira' || sourceType === 'confluence') {\n const creds = await storageService.getServiceCredentials(sourceType);\n\n // Try environment variable or project config as fallback\n const envInstance =\n loadEnvConfig()[`${sourceType}Instance` as keyof ReturnType<typeof loadEnvConfig>];\n const projectConfig = await findProjectConfig();\n const configInstance =\n projectConfig?.[`${sourceType}Instance` as keyof typeof projectConfig];\n\n if (!creds?.instanceUrl && !envInstance && !configInstance) {\n failStepSpinner(detectionSpinner, 1, TOTAL_STEPS, `No ${sourceType} instance configured`);\n logger.log('');\n logger.info('Configure instance via:');\n logger.info(` ${theme.command('bragduck auth atlassian')} (interactive)`);\n logger.info(\n ` ${theme.command(`bragduck config set ${sourceType}Instance company.atlassian.net`)}`\n );\n logger.info(\n ` ${theme.command(`export BRAGDUCK_${sourceType.toUpperCase()}_INSTANCE=company.atlassian.net`)}`\n );\n return;\n }\n }\n\n succeedStepSpinner(detectionSpinner, 1, TOTAL_STEPS, `Source: ${theme.value(sourceType)}`);\n logger.log('');\n\n // Sync the selected service\n const result = await syncSingleService(sourceType, options, TOTAL_STEPS);\n\n // Show success message\n if (result.created > 0) {\n logger.log(boxen(formatSuccessMessage(result.created), boxStyles.success));\n }\n }\n } catch (error) {\n if (error instanceof CancelPromptError) {\n logger.log('');\n logger.info(theme.secondary('Sync cancelled.'));\n logger.log('');\n return;\n }\n\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(formatErrorMessage(err.message, getErrorHint(err, sourceType)), boxStyles.error)\n );\n\n process.exit(1);\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError, sourceType?: SourceType): string {\n if (error.name === 'GitHubError') {\n return 'Make sure you are in a GitHub repository and have authenticated with \"gh auth login\"';\n }\n\n if (error.name === 'GitError') {\n return 'Make sure you are in a git repository';\n }\n\n if (error.name === 'TokenExpiredError' || error.name === 'AuthenticationError') {\n // Provide context-aware hint for non-git sources\n if (sourceType === 'jira' || sourceType === 'confluence') {\n return 'This is your Bragduck platform session. Run \"bragduck auth login\" (not \"bragduck auth atlassian\")';\n }\n return 'Run \"bragduck auth login\" to login again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'ApiError') {\n return 'The server might be experiencing issues. Try again later';\n }\n\n return 'Try running with DEBUG=* for more information';\n}\n","export class AbortPromptError extends Error {\n name = 'AbortPromptError';\n message = 'Prompt was aborted';\n constructor(options) {\n super();\n this.cause = options?.cause;\n }\n}\nexport class CancelPromptError extends Error {\n name = 'CancelPromptError';\n message = 'Prompt was canceled';\n}\nexport class ExitPromptError extends Error {\n name = 'ExitPromptError';\n}\nexport class HookError extends Error {\n name = 'HookError';\n}\nexport class ValidationError extends Error {\n name = 'ValidationError';\n}\n","import type { SourceType } from '../types/source.types.js';\nimport type { SyncAdapter } from './base-adapter.js';\nimport { githubSyncAdapter } from './github-adapter.js';\nimport { bitbucketSyncAdapter } from './bitbucket-adapter.js';\nimport { gitlabSyncAdapter } from './gitlab-adapter.js';\nimport { jiraSyncAdapter } from './jira-adapter.js';\nimport { confluenceSyncAdapter } from './confluence-adapter.js';\n\n/**\n * Factory for creating source adapters\n */\nexport class AdapterFactory {\n /**\n * Get adapter for a specific source type\n */\n static getAdapter(source: SourceType): SyncAdapter {\n switch (source) {\n case 'github':\n return githubSyncAdapter;\n case 'bitbucket':\n case 'atlassian':\n return bitbucketSyncAdapter; // Bitbucket Cloud and Server use same adapter\n case 'gitlab':\n return gitlabSyncAdapter;\n case 'jira':\n return jiraSyncAdapter;\n case 'confluence':\n return confluenceSyncAdapter;\n default:\n throw new Error(`Unknown source type: ${source}`);\n }\n }\n\n /**\n * Check if adapter is available for source\n */\n static isSupported(source: SourceType): boolean {\n return (\n source === 'github' ||\n source === 'bitbucket' ||\n source === 'atlassian' ||\n source === 'gitlab' ||\n source === 'jira' ||\n source === 'confluence'\n );\n }\n}\n","import { githubService } from '../services/github.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * GitHub adapter for syncing PRs and commits\n */\nexport class GitHubSyncAdapter implements SyncAdapter {\n readonly name = 'github';\n\n async validate(): Promise<void> {\n await githubService.validateGitHubRepository();\n }\n\n async getRepositoryInfo() {\n const info = await githubService.getRepositoryInfo();\n return {\n owner: info.owner,\n name: info.name,\n fullName: info.fullName,\n url: info.url,\n };\n }\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n // Reuse existing GitHub PR fetching logic\n let prs;\n if (options.author) {\n prs = await githubService.getMergedPRs({\n days: options.days,\n limit: options.limit,\n author: options.author,\n });\n } else {\n prs = await githubService.getPRsByCurrentUser({\n days: options.days,\n limit: options.limit,\n });\n }\n\n // Transform to GitCommit format\n return prs.map((pr) => githubService.transformPRToCommit(pr));\n }\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await githubService.validateGitHubRepository();\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentUser(): Promise<string | null> {\n return githubService.getCurrentGitHubUser();\n }\n}\n\nexport const githubSyncAdapter = new GitHubSyncAdapter();\n","import { bitbucketService } from '../services/bitbucket.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Bitbucket adapter for syncing PRs and commits\n */\nexport class BitbucketSyncAdapter implements SyncAdapter {\n readonly name = 'bitbucket';\n\n async validate(): Promise<void> {\n await bitbucketService.validateBitbucketRepository();\n }\n\n async getRepositoryInfo() {\n const info = await bitbucketService.getRepositoryInfo();\n return {\n owner: info.owner,\n name: info.name,\n fullName: info.fullName,\n url: info.url,\n };\n }\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n let prs;\n if (options.author) {\n prs = await bitbucketService.getMergedPRs({\n days: options.days,\n limit: options.limit,\n author: options.author,\n });\n } else {\n prs = await bitbucketService.getPRsByCurrentUser({\n days: options.days,\n limit: options.limit,\n });\n }\n\n return prs.map((pr) => bitbucketService.transformPRToCommit(pr));\n }\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await bitbucketService.validateBitbucketRepository();\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentUser(): Promise<string | null> {\n return bitbucketService.getCurrentGitHubUser();\n }\n}\n\nexport const bitbucketSyncAdapter = new BitbucketSyncAdapter();\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { BitbucketError, GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport { gitService } from './git.service.js';\nimport type {\n BitbucketPullRequest,\n BitbucketUser,\n FetchBitbucketPRsOptions,\n BitbucketPaginatedResponse,\n BitbucketRepository,\n} from '../types/bitbucket.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Bitbucket service for interacting with Bitbucket Cloud REST API\n */\nexport class BitbucketService {\n private readonly BITBUCKET_API_BASE = 'https://api.bitbucket.org/2.0';\n private readonly MAX_DESCRIPTION_LENGTH = 5000;\n\n /**\n * Get stored Bitbucket credentials\n */\n private async getCredentials(): Promise<{ email: string; apiToken: string }> {\n const creds = await storageService.getServiceCredentials('bitbucket');\n if (!creds || !creds.username || !creds.accessToken) {\n throw new BitbucketError('Not authenticated with Bitbucket', {\n hint: 'Run: bragduck auth bitbucket',\n });\n }\n\n // Check token expiry\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new BitbucketError('API token has expired', {\n hint: 'Run: bragduck auth bitbucket',\n });\n }\n\n return {\n email: creds.username, // username field stores email\n apiToken: creds.accessToken,\n };\n }\n\n /**\n * Make authenticated request to Bitbucket API\n */\n private async request<T>(endpoint: string): Promise<T> {\n const { email, apiToken } = await this.getCredentials();\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n\n logger.debug(`Bitbucket API: GET ${endpoint}`);\n\n const response = await fetch(`${this.BITBUCKET_API_BASE}${endpoint}`, {\n headers: {\n Authorization: `Basic ${auth}`,\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new BitbucketError('Invalid or expired API token', {\n hint: 'Run: bragduck auth bitbucket',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new BitbucketError('Forbidden - check token permissions', {\n hint: 'Token needs: pullrequest:read, repository:read, account:read',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new BitbucketError('Repository or resource not found', {\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new BitbucketError('Rate limit exceeded', {\n hint: 'Wait a few minutes before trying again',\n originalError: statusText,\n });\n }\n\n throw new BitbucketError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Extract workspace and repo from git remote URL\n */\n private parseRemoteUrl(url: string): { workspace: string; repo: string } | null {\n // Match: bitbucket.org/{workspace}/{repo}\n const match = url.match(/bitbucket\\.org[:/]([^/]+)\\/([^/.]+)/);\n if (match && match[1] && match[2]) {\n return {\n workspace: match[1],\n repo: match[2].replace(/\\.git$/, ''),\n };\n }\n return null;\n }\n\n /**\n * Get repository info from git remote\n */\n private async getRepoFromGit(): Promise<{ workspace: string; repo: string }> {\n try {\n const { stdout } = await execAsync('command git remote get-url origin');\n const remoteUrl = stdout.trim();\n\n const parsed = this.parseRemoteUrl(remoteUrl);\n if (!parsed) {\n throw new BitbucketError('Could not parse Bitbucket repository from git remote', {\n hint: 'Ensure this is a Bitbucket repository',\n });\n }\n\n return parsed;\n } catch (error: unknown) {\n if (error instanceof BitbucketError) {\n throw error;\n }\n throw new GitError('Could not get git remote URL');\n }\n }\n\n /**\n * Validate that this is a Bitbucket repository and credentials work\n */\n async validateBitbucketRepository(): Promise<void> {\n // Check if in git repo\n await gitService.validateRepository();\n\n // Get repo info from git\n const { workspace, repo } = await this.getRepoFromGit();\n\n // Test API access by fetching repository info\n try {\n await this.request<BitbucketRepository>(`/repositories/${workspace}/${repo}`);\n } catch (error: unknown) {\n if (error instanceof BitbucketError) {\n throw error;\n }\n throw new BitbucketError('Could not access Bitbucket repository via API', {\n hint: 'Check that this is a Bitbucket repository and your credentials are valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get repository information\n */\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const { workspace, repo } = await this.getRepoFromGit();\n\n const bitbucketRepo = await this.request<BitbucketRepository>(\n `/repositories/${workspace}/${repo}`\n );\n\n return {\n owner: workspace,\n name: bitbucketRepo.name,\n fullName: bitbucketRepo.full_name,\n url: bitbucketRepo.links.html.href,\n };\n }\n\n /**\n * Get current user's account ID\n */\n private async getCurrentUserAccountId(): Promise<string> {\n const user = await this.request<BitbucketUser>('/user');\n return user.account_id;\n }\n\n /**\n * Get current user's username (nickname)\n */\n async getCurrentGitHubUser(): Promise<string | null> {\n try {\n const user = await this.request<BitbucketUser>('/user');\n return user.nickname;\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch merged pull requests with optional filtering\n */\n async getMergedPRs(options: FetchBitbucketPRsOptions = {}): Promise<BitbucketPullRequest[]> {\n const { workspace, repo } = await this.getRepoFromGit();\n\n // Build query\n const queries = ['state=\"MERGED\"'];\n\n // Date filtering\n if (options.days) {\n const since = new Date();\n since.setDate(since.getDate() - options.days);\n queries.push(`updated_on>=${since.toISOString()}`);\n }\n\n // Author filtering by account_id\n if (options.author) {\n queries.push(`author.account_id=\"${options.author}\"`);\n }\n\n const queryString = queries.join(' AND ');\n\n // Fetch with cursor-based pagination\n const allPRs: BitbucketPullRequest[] = [];\n let endpoint = `/repositories/${workspace}/${repo}/pullrequests?q=${encodeURIComponent(queryString)}&pagelen=100`;\n\n while (endpoint) {\n const response =\n await this.request<BitbucketPaginatedResponse<BitbucketPullRequest>>(endpoint);\n\n allPRs.push(...response.values);\n\n logger.debug(\n `Fetched ${response.values.length} PRs (total: ${allPRs.length})${response.next ? ', fetching next page...' : ''}`\n );\n\n // Check limit\n if (options.limit && allPRs.length >= options.limit) {\n return allPRs.slice(0, options.limit);\n }\n\n // Get next page (convert absolute URL to relative endpoint)\n if (response.next) {\n const url = new URL(response.next);\n endpoint = url.pathname + url.search;\n } else {\n endpoint = '';\n }\n }\n\n return allPRs;\n }\n\n /**\n * Fetch PRs for the current authenticated user\n */\n async getPRsByCurrentUser(\n options: Omit<FetchBitbucketPRsOptions, 'author'> = {}\n ): Promise<BitbucketPullRequest[]> {\n const accountId = await this.getCurrentUserAccountId();\n return this.getMergedPRs({\n ...options,\n author: accountId,\n });\n }\n\n /**\n * Transform Bitbucket PR to GitCommit format\n */\n transformPRToCommit(pr: BitbucketPullRequest): GitCommit {\n // Format message: title + description\n let message = pr.title;\n if (pr.description) {\n const truncatedDesc = pr.description.substring(0, this.MAX_DESCRIPTION_LENGTH);\n message = `${pr.title}\\n\\n${truncatedDesc}`;\n }\n\n return {\n sha: `pr-${pr.id}`,\n message,\n author: pr.author.nickname,\n authorEmail: '', // Not available in Bitbucket API\n date: pr.created_on,\n url: pr.links.html.href,\n diffStats: {\n filesChanged: 0, // Would require separate API call to diffstat endpoint\n insertions: 0,\n deletions: 0,\n },\n };\n }\n}\n\nexport const bitbucketService = new BitbucketService();\n","import { gitlabService } from '../services/gitlab.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * GitLab sync adapter for fetching merge requests\n */\nexport class GitLabSyncAdapter implements SyncAdapter {\n readonly name = 'gitlab';\n\n async validate(): Promise<void> {\n await gitlabService.validateGitLabRepository();\n }\n\n async getRepositoryInfo() {\n const info = await gitlabService.getRepositoryInfo();\n return {\n owner: info.owner,\n name: info.name,\n fullName: info.fullName,\n url: info.url,\n };\n }\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n let mrs;\n if (options.author) {\n mrs = await gitlabService.getMergedMRs({\n days: options.days,\n limit: options.limit,\n author: options.author,\n });\n } else {\n mrs = await gitlabService.getMRsByCurrentUser({\n days: options.days,\n limit: options.limit,\n });\n }\n return mrs.map((mr) => gitlabService.transformMRToCommit(mr));\n }\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await gitlabService.validateGitLabRepository();\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentUser(): Promise<string | null> {\n return gitlabService.getCurrentGitLabUser();\n }\n}\n\nexport const gitlabSyncAdapter = new GitLabSyncAdapter();\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { URLSearchParams } from 'url';\nimport { GitLabError, GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport { gitService } from './git.service.js';\nimport type {\n GitLabMergeRequest,\n GitLabUser,\n FetchGitLabMRsOptions,\n GitLabProject,\n} from '../types/gitlab.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * GitLab service for interacting with GitLab REST API v4\n */\nexport class GitLabService {\n private readonly DEFAULT_INSTANCE = 'https://gitlab.com';\n private readonly MAX_DESCRIPTION_LENGTH = 5000;\n\n /**\n * Get stored GitLab credentials\n */\n private async getCredentials(): Promise<{ accessToken: string; instanceUrl: string }> {\n const creds = await storageService.getServiceCredentials('gitlab');\n if (!creds || !creds.accessToken) {\n throw new GitLabError('Not authenticated with GitLab', {\n hint: 'Run: bragduck auth gitlab',\n });\n }\n\n // Check token expiry (future feature)\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new GitLabError('Access token has expired', {\n hint: 'Run: bragduck auth gitlab',\n });\n }\n\n return {\n accessToken: creds.accessToken,\n instanceUrl: creds.instanceUrl || this.DEFAULT_INSTANCE,\n };\n }\n\n /**\n * Make authenticated request to GitLab API\n */\n private async request<T>(endpoint: string): Promise<T> {\n const { accessToken, instanceUrl } = await this.getCredentials();\n const baseUrl = `${instanceUrl}/api/v4`;\n const url = `${baseUrl}${endpoint}`;\n\n logger.debug(`GitLab API: GET ${endpoint}`);\n\n const response = await fetch(url, {\n headers: {\n 'PRIVATE-TOKEN': accessToken,\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new GitLabError('Invalid or expired access token', {\n hint: 'Run: bragduck auth gitlab',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new GitLabError('Insufficient token permissions', {\n hint: 'Token requires scopes: api, read_api, read_user',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new GitLabError('Resource not found', {\n hint: 'Check repository URL and token permissions',\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new GitLabError('Rate limit exceeded', {\n hint: 'Wait a moment and try again',\n originalError: statusText,\n });\n }\n\n throw new GitLabError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Extract namespace and project from git remote URL\n */\n private parseRemoteUrl(url: string): { namespace: string; project: string } | null {\n // Patterns:\n // https://gitlab.com/owner/repo.git\n // git@gitlab.com:owner/repo.git\n // https://custom-gitlab.com/owner/repo.git\n const match = url.match(/[:/]([\\w-]+)\\/([\\w-]+?)(?:\\.git)?$/);\n if (match && match[1] && match[2]) {\n return {\n namespace: match[1],\n project: match[2],\n };\n }\n return null;\n }\n\n /**\n * Get project path from git remote\n */\n private async getProjectFromGit(): Promise<{\n namespace: string;\n project: string;\n projectPath: string;\n }> {\n try {\n const { stdout } = await execAsync('git remote get-url origin');\n const remoteUrl = stdout.trim();\n\n const parsed = this.parseRemoteUrl(remoteUrl);\n if (!parsed) {\n throw new GitLabError('Could not parse GitLab project from remote URL', {\n url: remoteUrl,\n });\n }\n\n return {\n ...parsed,\n projectPath: `${parsed.namespace}/${parsed.project}`,\n };\n } catch (error: unknown) {\n if (error instanceof GitLabError) {\n throw error;\n }\n throw new GitError('Could not get git remote URL');\n }\n }\n\n /**\n * Validate that this is a GitLab repository and credentials work\n */\n async validateGitLabRepository(): Promise<void> {\n // Check if in git repo\n await gitService.validateRepository();\n\n // Get project info from git\n const { projectPath } = await this.getProjectFromGit();\n\n // Test API access by fetching project\n const encodedPath = encodeURIComponent(projectPath);\n try {\n await this.request<GitLabProject>(`/projects/${encodedPath}`);\n } catch (error: unknown) {\n if (error instanceof GitLabError) {\n throw error;\n }\n throw new GitLabError('Could not access GitLab project via API', {\n hint: 'Check that this is a GitLab repository and your token is valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get repository information\n */\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const { projectPath } = await this.getProjectFromGit();\n const encodedPath = encodeURIComponent(projectPath);\n const project = await this.request<GitLabProject>(`/projects/${encodedPath}`);\n\n const [owner, name] = projectPath.split('/');\n\n return {\n owner: owner || '',\n name: name || '',\n fullName: project.path_with_namespace,\n url: project.web_url,\n };\n }\n\n /**\n * Fetch merged MRs with pagination\n */\n async getMergedMRs(options: FetchGitLabMRsOptions = {}): Promise<GitLabMergeRequest[]> {\n const { projectPath } = await this.getProjectFromGit();\n const encodedPath = encodeURIComponent(projectPath);\n\n // Build query params\n const params = new URLSearchParams({\n state: 'merged',\n order_by: 'updated_at',\n sort: 'desc',\n per_page: '100',\n });\n\n // Date filtering\n if (options.days) {\n const since = new Date();\n since.setDate(since.getDate() - options.days);\n params.append('updated_after', since.toISOString());\n }\n\n // Author filtering\n if (options.author) {\n params.append('author_username', options.author);\n }\n\n // Pagination (page-based)\n const allMRs: GitLabMergeRequest[] = [];\n let page = 1;\n\n while (true) {\n params.set('page', page.toString());\n const endpoint = `/projects/${encodedPath}/merge_requests?${params}`;\n\n const mrs = await this.request<GitLabMergeRequest[]>(endpoint);\n allMRs.push(...mrs);\n\n logger.debug(\n `Fetched ${mrs.length} MRs (total: ${allMRs.length})${mrs.length === 100 ? ', fetching next page...' : ''}`\n );\n\n // Check limit\n if (options.limit && allMRs.length >= options.limit) {\n return allMRs.slice(0, options.limit);\n }\n\n // Check if more pages (last page has < per_page results)\n if (mrs.length < 100) {\n break;\n }\n\n page++;\n }\n\n return allMRs;\n }\n\n /**\n * Get MRs by current user\n */\n async getMRsByCurrentUser(options: FetchGitLabMRsOptions = {}): Promise<GitLabMergeRequest[]> {\n const username = await this.getCurrentGitLabUser();\n if (!username) {\n throw new GitLabError('Could not get current user username');\n }\n return this.getMergedMRs({\n ...options,\n author: username,\n });\n }\n\n /**\n * Get current authenticated user\n */\n async getCurrentGitLabUser(): Promise<string | null> {\n try {\n const user = await this.request<GitLabUser>('/user');\n return user.username;\n } catch {\n return null;\n }\n }\n\n /**\n * Transform GitLab MR to GitCommit format\n */\n transformMRToCommit(mr: GitLabMergeRequest): GitCommit {\n const message = this.formatMessage(mr.title, mr.description);\n\n return {\n sha: `mr-${mr.iid}`, // Use iid (project-scoped)\n message,\n author: mr.author.username,\n authorEmail: '', // Not available in MR response\n date: mr.created_at,\n url: mr.web_url,\n diffStats: {\n filesChanged: mr.diff_stats?.file_count || 0,\n insertions: mr.diff_stats?.additions || 0,\n deletions: mr.diff_stats?.deletions || 0,\n },\n };\n }\n\n /**\n * Format MR message with title and description\n */\n private formatMessage(title: string, description: string | null): string {\n if (!description) return title;\n const truncated = description.substring(0, this.MAX_DESCRIPTION_LENGTH);\n return `${title}\\n\\n${truncated}`;\n }\n}\n\nexport const gitlabService = new GitLabService();\n","import { jiraService } from '../services/jira.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Jira adapter for syncing issues\n */\nexport const jiraSyncAdapter: SyncAdapter = {\n name: 'jira',\n\n async validate(): Promise<void> {\n await jiraService.validateJiraInstance();\n },\n\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const user = await jiraService.getCurrentUser();\n // Access private method via bracket notation to avoid exposing it publicly\n const creds = await (\n jiraService as unknown as { getCredentials: () => Promise<{ instanceUrl: string }> }\n ).getCredentials();\n\n const userName = user || 'Unknown User';\n const baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n\n return {\n owner: userName,\n name: 'Jira Issues',\n fullName: `${userName}'s Jira Issues`,\n url: baseUrl,\n };\n },\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n // Handle 'current' author\n const author = options.author === 'current' ? await this.getCurrentUser() : options.author;\n\n return jiraService.getIssues({\n days: options.days,\n limit: options.limit,\n author: author || undefined,\n });\n },\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await this.validate();\n return true;\n } catch {\n return false;\n }\n },\n\n async getCurrentUser(): Promise<string | null> {\n return jiraService.getCurrentUser();\n },\n};\n","import { JiraError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport type {\n JiraIssue,\n JiraSearchResponse,\n JiraUser,\n FetchJiraIssuesOptions,\n} from '../types/atlassian.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Jira service for interacting with Jira Cloud and Server REST API\n */\nexport class JiraService {\n private readonly MAX_DESCRIPTION_LENGTH = 5000;\n\n /**\n * Get stored Jira credentials\n */\n private async getCredentials(): Promise<{\n email: string;\n apiToken: string;\n instanceUrl: string;\n }> {\n const creds = await storageService.getServiceCredentials('jira');\n if (!creds || !creds.username || !creds.accessToken || !creds.instanceUrl) {\n throw new JiraError('Not authenticated with Jira', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n // Check token expiry\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new JiraError('API token has expired', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n return {\n email: creds.username,\n apiToken: creds.accessToken,\n instanceUrl: creds.instanceUrl,\n };\n }\n\n /**\n * Make authenticated request to Jira API\n */\n private async request<T>(endpoint: string, method = 'GET', body?: unknown): Promise<T> {\n const { email, apiToken, instanceUrl } = await this.getCredentials();\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n\n // Ensure instanceUrl has protocol\n const baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n\n logger.debug(`Jira API: ${method} ${endpoint}`);\n\n const options: Parameters<typeof fetch>[1] = {\n method,\n headers: {\n Authorization: `Basic ${auth}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n };\n\n if (body) {\n options.body = JSON.stringify(body);\n }\n\n const response = await fetch(`${baseUrl}${endpoint}`, options);\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new JiraError('Invalid or expired API token', {\n hint: 'Run: bragduck auth atlassian',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new JiraError('Forbidden - check token permissions', {\n hint: 'Token needs: read access to issues',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new JiraError('Resource not found', {\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new JiraError('Rate limit exceeded', {\n hint: 'Wait a few minutes before trying again',\n originalError: statusText,\n });\n }\n\n throw new JiraError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Validate Jira instance and credentials\n */\n async validateJiraInstance(): Promise<void> {\n try {\n await this.request<JiraUser>('/rest/api/2/myself');\n } catch (error: unknown) {\n if (error instanceof JiraError) {\n throw error;\n }\n throw new JiraError('Could not access Jira instance via API', {\n hint: 'Check that the instance URL is correct and your credentials are valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get current user's email\n */\n async getCurrentUser(): Promise<string | null> {\n try {\n const user = await this.request<JiraUser>('/rest/api/2/myself');\n return user.emailAddress;\n } catch {\n return null;\n }\n }\n\n /**\n * Build JQL query from options\n */\n private buildJQL(options: FetchJiraIssuesOptions): string {\n const queries: string[] = [];\n\n // Status filter (completed issues only)\n queries.push('status IN (Done, Resolved, Closed)');\n\n // Date filtering\n if (options.days) {\n queries.push(`updated >= -${options.days}d`);\n }\n\n // Author filtering\n if (options.author) {\n queries.push(`creator = \"${options.author}\"`);\n }\n\n // Custom JQL\n if (options.jql) {\n queries.push(`(${options.jql})`);\n }\n\n return queries.join(' AND ');\n }\n\n /**\n * Estimate issue complexity for impact scoring\n */\n private estimateComplexity(issue: JiraIssue): number {\n const typeScores: Record<string, number> = {\n Epic: 500,\n Story: 200,\n Task: 100,\n Bug: 100,\n 'Sub-task': 50,\n };\n\n return typeScores[issue.fields.issuetype.name] || 100;\n }\n\n /**\n * Fetch issues with optional filtering\n */\n async getIssues(options: FetchJiraIssuesOptions = {}): Promise<GitCommit[]> {\n const jql = this.buildJQL(options);\n const fields = [\n 'summary',\n 'description',\n 'created',\n 'updated',\n 'resolutiondate',\n 'creator',\n 'status',\n 'issuetype',\n ];\n\n const allIssues: JiraIssue[] = [];\n let startAt = 0;\n const maxResults = 100;\n\n // Pagination: loop until all results fetched\n while (true) {\n const endpoint = `/rest/api/2/search?jql=${encodeURIComponent(jql)}&startAt=${startAt}&maxResults=${maxResults}&fields=${fields.join(',')}`;\n\n const response = await this.request<JiraSearchResponse>(endpoint);\n\n allIssues.push(...response.issues);\n\n logger.debug(\n `Fetched ${response.issues.length} issues (total: ${allIssues.length} of ${response.total})${startAt + maxResults < response.total ? ', fetching next page...' : ''}`\n );\n\n // Check if we've fetched all issues\n if (startAt + maxResults >= response.total) {\n break;\n }\n\n // Check limit\n if (options.limit && allIssues.length >= options.limit) {\n return allIssues.slice(0, options.limit).map((issue) => this.transformIssueToCommit(issue));\n }\n\n startAt += maxResults;\n }\n\n return allIssues.map((issue) => this.transformIssueToCommit(issue));\n }\n\n /**\n * Fetch issues for the current authenticated user\n */\n async getIssuesByCurrentUser(\n options: Omit<FetchJiraIssuesOptions, 'author'> = {}\n ): Promise<GitCommit[]> {\n const email = await this.getCurrentUser();\n if (!email) {\n throw new JiraError('Could not get current user');\n }\n\n return this.getIssues({\n ...options,\n author: email,\n });\n }\n\n /**\n * Transform Jira issue to GitCommit format with external fields\n */\n transformIssueToCommit(issue: JiraIssue, instanceUrl?: string): GitCommit {\n // Format message: title + description\n let message = issue.fields.summary;\n if (issue.fields.description) {\n const truncatedDesc = issue.fields.description.substring(0, this.MAX_DESCRIPTION_LENGTH);\n message = `${issue.fields.summary}\\n\\n${truncatedDesc}`;\n }\n\n // Use resolution date if available, otherwise updated date\n const date = issue.fields.resolutiondate || issue.fields.updated;\n\n // Build URL (use provided instanceUrl or try to get from storage)\n let baseUrl = 'https://jira.atlassian.net';\n if (instanceUrl) {\n baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n } else {\n try {\n const creds = storageService.getServiceCredentials('jira') as {\n instanceUrl?: string;\n } | null;\n if (creds?.instanceUrl) {\n baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n }\n } catch {\n // Use default if credentials not available\n }\n }\n const url = `${baseUrl}/browse/${issue.key}`;\n\n return {\n sha: issue.key,\n message,\n author: issue.fields.creator.displayName,\n authorEmail: issue.fields.creator.emailAddress,\n date,\n url,\n diffStats: {\n filesChanged: 0,\n insertions: this.estimateComplexity(issue),\n deletions: 0,\n },\n externalId: issue.key,\n externalType: 'issue',\n externalSource: 'jira',\n externalUrl: url,\n };\n }\n}\n\nexport const jiraService = new JiraService();\n","import { confluenceService } from '../services/confluence.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Confluence adapter for syncing pages\n */\nexport const confluenceSyncAdapter: SyncAdapter = {\n name: 'confluence',\n\n async validate(): Promise<void> {\n await confluenceService.validateConfluenceInstance();\n },\n\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const user = await confluenceService.getCurrentUser();\n // Access private method via bracket notation to avoid exposing it publicly\n const creds = await (\n confluenceService as unknown as { getCredentials: () => Promise<{ instanceUrl: string }> }\n ).getCredentials();\n\n const userName = user || 'Unknown User';\n const baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n\n return {\n owner: userName,\n name: 'Confluence Pages',\n fullName: `${userName}'s Confluence Pages`,\n url: `${baseUrl}/wiki`,\n };\n },\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n // Handle 'current' author\n const author = options.author === 'current' ? await this.getCurrentUser() : options.author;\n\n return confluenceService.getPages({\n days: options.days,\n limit: options.limit,\n author: author || undefined,\n });\n },\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await this.validate();\n return true;\n } catch {\n return false;\n }\n },\n\n async getCurrentUser(): Promise<string | null> {\n return confluenceService.getCurrentUser();\n },\n};\n","import { ConfluenceError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport type {\n ConfluencePage,\n ConfluenceSearchResponse,\n FetchConfluencePagesOptions,\n} from '../types/atlassian.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Confluence service for interacting with Confluence Cloud and Server REST API\n */\nexport class ConfluenceService {\n /**\n * Get stored Confluence credentials\n */\n private async getCredentials(): Promise<{\n email: string;\n apiToken: string;\n instanceUrl: string;\n }> {\n const creds = await storageService.getServiceCredentials('confluence');\n if (!creds || !creds.username || !creds.accessToken || !creds.instanceUrl) {\n throw new ConfluenceError('Not authenticated with Confluence', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n // Check token expiry\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new ConfluenceError('API token has expired', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n return {\n email: creds.username,\n apiToken: creds.accessToken,\n instanceUrl: creds.instanceUrl,\n };\n }\n\n /**\n * Make authenticated request to Confluence API\n */\n private async request<T>(endpoint: string, method = 'GET', body?: unknown): Promise<T> {\n const { email, apiToken, instanceUrl } = await this.getCredentials();\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n\n // Ensure instanceUrl has protocol\n const baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n\n logger.debug(`Confluence API: ${method} ${endpoint}`);\n\n const options: Parameters<typeof fetch>[1] = {\n method,\n headers: {\n Authorization: `Basic ${auth}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n };\n\n if (body) {\n options.body = JSON.stringify(body);\n }\n\n const response = await fetch(`${baseUrl}${endpoint}`, options);\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new ConfluenceError('Invalid or expired API token', {\n hint: 'Run: bragduck auth atlassian',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new ConfluenceError('Forbidden - check token permissions', {\n hint: 'Token needs: read access to pages',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new ConfluenceError('Resource not found', {\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new ConfluenceError('Rate limit exceeded', {\n hint: 'Wait a few minutes before trying again',\n originalError: statusText,\n });\n }\n\n throw new ConfluenceError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Validate Confluence instance and credentials\n */\n async validateConfluenceInstance(): Promise<void> {\n try {\n // Test with a simple content search\n await this.request<ConfluenceSearchResponse>('/wiki/rest/api/content?type=page&limit=1');\n } catch (error: unknown) {\n if (error instanceof ConfluenceError) {\n throw error;\n }\n throw new ConfluenceError('Could not access Confluence instance via API', {\n hint: 'Check that the instance URL is correct and your credentials are valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get current user's email\n */\n async getCurrentUser(): Promise<string | null> {\n try {\n const creds = await this.getCredentials();\n return creds.email;\n } catch {\n return null;\n }\n }\n\n /**\n * Build CQL query from options\n */\n private buildCQL(options: FetchConfluencePagesOptions): string {\n const queries: string[] = [];\n\n // Type filter\n queries.push('type=page');\n\n // Date filtering\n if (options.days) {\n queries.push(`lastModified >= now(\"-${options.days}d\")`);\n }\n\n // Author filtering\n if (options.author) {\n queries.push(`creator = \"${options.author}\"`);\n }\n\n // Custom CQL\n if (options.cql) {\n queries.push(`(${options.cql})`);\n }\n\n return queries.join(' AND ');\n }\n\n /**\n * Estimate page size for impact scoring\n */\n private estimatePageSize(page: ConfluencePage): number {\n const content = page.body?.storage?.value || '';\n // Rough heuristic: 1 line per 80 characters\n return Math.ceil(content.length / 80);\n }\n\n /**\n * Fetch pages with optional filtering\n */\n async getPages(options: FetchConfluencePagesOptions = {}): Promise<GitCommit[]> {\n const cql = this.buildCQL(options);\n\n const allPages: ConfluencePage[] = [];\n let start = 0;\n const limit = 100;\n\n // Pagination: loop until all results fetched\n while (true) {\n const params: Record<string, string> = {\n type: 'page',\n status: 'current',\n start: start.toString(),\n limit: limit.toString(),\n expand: 'version,body.storage',\n };\n\n if (cql) {\n params.cql = cql;\n }\n\n const queryString = Object.entries(params)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&');\n\n const endpoint = `/wiki/rest/api/content?${queryString}`;\n\n const response = await this.request<ConfluenceSearchResponse>(endpoint);\n\n allPages.push(...response.results);\n\n logger.debug(\n `Fetched ${response.results.length} pages (total: ${allPages.length})${response.results.length === limit ? ', fetching next page...' : ''}`\n );\n\n // Check if we've fetched all pages\n if (response.results.length < limit) {\n break;\n }\n\n // Check limit\n if (options.limit && allPages.length >= options.limit) {\n return allPages.slice(0, options.limit).map((page) => this.transformPageToCommit(page));\n }\n\n start += limit;\n }\n\n return allPages.map((page) => this.transformPageToCommit(page));\n }\n\n /**\n * Fetch pages for the current authenticated user\n */\n async getPagesByCurrentUser(\n options: Omit<FetchConfluencePagesOptions, 'author'> = {}\n ): Promise<GitCommit[]> {\n const email = await this.getCurrentUser();\n if (!email) {\n throw new ConfluenceError('Could not get current user');\n }\n\n return this.getPages({\n ...options,\n author: email,\n });\n }\n\n /**\n * Transform Confluence page to GitCommit format with external fields\n */\n transformPageToCommit(page: ConfluencePage, instanceUrl?: string): GitCommit {\n // Format message: title + version info\n const message = `${page.title}\\n\\n[Confluence Page v${page.version.number}]`;\n\n // Build URL (use provided instanceUrl or try to get from storage)\n let baseUrl = 'https://confluence.atlassian.net';\n if (instanceUrl) {\n baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n } else {\n try {\n const creds = storageService.getServiceCredentials('confluence') as {\n instanceUrl?: string;\n } | null;\n if (creds?.instanceUrl) {\n baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n }\n } catch {\n // Use default if credentials not available\n }\n }\n const url = `${baseUrl}/wiki${page._links.webui}`;\n\n return {\n sha: page.id,\n message,\n author: page.version.by.displayName,\n authorEmail: page.version.by.email,\n date: page.version.when,\n url,\n diffStats: {\n filesChanged: 1,\n insertions: this.estimatePageSize(page),\n deletions: 0,\n },\n externalId: page.id,\n externalType: 'page',\n externalSource: 'confluence',\n externalUrl: url,\n };\n }\n}\n\nexport const confluenceService = new ConfluenceService();\n","import boxen from 'boxen';\nimport { authService } from '../services/auth.service.js';\nimport { initCommand } from '../commands/init.js';\nimport { logger } from './logger.js';\nimport { promptConfirm } from '../ui/prompts.js';\nimport { theme, boxStyles } from '../ui/theme.js';\n\n/**\n * Ensure user is authenticated, offering to run init if not\n * Returns true if authenticated (or after successful auth), false if user declined\n */\nexport async function ensureAuthenticated(): Promise<boolean> {\n const isAuthenticated = await authService.isAuthenticated();\n\n if (isAuthenticated) {\n return true;\n }\n\n // User is not authenticated - offer to authenticate now\n logger.log('');\n logger.log(\n boxen(\n theme.warning('Not authenticated') +\n '\\n\\n' +\n 'You need to be logged in to use this command.\\n\\n' +\n 'Would you like to authenticate now?',\n boxStyles.warning\n )\n );\n logger.log('');\n\n const shouldAuth = await promptConfirm('Authenticate now?', true);\n\n if (!shouldAuth) {\n logger.log('');\n logger.info(\n theme.secondary('Authentication skipped. Run ') +\n theme.command('bragduck auth login') +\n theme.secondary(\" when you're ready to authenticate.\")\n );\n logger.log('');\n return false;\n }\n\n // Run init command inline\n try {\n await initCommand();\n return true;\n } catch {\n // Init command will handle its own error display\n return false;\n }\n}\n\n/**\n * Simple authentication check without offering init\n * Used for commands that should fail fast if not authenticated\n */\nexport async function requireAuthentication(): Promise<void> {\n const isAuthenticated = await authService.isAuthenticated();\n\n if (!isAuthenticated) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('Not authenticated') +\n '\\n\\n' +\n 'You need to be logged in to use this command.\\n\\n' +\n theme.secondary('Run ') +\n theme.command('bragduck auth login') +\n theme.secondary(' to authenticate.'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n","import ora from 'ora';\nimport boxen from 'boxen';\nimport chalk from 'chalk';\nimport { authService } from '../services/auth.service.js';\nimport { logger } from '../utils/logger.js';\nimport type { BragduckError } from '../utils/errors.js';\n\n/**\n * Init command: Authenticate with Bragduck\n */\nexport async function initCommand(): Promise<void> {\n // Deprecation warning\n logger.log('');\n logger.log(\n boxen(\n chalk.yellow.bold('⚠ Deprecation Notice') +\n '\\n\\n' +\n `The ${chalk.cyan('init')} command is deprecated.\\n` +\n `Please use ${chalk.cyan('bragduck auth login')} instead.\\n\\n` +\n chalk.dim('This command will be removed in v3.0.0'),\n {\n padding: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n dimBorder: true,\n }\n )\n );\n logger.log('');\n\n logger.info('Starting authentication flow...');\n logger.log('');\n\n // Check if already authenticated\n const isAuthenticated = await authService.isAuthenticated();\n if (isAuthenticated) {\n const userInfo = authService.getUserInfo();\n if (userInfo) {\n logger.log(\n boxen(\n `${chalk.yellow('Already authenticated!')}\\n\\n` +\n `${chalk.gray('User:')} ${userInfo.name}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('Run')} ${chalk.cyan('bragduck logout')} ${chalk.dim('to sign out')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n }\n )\n );\n logger.log('');\n globalThis.setTimeout(() => {\n process.exit(0);\n }, 100);\n return;\n }\n }\n\n const spinner = ora('Opening browser for authentication...').start();\n\n try {\n // Start OAuth flow\n spinner.text = 'Waiting for authentication...';\n const userInfo = await authService.login();\n\n spinner.succeed('Authentication successful!');\n logger.log('');\n\n // Show success message\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Successfully authenticated!')}\\n\\n` +\n `${chalk.gray('Welcome,')} ${chalk.cyan(userInfo.name)}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('You can now use')} ${chalk.cyan('bragduck scan')} ${chalk.dim('to create brags!')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n logger.log('');\n\n // Exit successfully - force immediate exit\n // Use setTimeout to ensure all logs are flushed\n globalThis.setTimeout(() => {\n process.exit(0);\n }, 100);\n\n // Return to prevent further execution\n return;\n } catch (error) {\n spinner.fail('Authentication failed');\n logger.log('');\n\n const err = error as BragduckError;\n\n // Show error message\n logger.log(\n boxen(\n `${chalk.red.bold('✗ Authentication Failed')}\\n\\n` +\n `${err.message}\\n\\n` +\n `${chalk.dim('Hint:')} ${getErrorHint(err)}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'red',\n }\n )\n );\n\n process.exit(1);\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError): string {\n if (error.name === 'OAuthError') {\n if (error.message.includes('timeout')) {\n return 'Try again and complete the authentication within 2 minutes';\n }\n if (error.message.includes('CSRF')) {\n return 'This might be a security issue. Try running the command again';\n }\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and firewall settings';\n }\n\n if (error.name === 'AuthenticationError') {\n return 'Verify your credentials and try again';\n }\n\n return 'Try running the command again or check the logs with DEBUG=* bragduck init';\n}\n","import { checkbox, confirm, input, select, editor } from '@inquirer/prompts';\nimport boxen from 'boxen';\nimport type { GitCommit } from '../types/git.types.js';\nimport type { RefinedCommit, RefinedBrag, OrganisationItem } from '../types/api.types.js';\nimport { formatCommitChoice } from './formatters.js';\nimport { theme, colors, boxStyles } from './theme.js';\n\n/**\n * Prompt user to select commits\n */\nexport async function promptSelectCommits(commits: GitCommit[]): Promise<string[]> {\n if (commits.length === 0) {\n return [];\n }\n\n const choices = commits.map((commit) => ({\n name: formatCommitChoice(commit),\n value: commit.sha,\n checked: false,\n }));\n\n const selected = await checkbox({\n message: 'Select PRs to brag about (use space to select, enter to confirm):',\n choices,\n pageSize: 10,\n loop: false,\n });\n\n return selected;\n}\n\n/**\n * Prompt user to confirm action\n */\nexport async function promptConfirm(\n message: string,\n defaultValue: boolean = true\n): Promise<boolean> {\n return await confirm({\n message,\n default: defaultValue,\n });\n}\n\n/**\n * Prompt user for text input\n */\nexport async function promptInput(message: string, defaultValue?: string): Promise<string> {\n return await input({\n message,\n default: defaultValue,\n });\n}\n\n/**\n * Prompt user to select from options\n */\nexport async function promptSelect<T extends string>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return await select({\n message,\n choices,\n });\n}\n\n/**\n * Prompt for number of days to scan\n */\nexport async function promptDaysToScan(defaultDays: number = 30): Promise<number> {\n const choices = [\n { name: '7 days', value: '7', description: 'Last week' },\n { name: '30 days (Recommended)', value: '30', description: 'Last month' },\n { name: '60 days', value: '60', description: 'Last 2 months' },\n { name: '90 days', value: '90', description: 'Last 3 months' },\n { name: 'Custom', value: 'custom', description: 'Enter custom number of days' },\n ];\n\n const selected = await select({\n message: 'How many days back should we scan for PRs?',\n choices,\n default: '30',\n });\n\n if (selected === 'custom') {\n const customDays = await input({\n message: 'Enter number of days:',\n default: defaultDays.toString(),\n validate: (value) => {\n const num = parseInt(value, 10);\n if (isNaN(num) || num <= 0) {\n return 'Please enter a valid positive number';\n }\n return true;\n },\n });\n return parseInt(customDays, 10);\n }\n\n return parseInt(selected, 10);\n}\n\n/**\n * Prompt user to select sort option before PR selection\n */\nexport async function promptSortOption(): Promise<'date' | 'size' | 'files' | 'none'> {\n const choices = [\n {\n name: 'By date (newest first)',\n value: 'date' as const,\n description: 'Most recent PRs first',\n },\n { name: 'By size (largest first)', value: 'size' as const, description: 'Most lines changed' },\n { name: 'By files (most files)', value: 'files' as const, description: 'Most files changed' },\n { name: 'No sorting', value: 'none' as const, description: 'Keep original order' },\n ];\n\n return await select({\n message: 'How would you like to sort the PRs?',\n choices,\n default: 'date',\n });\n}\n\n/**\n * Prompt user to select organisation for brags\n */\nexport async function promptSelectOrganisation(\n organisations: OrganisationItem[]\n): Promise<string | null> {\n const choices = [\n { name: 'No company', value: 'none' as const },\n ...organisations.map((org) => ({\n name: org.name,\n value: org.id,\n })),\n ];\n\n const selected = await select({\n message: 'Attach brags to which company?',\n choices,\n default: 'none',\n });\n\n return selected === 'none' ? null : selected;\n}\n\n/**\n * Prompt user to review and edit brags before creation\n */\nexport async function promptReviewBrags(\n refinedBrags: RefinedBrag[] | RefinedCommit[],\n selectedCommits?: GitCommit[]\n): Promise<(RefinedBrag | RefinedCommit)[]> {\n const acceptedBrags: (RefinedBrag | RefinedCommit)[] = [];\n\n console.log('\\n' + theme.info('Review each brag before creation:') + '\\n');\n\n for (let i = 0; i < refinedBrags.length; i++) {\n let currentBrag = refinedBrags[i];\n const current = i + 1;\n const total = refinedBrags.length;\n let reviewingBrag = true;\n\n // Loop until user accepts, skips, or cancels\n while (reviewingBrag) {\n // Check if this is the new RefinedBrag type\n const isNewBragType = !('sha' in currentBrag);\n\n // Display brag details\n let displaySha: string = `#${i + 1}`;\n let prUrl: string | undefined;\n\n if (isNewBragType && selectedCommits) {\n const commit = selectedCommits[i];\n if (commit) {\n displaySha = commit.sha.startsWith('pr-')\n ? commit.sha.replace('pr-', '#')\n : commit.sha.substring(0, 7);\n prUrl = commit.url;\n }\n } else if (!isNewBragType) {\n const commit = currentBrag as RefinedCommit;\n displaySha = commit.sha.startsWith('pr-')\n ? commit.sha.replace('pr-', '#')\n : commit.sha.substring(0, 7);\n prUrl = commit.commit_url;\n } else {\n displaySha = `#${i + 1}`;\n }\n\n // Get impact score\n const impactScore = isNewBragType\n ? (currentBrag as RefinedBrag).suggested_impactLevel?.toString() || 'N/A'\n : (currentBrag as RefinedCommit).impact_score?.toString() || 'N/A';\n\n let bragDetails =\n `${theme.step(current, total)} ${colors.highlight(displaySha)}\\n\\n` +\n `${theme.label('Title')} ${colors.white(currentBrag.refined_title)}\\n\\n` +\n `${theme.label('Description')}\\n${colors.white(currentBrag.refined_description)}\\n\\n` +\n `${theme.label('Tags')} ${colors.primary((currentBrag.suggested_tags || []).join(', ') || 'none')}\\n\\n` +\n `${theme.label('Impact Score')} ${colors.highlight(impactScore)}`;\n\n // Add PR URL if available\n if (prUrl) {\n bragDetails += `\\n\\n${theme.label('PR Link')} ${colors.link(prUrl)}`;\n }\n\n console.log(boxen(bragDetails, boxStyles.info));\n console.log('');\n\n // Prompt for action\n const action = await select({\n message: `What would you like to do with this brag?`,\n choices: [\n { name: '✓ Accept', value: 'accept', description: 'Add this brag as-is' },\n { name: '✎ Edit title', value: 'edit-title', description: 'Modify the title' },\n {\n name: '✎ Edit description',\n value: 'edit-desc',\n description: 'Modify the description',\n },\n { name: '✎ Edit both', value: 'edit-both', description: 'Modify title and description' },\n { name: '✗ Skip', value: 'skip', description: 'Skip this brag' },\n ...(current < total\n ? [\n {\n name: '✓ Accept all remaining',\n value: 'accept-all',\n description: 'Accept this and all remaining brags',\n },\n ]\n : []),\n { name: '✗ Cancel', value: 'cancel', description: 'Cancel and discard all brags' },\n ],\n });\n\n if (action === 'cancel') {\n return [];\n }\n\n if (action === 'accept-all') {\n acceptedBrags.push(currentBrag);\n // Add all remaining brags\n for (let j = i + 1; j < refinedBrags.length; j++) {\n acceptedBrags.push(refinedBrags[j]);\n }\n reviewingBrag = false;\n // Skip to end since we accepted all\n i = refinedBrags.length - 1;\n break;\n }\n\n if (action === 'skip') {\n reviewingBrag = false;\n continue;\n }\n\n if (action === 'accept') {\n acceptedBrags.push(currentBrag);\n reviewingBrag = false;\n continue;\n }\n\n // Handle editing\n let editedBrag = { ...currentBrag };\n\n if (action === 'edit-title' || action === 'edit-both') {\n console.log('');\n const newTitle = await input({\n message: 'Enter new title:',\n default: currentBrag.refined_title,\n });\n editedBrag.refined_title = newTitle;\n }\n\n if (action === 'edit-desc' || action === 'edit-both') {\n console.log('');\n const newDesc = await editor({\n message: 'Edit description (will open your default editor):',\n default: currentBrag.refined_description,\n });\n editedBrag.refined_description = newDesc;\n }\n\n // Update current brag with edits and loop back to review\n currentBrag = editedBrag;\n console.log('\\n' + theme.success('✓ Changes saved. Review your edits:') + '\\n');\n }\n }\n\n return acceptedBrags;\n}\n","import Table from 'cli-table3';\nimport terminalLink from 'terminal-link';\nimport type { GitCommit } from '../types/git.types.js';\nimport type { RefinedCommit, RefinedBrag } from '../types/api.types.js';\nimport { theme, colors, getSizeIndicator, formatDiffStats, tableStyles } from './theme.js';\n\n/**\n * Format a commit for display in checkbox list\n */\nexport function formatCommitChoice(commit: GitCommit): string {\n // Handle PR format (pr-123) by displaying as #123\n let displaySha: string;\n if (commit.sha.startsWith('pr-')) {\n const prNumber = commit.sha.replace('pr-', '#');\n displaySha = colors.highlight(prNumber);\n } else {\n displaySha = colors.highlight(commit.sha.substring(0, 7));\n }\n\n const lines = commit.message.split('\\n');\n const title = lines[0]; // First line only\n\n // Extract PR body preview if available (lines after the first)\n let bodyPreview = '';\n if (lines.length > 1) {\n const body = lines.slice(1).join(' ').trim();\n if (body.length > 0) {\n const preview = body.length > 80 ? body.substring(0, 80) + '...' : body;\n bodyPreview = `\\n ${colors.infoDim(preview)}`;\n }\n }\n\n const author = colors.info(`by ${commit.author}`);\n const date = colors.info(new Date(commit.date).toLocaleDateString());\n\n let stats = '';\n let sizeIndicator = '';\n if (commit.diffStats) {\n const { filesChanged, insertions, deletions } = commit.diffStats;\n sizeIndicator = ` ${getSizeIndicator(insertions, deletions)}`;\n stats = colors.info(` [${filesChanged} files, ${formatDiffStats(insertions, deletions)}]`);\n }\n\n return `${displaySha} ${title}${sizeIndicator}${stats}\\n ${author} • ${date}${bodyPreview}`;\n}\n\n/**\n * Format refined commits as a preview table\n */\nexport function formatRefinedCommitsTable(\n brags: RefinedBrag[] | RefinedCommit[],\n selectedCommits?: GitCommit[]\n): string {\n const table = new Table({\n head: [\n colors.primary('SHA'),\n colors.primary('Original'),\n colors.primary('Refined Title'),\n colors.primary('Description'),\n colors.primary('Tags'),\n ],\n colWidths: [12, 28, 30, 40, 20],\n wordWrap: true,\n style: tableStyles.default.style,\n });\n\n brags.forEach((brag, index) => {\n // Handle both RefinedBrag and RefinedCommit types\n const isNewBragType = !('sha' in brag);\n\n // Get SHA - either from brag directly or from selectedCommits\n let displaySha: string = `#${index + 1}`;\n if (isNewBragType && selectedCommits) {\n const commit = selectedCommits[index];\n if (commit && commit.sha.startsWith('pr-')) {\n displaySha = commit.sha.replace('pr-', '#');\n } else if (commit) {\n displaySha = commit.sha.substring(0, 7);\n }\n } else if (!isNewBragType) {\n const commit = brag as RefinedCommit;\n if (commit.sha.startsWith('pr-')) {\n displaySha = commit.sha.replace('pr-', '#');\n } else {\n displaySha = commit.sha.substring(0, 7);\n }\n } else {\n displaySha = `#${index + 1}`;\n }\n\n // Get original message\n const original = isNewBragType\n ? typeof (brag as RefinedBrag).original_input === 'string'\n ? (brag as RefinedBrag).original_input.split('\\n')[0] || ''\n : 'Raw input'\n : (brag as RefinedCommit).original_message.split('\\n')[0] || '';\n\n const title = brag.refined_title;\n const description =\n brag.refined_description.length > 100\n ? brag.refined_description.substring(0, 97) + '...'\n : brag.refined_description;\n const tags = (brag.suggested_tags || []).join(', ') || 'none';\n\n // Add row number for easy reference\n const rowNum = colors.infoDim(`${index + 1}.`);\n\n table.push([\n `${rowNum} ${colors.highlight(displaySha)}`,\n colors.info(original),\n colors.white(title),\n colors.dim(description),\n colors.primary(tags),\n ]);\n });\n\n return table.toString();\n}\n\n/**\n * Format commit statistics\n */\nexport function formatCommitStats(commits: GitCommit[]): string {\n const totalFiles = commits.reduce((sum, c) => sum + (c.diffStats?.filesChanged || 0), 0);\n const totalInsertions = commits.reduce((sum, c) => sum + (c.diffStats?.insertions || 0), 0);\n const totalDeletions = commits.reduce((sum, c) => sum + (c.diffStats?.deletions || 0), 0);\n\n return (\n colors.info('Total changes: ') +\n colors.white(`${totalFiles} files`) +\n colors.info(', ') +\n formatDiffStats(totalInsertions, totalDeletions)\n );\n}\n\n/**\n * Format selection summary for user feedback\n */\nexport function formatSelectionSummary(count: number, commits: GitCommit[]): string {\n const totalFiles = commits.reduce((sum, c) => sum + (c.diffStats?.filesChanged || 0), 0);\n const totalInsertions = commits.reduce((sum, c) => sum + (c.diffStats?.insertions || 0), 0);\n const totalDeletions = commits.reduce((sum, c) => sum + (c.diffStats?.deletions || 0), 0);\n\n const selectedText = theme.success(`Selected ${theme.count(count)} PR${count > 1 ? 's' : ''}`);\n const stats = `${theme.count(totalFiles)} files changed, ${formatDiffStats(totalInsertions, totalDeletions)}`;\n\n return `\\n${selectedText}: ${stats}`;\n}\n\n/**\n * Format success message for created brags\n */\nexport function formatSuccessMessage(count: number): string {\n const emoji = '🎉';\n const title = colors.successBold(\n `${emoji} Successfully created ${count} brag${count > 1 ? 's' : ''}!`\n );\n const message = colors.white('\\nYour achievements are now saved and ready to showcase.');\n const hint =\n theme.secondary('\\nRun ') +\n theme.command('bragduck list') +\n theme.secondary(' to see all your brags');\n\n // Create clickable hyperlink using terminal-link (OSC 8 standard)\n // Supported by: iTerm2, Terminal.app, Hyper, Windows Terminal, VS Code terminal\n // Usage: CMD+click (macOS) or Ctrl+click (Windows/Linux)\n // Falls back to plain URL text in terminals without hyperlink support\n // Hover effects and exact behavior vary by terminal implementation\n const url = 'https://bragduck.com/app/brags';\n const clickableUrl = terminalLink(url, url, {\n fallback: () => colors.primary(url),\n });\n const webUrl =\n theme.secondary('\\n\\nOr, check ') + clickableUrl + theme.secondary(' to see all your brags');\n\n return `${title}${message}${hint}${webUrl}`;\n}\n\n/**\n * Format error message for display\n */\nexport function formatErrorMessage(message: string, hint?: string): string {\n const title = colors.errorBold('✗ Error');\n const error = colors.white(message);\n const hintText = hint ? theme.secondary('\\n\\nHint: ') + theme.command(hint) : '';\n\n return `${title}\\n\\n${error}${hintText}`;\n}\n\n/**\n * Format progress message\n */\nexport function formatProgress(current: number, total: number, label: string): string {\n const percentage = Math.round((current / total) * 100);\n const bar = '█'.repeat(Math.floor(percentage / 5)) + '░'.repeat(20 - Math.floor(percentage / 5));\n\n return `${colors.primary(bar)} ${colors.white(`${percentage}%`)} ${theme.progress(label)}`;\n}\n\n/**\n * Format hierarchical data with tree structure\n */\nexport function formatHierarchical(items: string[], isLast: boolean[] = []): string {\n return items\n .map((item, index) => {\n const isLastItem = index === items.length - 1;\n const prefix = isLast\n .slice(0, -1)\n .map((last) => (last ? ' ' : '│ '))\n .join('');\n const connector = isLastItem ? '└─' : '├─';\n\n return `${prefix}${connector} ${item}`;\n })\n .join('\\n');\n}\n","import ora, { Ora } from 'ora';\nimport { theme, colors } from './theme.js';\n\n/**\n * Create a spinner with consistent styling\n */\nexport function createSpinner(text: string): Ora {\n return ora({\n text,\n color: 'cyan',\n spinner: 'dots',\n });\n}\n\n/**\n * Create a step-aware spinner with progress indicator\n */\nexport function createStepSpinner(currentStep: number, totalSteps: number, text: string): Ora {\n const stepIndicator = theme.step(currentStep, totalSteps);\n return ora({\n text: `${stepIndicator} ${text}`,\n color: 'cyan',\n spinner: 'dots',\n });\n}\n\n/**\n * Update step spinner with new step and text\n */\nexport function updateStepSpinner(\n spinner: Ora,\n currentStep: number,\n totalSteps: number,\n text: string\n): void {\n const stepIndicator = theme.step(currentStep, totalSteps);\n spinner.text = `${stepIndicator} ${text}`;\n}\n\n/**\n * Spinner for fetching commits\n */\nexport function fetchingCommitsSpinner(days: number): Ora {\n return createSpinner(`Fetching commits from the last ${days} days...`);\n}\n\n/**\n * Spinner for fetching PRs\n */\nexport function fetchingPRsSpinner(days: number): Ora {\n return createSpinner(`Fetching merged PRs from the last ${days} days...`);\n}\n\n/**\n * Spinner for refining commits\n */\nexport function refiningCommitsSpinner(count: number): Ora {\n return createSpinner(`Refining ${count} commit${count > 1 ? 's' : ''} with AI...`);\n}\n\n/**\n * Spinner for creating brags\n */\nexport function creatingBragsSpinner(count: number): Ora {\n return createSpinner(`Creating ${count} brag${count > 1 ? 's' : ''}...`);\n}\n\n/**\n * Spinner for fetching brags\n */\nexport function fetchingBragsSpinner(): Ora {\n return createSpinner('Fetching your brags...');\n}\n\n/**\n * Update spinner with new text\n */\nexport function updateSpinner(spinner: Ora, text: string): void {\n spinner.text = text;\n}\n\n/**\n * Succeed spinner with custom text\n */\nexport function succeedSpinner(spinner: Ora, text?: string): void {\n if (text) {\n spinner.succeed(colors.success(text));\n } else {\n spinner.succeed();\n }\n}\n\n/**\n * Fail spinner with custom text\n */\nexport function failSpinner(spinner: Ora, text?: string): void {\n if (text) {\n spinner.fail(colors.error(text));\n } else {\n spinner.fail();\n }\n}\n\n/**\n * Warn spinner with custom text\n */\nexport function warnSpinner(spinner: Ora, text?: string): void {\n if (text) {\n spinner.warn(colors.warning(text));\n } else {\n spinner.warn();\n }\n}\n\n/**\n * Complete a step spinner with success\n */\nexport function succeedStepSpinner(\n spinner: Ora,\n currentStep: number,\n totalSteps: number,\n text: string\n): void {\n const stepIndicator = theme.step(currentStep, totalSteps);\n spinner.succeed(`${stepIndicator} ${colors.success(text)}`);\n}\n\n/**\n * Fail a step spinner with error\n */\nexport function failStepSpinner(\n spinner: Ora,\n currentStep: number,\n totalSteps: number,\n text: string\n): void {\n const stepIndicator = theme.step(currentStep, totalSteps);\n spinner.fail(`${stepIndicator} ${colors.error(text)}`);\n}\n","import { confirm } from '@inquirer/prompts';\nimport boxen from 'boxen';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { authService } from '../services/auth.service.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Logout command: Clear stored credentials\n */\nexport async function logoutCommand(): Promise<void> {\n // Check if user is authenticated\n const isAuthenticated = await authService.isAuthenticated();\n\n if (!isAuthenticated) {\n logger.log(\n boxen(\n `${chalk.yellow('Not currently authenticated')}\\n\\n${chalk.dim('Nothing to logout from')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n }\n )\n );\n return;\n }\n\n // Get user info to show in confirmation\n const userInfo = authService.getUserInfo();\n const userName = userInfo?.name || 'Unknown User';\n\n logger.log('');\n\n // Confirm logout\n const shouldLogout = await confirm({\n message: `Are you sure you want to logout? (${chalk.cyan(userName)})`,\n default: false,\n });\n\n if (!shouldLogout) {\n logger.info('Logout cancelled');\n return;\n }\n\n const spinner = ora('Logging out...').start();\n\n try {\n await authService.logout();\n spinner.succeed('Logged out successfully');\n logger.log('');\n\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Logged out successfully')}\\n\\n` +\n `${chalk.dim('Your credentials have been cleared')}\\n\\n` +\n `${chalk.dim('Run')} ${chalk.cyan('bragduck init')} ${chalk.dim('to login again')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n } catch {\n spinner.fail('Logout failed');\n logger.error('Failed to logout. Please try again.');\n process.exit(1);\n }\n}\n","import boxen from 'boxen';\nimport chalk from 'chalk';\nimport { CancelPromptError } from '@inquirer/core';\nimport { githubService } from '../services/github.service.js';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from '../utils/logger.js';\nimport { openBrowser } from '../utils/browser.js';\nimport { ensureAuthenticated } from '../utils/auth-helper.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport {\n promptSelectCommits,\n promptDaysToScan,\n promptSortOption,\n promptReviewBrags,\n promptConfirm,\n promptSelectOrganisation,\n} from '../ui/prompts.js';\nimport { authService } from '../services/auth.service.js';\nimport { createStepSpinner, succeedStepSpinner, failStepSpinner } from '../ui/spinners.js';\nimport {\n formatRefinedCommitsTable,\n formatSuccessMessage,\n formatErrorMessage,\n formatCommitStats,\n formatSelectionSummary,\n} from '../ui/formatters.js';\nimport { theme, colors, boxStyles } from '../ui/theme.js';\nimport type { GitCommit } from '../types/git.types.js';\nimport type { CreateBragItem, RefinedBrag } from '../types/api.types.js';\nimport type { GitHubPR } from '../types/github.types.js';\n\n/**\n * Scan command options\n */\nexport interface ScanCommandOptions {\n days?: number;\n all?: boolean; // Include all commits, not just current user's\n}\n\n/**\n * Scan command: Scan git commits and create brags\n */\nexport async function scanCommand(options: ScanCommandOptions = {}): Promise<void> {\n // Deprecation warning\n logger.log('');\n logger.log(\n boxen(\n chalk.yellow.bold('⚠ Deprecation Notice') +\n '\\n\\n' +\n `The ${chalk.cyan('scan')} command is deprecated.\\n` +\n `Please use ${chalk.cyan('bragduck sync')} instead.\\n\\n` +\n chalk.dim('This command will be removed in v3.0.0'),\n {\n padding: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n dimBorder: true,\n }\n )\n );\n logger.log('');\n\n const TOTAL_STEPS = 5;\n\n try {\n // Step 1: Check authentication\n const isAuthenticated = await ensureAuthenticated();\n if (!isAuthenticated) {\n process.exit(1);\n }\n\n // Step 1.5: Check subscription plan\n logger.debug('Fetching subscription status...');\n const subscriptionStatus = await apiService.getSubscriptionStatus();\n\n logger.debug('Subscription status response:', JSON.stringify(subscriptionStatus, null, 2));\n logger.debug(\n `Checking tier: \"${subscriptionStatus.tier}\" (type: ${typeof subscriptionStatus.tier})`\n );\n logger.debug(`Tier === 'FREE': ${subscriptionStatus.tier === 'FREE'}`);\n\n if (subscriptionStatus.tier === 'FREE') {\n logger.debug('FREE tier detected - blocking scan command');\n logger.log('');\n logger.log(\n boxen(\n theme.warning('CLI Access Requires Subscription') +\n '\\n\\n' +\n 'The Bragduck CLI is available for Plus and Pro subscribers.\\n' +\n 'Upgrade now to unlock:\\n\\n' +\n ' • Automatic PR scanning\\n' +\n ' • AI-powered brag generation\\n' +\n ' • Unlimited brags\\n\\n' +\n colors.highlight('Start your free trial today!'),\n {\n ...boxStyles.warning,\n padding: 1,\n margin: 1,\n }\n )\n );\n logger.log('');\n\n const shouldOpenBrowser = await promptConfirm(\n 'Open subscription plans in your browser?',\n true\n );\n\n if (shouldOpenBrowser) {\n logger.log('');\n const plansUrl = 'https://bragduck.com/app/settings/plans';\n\n try {\n await openBrowser(plansUrl);\n logger.info(theme.secondary('Opening browser...'));\n } catch {\n logger.warning('Could not open browser automatically');\n logger.info(`Please visit: ${theme.value(plansUrl)}`);\n }\n }\n\n logger.log('');\n return;\n }\n\n logger.debug(`Subscription tier \"${subscriptionStatus.tier}\" - proceeding with scan`);\n\n // Step 2: Validate GitHub repository\n const repoSpinner = createStepSpinner(1, TOTAL_STEPS, 'Validating GitHub repository');\n repoSpinner.start();\n\n await githubService.validateGitHubRepository();\n const repoInfo = await githubService.getRepositoryInfo();\n\n succeedStepSpinner(\n repoSpinner,\n 1,\n TOTAL_STEPS,\n `Repository: ${theme.value(repoInfo.fullName)}`\n );\n logger.log('');\n\n // Step 3: Prompt for days to scan (if not provided)\n let days = options.days;\n if (!days) {\n const defaultDays = storageService.getConfig('defaultCommitDays');\n days = await promptDaysToScan(defaultDays);\n logger.log('');\n }\n\n // Step 4: Fetch PRs\n const prSpinner = createStepSpinner(\n 2,\n TOTAL_STEPS,\n `Fetching merged PRs from the last ${days} days`\n );\n prSpinner.start();\n\n let prs: GitHubPR[];\n if (options.all) {\n prs = await githubService.getMergedPRs({ days });\n } else {\n prs = await githubService.getPRsByCurrentUser({ days });\n }\n\n // Transform PRs to GitCommit format for UI compatibility\n const commits: GitCommit[] = prs.map((pr) => githubService.transformPRToCommit(pr));\n\n if (commits.length === 0) {\n failStepSpinner(prSpinner, 2, TOTAL_STEPS, `No merged PRs found in the last ${days} days`);\n logger.log('');\n logger.info('Try increasing the number of days or check your GitHub activity');\n return;\n }\n\n succeedStepSpinner(\n prSpinner,\n 2,\n TOTAL_STEPS,\n `Found ${theme.count(commits.length)} PR${commits.length > 1 ? 's' : ''}`\n );\n logger.log('');\n\n // Show commit statistics\n logger.log(formatCommitStats(commits));\n logger.log('');\n\n // Step 5: Sort and select PRs (skip sorting if only 1 PR)\n let sortedCommits = [...commits];\n if (commits.length > 1) {\n const sortOption = await promptSortOption();\n logger.log('');\n\n // Sort commits based on user preference\n if (sortOption === 'date') {\n sortedCommits.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());\n } else if (sortOption === 'size') {\n sortedCommits.sort((a, b) => {\n const sizeA = (a.diffStats?.insertions || 0) + (a.diffStats?.deletions || 0);\n const sizeB = (b.diffStats?.insertions || 0) + (b.diffStats?.deletions || 0);\n return sizeB - sizeA;\n });\n } else if (sortOption === 'files') {\n sortedCommits.sort((a, b) => {\n const filesA = a.diffStats?.filesChanged || 0;\n const filesB = b.diffStats?.filesChanged || 0;\n return filesB - filesA;\n });\n }\n }\n\n const selectedShas = await promptSelectCommits(sortedCommits);\n\n if (selectedShas.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No PRs selected. Scan cancelled.'));\n logger.log('');\n return;\n }\n\n const selectedCommits = sortedCommits.filter((c) => selectedShas.includes(c.sha));\n\n // Show selection summary\n logger.log(formatSelectionSummary(selectedCommits.length, selectedCommits));\n logger.log('');\n\n // Check for duplicate PRs already in Bragduck\n const existingBrags = await apiService.listBrags({ limit: 100 });\n logger.debug(`Fetched ${existingBrags.brags.length} existing brags`);\n\n // Match by PR URL stored in attachments\n const existingUrls = new Set(existingBrags.brags.flatMap((b) => b.attachments || []));\n logger.debug(`Existing PR URLs in attachments: ${existingUrls.size}`);\n\n const duplicates = selectedCommits.filter((c) => c.url && existingUrls.has(c.url));\n const newCommits = selectedCommits.filter((c) => !c.url || !existingUrls.has(c.url));\n\n logger.debug(`Duplicates: ${duplicates.length}, New: ${newCommits.length}`);\n\n if (duplicates.length > 0) {\n logger.log('');\n logger.info(\n colors.warning(\n `${duplicates.length} PR${duplicates.length > 1 ? 's' : ''} already added to Bragduck - skipping`\n )\n );\n logger.log('');\n }\n\n if (newCommits.length === 0) {\n logger.log('');\n logger.info(\n theme.secondary('All selected PRs already exist in Bragduck. Nothing to refine.')\n );\n logger.log('');\n return;\n }\n\n // Step 6: Refine commits with AI\n const refineSpinner = createStepSpinner(\n 3,\n TOTAL_STEPS,\n `Refining ${theme.count(newCommits.length)} PR${newCommits.length > 1 ? 's' : ''} with AI`\n );\n refineSpinner.start();\n\n const refineRequest = {\n brags: newCommits.map((c) => ({\n text: c.message,\n date: c.date,\n title: c.message.split('\\n')[0], // First line as initial title\n })),\n };\n\n const refineResponse = await apiService.refineBrags(refineRequest);\n let refinedBrags = refineResponse.refined_brags;\n\n succeedStepSpinner(refineSpinner, 3, TOTAL_STEPS, 'PRs refined successfully');\n logger.log('');\n\n // Step 7: Review and edit brags\n logger.info('Preview of refined brags:');\n logger.log('');\n logger.log(formatRefinedCommitsTable(refinedBrags, newCommits));\n logger.log('');\n\n // Interactive review with option to edit\n const acceptedBrags = await promptReviewBrags(refinedBrags, newCommits);\n\n if (acceptedBrags.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No brags selected for creation. Scan cancelled.'));\n logger.log('');\n return;\n }\n\n logger.log('');\n\n // Step 8: Select organisation (if user has any)\n let selectedOrgId: string | null = null;\n const userInfo = authService.getUserInfo();\n if (userInfo?.id) {\n try {\n const orgsResponse = await apiService.listUserOrganisations(userInfo.id);\n if (orgsResponse.items.length > 0) {\n selectedOrgId = await promptSelectOrganisation(orgsResponse.items);\n logger.log('');\n }\n } catch {\n logger.debug('Failed to fetch organisations, skipping org selection');\n }\n }\n\n // Step 9: Create brags\n const createSpinner = createStepSpinner(\n 4,\n TOTAL_STEPS,\n `Creating ${theme.count(acceptedBrags.length)} brag${acceptedBrags.length > 1 ? 's' : ''}`\n );\n createSpinner.start();\n\n const createRequest = {\n brags: acceptedBrags.map((refined: RefinedBrag, index: number): CreateBragItem => {\n const originalCommit = newCommits[index];\n return {\n commit_sha: originalCommit?.sha || `brag-${index}`,\n title: refined.refined_title,\n description: refined.refined_description,\n tags: refined.suggested_tags,\n repository: repoInfo.url,\n date: originalCommit?.date || '',\n commit_url: originalCommit?.url || '',\n impact_score: refined.suggested_impactLevel,\n impact_description: refined.impact_description,\n attachments: originalCommit?.url ? [originalCommit.url] : [],\n orgId: selectedOrgId || undefined,\n };\n }),\n };\n\n const createResponse = await apiService.createBrags(createRequest);\n\n succeedStepSpinner(\n createSpinner,\n 4,\n TOTAL_STEPS,\n `Created ${theme.count(createResponse.created)} brag${createResponse.created > 1 ? 's' : ''}`\n );\n logger.log('');\n\n // Final: Show success message\n logger.log(boxen(formatSuccessMessage(createResponse.created), boxStyles.success));\n } catch (error) {\n // Handle user cancellation (Ctrl+C or ESC)\n if (error instanceof CancelPromptError) {\n logger.log('');\n logger.info(theme.secondary('Scan cancelled.'));\n logger.log('');\n return;\n }\n\n const err = error as BragduckError;\n\n logger.log('');\n logger.log(boxen(formatErrorMessage(err.message, getErrorHint(err)), boxStyles.error));\n\n process.exit(1);\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError): string {\n if (error.name === 'GitHubError') {\n return 'Make sure you are in a GitHub repository and have authenticated with \"gh auth login\"';\n }\n\n if (error.name === 'GitError') {\n return 'Make sure you are in a git repository. Note: Only GitHub repositories are supported for PR scanning.';\n }\n\n if (error.name === 'TokenExpiredError' || error.name === 'AuthenticationError') {\n return 'Run \"bragduck init\" to login again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'ApiError') {\n return 'The server might be experiencing issues. Try again later';\n }\n\n return 'Try running with DEBUG=* for more information';\n}\n","import boxen from 'boxen';\nimport Table from 'cli-table3';\nimport { apiService } from '../services/api.service.js';\nimport { ensureAuthenticated } from '../utils/auth-helper.js';\nimport { logger } from '../utils/logger.js';\nimport { formatErrorMessage } from '../ui/formatters.js';\nimport { fetchingBragsSpinner, succeedSpinner, failSpinner } from '../ui/spinners.js';\nimport { theme, colors, boxStyles, tableStyles } from '../ui/theme.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport type { Brag } from '../types/api.types.js';\n\n/**\n * List command options\n */\nexport interface ListCommandOptions {\n limit?: number;\n offset?: number;\n tags?: string;\n search?: string;\n oneline?: boolean;\n}\n\n/**\n * List command: Fetch and display existing brags\n */\nexport async function listCommand(options: ListCommandOptions = {}): Promise<void> {\n logger.log('');\n\n try {\n // 1. Check authentication\n const isAuthenticated = await ensureAuthenticated();\n if (!isAuthenticated) {\n process.exit(1);\n }\n\n // 2. Parse options\n const limit = options.limit || 50;\n const offset = options.offset || 0;\n const tags = options.tags ? options.tags.split(',').map((t) => t.trim()) : undefined;\n const search = options.search;\n\n // 3. Fetch brags\n const spinner = fetchingBragsSpinner();\n spinner.start();\n\n const response = await apiService.listBrags({\n limit,\n offset,\n tags,\n search,\n });\n\n if (response.brags.length === 0) {\n failSpinner(spinner, 'No brags found');\n logger.log('');\n\n if (search || tags) {\n logger.info('Try adjusting your filters or run without filters to see all brags');\n } else {\n logger.info(\n theme.secondary('Run ') +\n theme.command('bragduck scan') +\n theme.secondary(' to create your first brag!')\n );\n }\n return;\n }\n\n succeedSpinner(spinner, `Found ${response.total} brag${response.total > 1 ? 's' : ''}`);\n logger.log('');\n\n // 4. Display brags\n if (options.oneline) {\n logger.log(formatBragsOneline(response.brags));\n } else {\n logger.log(formatBragsTable(response.brags));\n }\n logger.log('');\n\n // 5. Show pagination info\n if (response.has_more) {\n const nextOffset = offset + limit;\n logger.info(\n `Showing ${offset + 1}-${offset + response.brags.length} of ${response.total} total brags`\n );\n logger.info(\n theme.secondary('Run ') +\n theme.command(`bragduck list --offset ${nextOffset}`) +\n theme.secondary(' to see more')\n );\n logger.log('');\n } else if (offset > 0) {\n logger.info(\n `Showing ${offset + 1}-${offset + response.brags.length} of ${response.total} total brags`\n );\n logger.log('');\n }\n\n // 6. Show filter info if filters are applied\n if (search || tags) {\n const filterInfo: string[] = [];\n if (search) filterInfo.push(`search: \"${search}\"`);\n if (tags) filterInfo.push(`tags: ${tags.join(', ')}`);\n logger.info(theme.info(`Filters applied: ${filterInfo.join(', ')}`));\n logger.log('');\n }\n } catch (error) {\n const err = error as BragduckError;\n\n logger.log('');\n logger.log(boxen(formatErrorMessage(err.message, getErrorHint(err)), boxStyles.error));\n\n process.exit(1);\n }\n}\n\n/**\n * Format brags as a table\n */\nfunction formatBragsTable(brags: Brag[]): string {\n const table = new Table({\n head: [\n colors.primary('Date'),\n colors.primary('Title'),\n colors.primary('Description'),\n colors.primary('Tags'),\n colors.primary('Repository'),\n ],\n colWidths: [12, 30, 40, 20, 30],\n wordWrap: true,\n style: tableStyles.default.style,\n });\n\n brags.forEach((brag) => {\n const date = new Date(brag.date).toLocaleDateString();\n const title = brag.title;\n const description = truncateText(brag.description, 100);\n const tags = brag.tags.length > 0 ? brag.tags.join(', ') : colors.dim('none');\n const repository = brag.repository\n ? truncateText(extractRepoName(brag.repository), 25)\n : colors.dim('none');\n\n table.push([\n colors.highlight(date),\n colors.white(title),\n colors.dim(description),\n colors.primary(tags),\n colors.info(repository),\n ]);\n });\n\n return table.toString();\n}\n\n/**\n * Format brags as oneline output (date + title only)\n */\nfunction formatBragsOneline(brags: Brag[]): string {\n return brags\n .map((brag) => {\n const date = new Date(brag.date).toLocaleDateString();\n return `${colors.highlight(date)} ${colors.white(brag.title)}`;\n })\n .join('\\n');\n}\n\n/**\n * Truncate text with ellipsis\n */\nfunction truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n return text.substring(0, maxLength - 3) + '...';\n}\n\n/**\n * Extract repository name from URL\n */\nfunction extractRepoName(url: string): string {\n try {\n // Handle GitHub URLs like: https://github.com/user/repo.git\n const match = url.match(/([^/]+\\/[^/]+?)(\\.git)?$/);\n return match ? match[1]! : url;\n } catch {\n return url;\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError): string {\n if (error.name === 'TokenExpiredError' || error.name === 'AuthenticationError') {\n return 'Run \"bragduck init\" to login again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'ApiError') {\n return 'The server might be experiencing issues. Try again later';\n }\n\n return 'Try running with DEBUG=* for more information';\n}\n","import boxen from 'boxen';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from '../utils/logger.js';\nimport { CONFIG_KEYS, DEFAULT_CONFIG } from '../constants.js';\nimport { formatErrorMessage } from '../ui/formatters.js';\nimport { ValidationError } from '../utils/errors.js';\nimport type { BragduckConfig } from '../types/config.types.js';\nimport type { SourceType } from '../types/source.types.js';\n\n/**\n * Valid configuration keys\n */\nconst VALID_CONFIG_KEYS = Object.values(CONFIG_KEYS);\n\n/**\n * Config subcommands\n */\ntype ConfigSubcommand = 'list' | 'get' | 'set';\n\n/**\n * Config command: Manage CLI configuration\n */\nexport async function configCommand(\n subcommand?: ConfigSubcommand,\n key?: string,\n value?: string\n): Promise<void> {\n logger.log('');\n\n try {\n // If no subcommand provided, default to 'list'\n if (!subcommand) {\n subcommand = 'list';\n }\n\n switch (subcommand) {\n case 'list':\n await handleListConfig();\n break;\n\n case 'get':\n if (!key) {\n throw new ValidationError('Config key is required for \"get\" command');\n }\n await handleGetConfig(key);\n break;\n\n case 'set':\n if (!key || value === undefined) {\n throw new ValidationError('Config key and value are required for \"set\" command');\n }\n await handleSetConfig(key, value);\n break;\n\n default:\n throw new ValidationError(\n `Invalid subcommand: \"${subcommand}\". Valid subcommands: list, get, set`\n );\n }\n } catch (error) {\n const err = error as Error;\n logger.log('');\n logger.log(\n boxen(formatErrorMessage(err.message, getConfigHint(err)), {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'red',\n })\n );\n\n process.exit(1);\n }\n}\n\n/**\n * Handle 'list' subcommand - Display all configuration values\n */\nasync function handleListConfig(): Promise<void> {\n const config = {\n defaultCommitDays: storageService.getConfig('defaultCommitDays'),\n autoVersionCheck: storageService.getConfig('autoVersionCheck'),\n defaultSource: storageService.getConfig('defaultSource'),\n sourcePriority: storageService.getConfig('sourcePriority'),\n jiraInstance: storageService.getConfig('jiraInstance'),\n confluenceInstance: storageService.getConfig('confluenceInstance'),\n gitlabInstance: storageService.getConfig('gitlabInstance'),\n };\n\n const table = new Table({\n head: [chalk.cyan('Key'), chalk.cyan('Value'), chalk.cyan('Default')],\n colWidths: [25, 40, 40],\n wordWrap: true,\n style: {\n head: [],\n border: ['gray'],\n },\n });\n\n table.push([\n chalk.white('defaultCommitDays'),\n chalk.yellow(String(config.defaultCommitDays)),\n chalk.dim(String(DEFAULT_CONFIG.defaultCommitDays)),\n ]);\n\n table.push([\n chalk.white('autoVersionCheck'),\n chalk.yellow(String(config.autoVersionCheck)),\n chalk.dim(String(DEFAULT_CONFIG.autoVersionCheck)),\n ]);\n\n table.push([\n chalk.white('defaultSource'),\n chalk.yellow(config.defaultSource || 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('sourcePriority'),\n chalk.yellow(config.sourcePriority ? config.sourcePriority.join(', ') : 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('jiraInstance'),\n chalk.yellow(config.jiraInstance || 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('confluenceInstance'),\n chalk.yellow(config.confluenceInstance || 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('gitlabInstance'),\n chalk.yellow(config.gitlabInstance || 'not set'),\n chalk.dim('not set'),\n ]);\n\n logger.info('Current configuration:');\n logger.log('');\n logger.log(table.toString());\n logger.log('');\n logger.info(chalk.dim('To change a value: ') + chalk.cyan('bragduck config set <key> <value>'));\n logger.log('');\n}\n\n/**\n * Handle 'get' subcommand - Get a specific configuration value\n */\nasync function handleGetConfig(key: string): Promise<void> {\n validateConfigKey(key);\n\n const value = storageService.getConfig(key as keyof BragduckConfig);\n const defaultValue = DEFAULT_CONFIG[key as keyof typeof DEFAULT_CONFIG];\n\n logger.info(`Configuration for ${chalk.cyan(key)}:`);\n logger.log('');\n logger.log(` ${chalk.white('Current:')} ${chalk.yellow(String(value))}`);\n logger.log(` ${chalk.white('Default:')} ${chalk.dim(String(defaultValue))}`);\n logger.log('');\n\n if (value === defaultValue) {\n logger.info(chalk.dim('Using default value'));\n } else {\n logger.info(\n chalk.dim('Custom value set. Reset with: ') +\n chalk.cyan(`bragduck config set ${key} ${defaultValue}`)\n );\n }\n logger.log('');\n}\n\n/**\n * Handle 'set' subcommand - Set a configuration value\n */\nasync function handleSetConfig(key: string, value: string): Promise<void> {\n validateConfigKey(key);\n\n // Validate and convert value based on key type\n const typedValue = validateAndConvertValue(key, value);\n\n // Store the configuration\n storageService.setConfig(key as keyof BragduckConfig, typedValue);\n\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Configuration updated')}\\n\\n` +\n `${chalk.white(key)}: ${chalk.yellow(String(typedValue))}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n}\n\n/**\n * Validate configuration key\n */\nfunction validateConfigKey(key: string): void {\n if (!VALID_CONFIG_KEYS.includes(key as any)) {\n throw new ValidationError(\n `Invalid config key: \"${key}\"\\n\\nValid keys:\\n${VALID_CONFIG_KEYS.map((k) => ` - ${k}`).join('\\n')}`\n );\n }\n}\n\n/**\n * Validate and convert value based on key type\n */\nfunction validateAndConvertValue(\n key: string,\n value: string\n): number | boolean | string | SourceType[] {\n switch (key) {\n case CONFIG_KEYS.DEFAULT_COMMIT_DAYS: {\n // Convert to number and validate\n const days = parseInt(value, 10);\n if (isNaN(days) || days < 1 || days > 365) {\n throw new ValidationError(\n `Invalid value for defaultCommitDays: \"${value}\"\\n\\nMust be a number between 1 and 365`\n );\n }\n return days;\n }\n\n case CONFIG_KEYS.AUTO_VERSION_CHECK: {\n // Convert to boolean\n const lowerValue = value.toLowerCase();\n if (lowerValue === 'true' || lowerValue === '1' || lowerValue === 'yes') {\n return true;\n } else if (lowerValue === 'false' || lowerValue === '0' || lowerValue === 'no') {\n return false;\n }\n throw new ValidationError(\n `Invalid value for autoVersionCheck: \"${value}\"\\n\\nMust be one of: true, false, yes, no, 1, 0`\n );\n }\n\n case CONFIG_KEYS.DEFAULT_SOURCE: {\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n if (!validSources.includes(value as SourceType)) {\n throw new ValidationError(\n `Invalid source: \"${value}\"\\n\\nValid sources: ${validSources.join(', ')}`\n );\n }\n return value as SourceType;\n }\n\n case CONFIG_KEYS.SOURCE_PRIORITY: {\n const sources = value.split(',').map((s) => s.trim());\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n for (const source of sources) {\n if (!validSources.includes(source as SourceType)) {\n throw new ValidationError(\n `Invalid source in priority list: \"${source}\"\\n\\nValid sources: ${validSources.join(', ')}`\n );\n }\n }\n return sources as SourceType[];\n }\n\n case CONFIG_KEYS.JIRA_INSTANCE:\n case CONFIG_KEYS.CONFLUENCE_INSTANCE:\n case CONFIG_KEYS.GITLAB_INSTANCE: {\n // Basic hostname/URL validation\n if (!value.match(/^[a-zA-Z0-9.-]+(:[0-9]+)?(\\/.*)?$/)) {\n throw new ValidationError(\n `Invalid instance URL: \"${value}\"\\n\\nMust be a valid hostname (e.g., company.atlassian.net, gitlab.company.com)`\n );\n }\n return value;\n }\n\n default:\n // This should never happen due to validateConfigKey check\n throw new ValidationError(`Unknown config key: \"${key}\"`);\n }\n}\n\n/**\n * Get helpful hint for config errors\n */\nfunction getConfigHint(error: any): string {\n if (error.name === 'ValidationError') {\n return 'Run \"bragduck config list\" to see all available configuration keys';\n }\n\n return 'Run \"bragduck config --help\" for usage information';\n}\n"],"mappings":";;;;;;;;;;;;AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAF9B;AAAA;AAAA;AAAA;AAAA;;;ACCA,SAAS,cAAc;AACvB,SAAS,iBAAAA,sBAAqB;AAC9B,SAAS,SAAS,YAAY;AAH9B,IAMM,YACA,WAYO,UAeA,aAaA,gBAaA,cAWA,eA4BA,mBAWA,eAsBA,aAwCA;AA5Kb;AAAA;AAAA;AAAA;AAMA,IAAM,aAAaA,eAAc,YAAY,GAAG;AAChD,IAAM,YAAY,QAAQ,UAAU;AAKpC,WAAO,EAAE,MAAM,KAAK,WAAW,MAAM,MAAM,MAAM,GAAG,OAAO,OAAO,OAAO,KAAK,CAAQ;AAO/E,IAAM,WAAW;AAejB,IAAM,cAAc;AAAA,MACzB,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,iBAAiB;AAAA,IACnB;AAKO,IAAM,iBAAiB;AAAA,MAC5B,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,IAClB;AAKO,IAAM,eAAe;AAAA,MAC1B,WAAW;AAAA,MACX,eAAe;AAAA,MACf,YAAY;AAAA;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAKO,IAAM,gBAAgB;AAAA,MAC3B,MAAM;AAAA,QACJ,UAAU;AAAA,QACV,OAAO;AAAA,MACT;AAAA,MACA,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,MACA,eAAe;AAAA,QACb,MAAM;AAAA,MACR;AAAA,MACA,SAAS;AAAA;AAAA;AAAA;AAAA,MAIT,SAAS;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,IACF;AAKO,IAAM,oBAAoB;AAAA,MAC/B,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf;AAKO,IAAM,gBAAgB;AAAA,MAC3B,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,aAAa;AAAA,IACf;AAkBO,IAAM,cAAc;AAAA,MACzB,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,aAAa;AAAA,MACb,cAAc;AAAA,MACd,WAAW;AAAA,MACX,WAAW;AAAA,MACX,uBAAuB;AAAA,IACzB;AAgCO,IAAM,eAAe,CAAC,eAAe,yBAAyB,kBAAkB;AAAA;AAAA;;;ACtKvF,SAAS,eAAe,KAAiC;AACvD,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,SAAS,OAAO,EAAE;AACjC,SAAO,MAAM,MAAM,IAAI,SAAY;AACrC;AAMA,SAAS,gBAAgB,KAAkC;AACzD,QAAM,QAAQ,QAAQ,IAAI,GAAG,GAAG,YAAY;AAC5C,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,CAAC,QAAQ,OAAO,GAAG,EAAE,SAAS,KAAK,EAAG,QAAO;AACjD,MAAI,CAAC,SAAS,MAAM,GAAG,EAAE,SAAS,KAAK,EAAG,QAAO;AACjD,SAAO;AACT;AAKA,SAAS,cAAc,KAAuC;AAC5D,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,QAAQ,MACX,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAE7B,SAAO,MAAM,SAAS,IAAK,QAAyB;AACtD;AAKA,SAAS,eAAe,KAAqC;AAC3D,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,SAAO,aAAa,SAAS,KAAmB,IAAK,QAAuB;AAC9E;AAMO,SAAS,gBAAmC;AACjD,SAAO;AAAA;AAAA,IAEL,QAAQ,eAAe,iBAAiB;AAAA,IACxC,cAAc,QAAQ,IAAI;AAAA,IAC1B,oBAAoB,QAAQ,IAAI;AAAA,IAChC,gBAAgB,QAAQ,IAAI;AAAA;AAAA,IAG5B,mBAAmB,eAAe,8BAA8B;AAAA,IAChE,kBAAkB,gBAAgB,6BAA6B;AAAA,IAC/D,gBAAgB,cAAc,0BAA0B;AAAA;AAAA,IAGxD,WAAW,QAAQ,IAAI;AAAA,IACvB,iBAAiB,QAAQ,IAAI;AAAA,IAC7B,aAAa,QAAQ,IAAI;AAAA,EAC3B;AACF;AA3EA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAKa,eAgBA,qBAUA,UAUA,UAaA,cAoBA,iBAUA,YAUA,mBAWA,aAUA,gBAUA,aAUA,WAUA;AAjJb;AAAA;AAAA;AAAA;AAKO,IAAM,gBAAN,cAA4B,MAAM;AAAA,MAChC;AAAA,MACA;AAAA,MAEP,YAAY,SAAiB,MAAc,SAA+B;AACxE,cAAM,OAAO;AACb,aAAK,OAAO;AACZ,aAAK,OAAO;AACZ,aAAK,UAAU;AACf,cAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAChD;AAAA,IACF;AAKO,IAAM,sBAAN,cAAkC,cAAc;AAAA,MACrD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,cAAc,OAAO;AACpC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,WAAN,cAAuB,cAAc;AAAA,MAC1C,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,aAAa,OAAO;AACnC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,WAAN,cAAuB,cAAc;AAAA,MACnC;AAAA,MAEP,YAAY,SAAiB,YAAqB,SAA+B;AAC/E,cAAM,SAAS,aAAa,OAAO;AACnC,aAAK,OAAO;AACZ,aAAK,aAAa;AAAA,MACpB;AAAA,IACF;AAKO,IAAM,eAAN,cAA2B,cAAc;AAAA,MAC9C,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,iBAAiB,OAAO;AACvC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAeO,IAAM,kBAAN,cAA8B,cAAc;AAAA,MACjD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,oBAAoB,OAAO;AAC1C,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,aAAN,cAAyB,oBAAoB;AAAA,MAClD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,OAAO;AACtB,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,oBAAN,cAAgC,oBAAoB;AAAA,MACzD,YAAY,UAAU,oCAAoC;AACxD,cAAM,OAAO;AACb,aAAK,OAAO;AACZ,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,cAAN,cAA0B,cAAc;AAAA,MAC7C,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,gBAAgB,OAAO;AACtC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,iBAAN,cAA6B,cAAc;AAAA,MAChD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,mBAAmB,OAAO;AACzC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,cAAN,cAA0B,cAAc;AAAA,MAC7C,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,gBAAgB,OAAO;AACtC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,YAAN,cAAwB,cAAc;AAAA,MAC3C,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,cAAc,OAAO;AACpC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,kBAAN,cAA8B,cAAc;AAAA,MACjD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,oBAAoB,OAAO;AAC1C,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;ACtJA,SAAS,YAAY,UAAU;AAC/B,OAAOC,WAAU;AAcjB,eAAsB,oBAAmD;AACvE,QAAM,MAAM,QAAQ,IAAI;AAGxB,MAAI,YAAY,IAAI,GAAG,GAAG;AACxB,WAAO,YAAY,IAAI,GAAG,KAAK;AAAA,EACjC;AAGA,aAAW,YAAY,cAAc;AACnC,UAAM,aAAaA,MAAK,KAAK,KAAK,QAAQ;AAE1C,QAAI;AACF,YAAM,GAAG,OAAO,UAAU;AAC1B,YAAMC,UAAS,MAAM,sBAAsB,UAAU;AACrD,kBAAY,IAAI,KAAKA,OAAM;AAC3B,aAAOA;AAAA,IACT,QAAQ;AAEN;AAAA,IACF;AAAA,EACF;AAGA,cAAY,IAAI,KAAK,IAAI;AACzB,SAAO;AACT;AAKA,eAAsB,sBAAsB,YAA4C;AACtF,MAAI;AACF,UAAM,UAAU,MAAM,GAAG,SAAS,YAAY,OAAO;AACrD,UAAMA,UAAS,KAAK,MAAM,OAAO;AAGjC,0BAAsBA,OAAM;AAE5B,WAAOA;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,aAAa;AAChC,YAAM,IAAI,gBAAgB,gCAAgC,UAAU,IAAI;AAAA,QACtE,eAAe,MAAM;AAAA,MACvB,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AACF;AAKA,SAAS,sBAAsBA,SAAuB;AACpD,MAAI,OAAOA,YAAW,YAAYA,YAAW,MAAM;AACjD,UAAM,IAAI,gBAAgB,8BAA8B;AAAA,EAC1D;AAEA,QAAM,MAAMA;AAGZ,MAAI,IAAI,sBAAsB,QAAW;AACvC,QAAI,OAAO,IAAI,sBAAsB,UAAU;AAC7C,YAAM,IAAI,gBAAgB,oCAAoC;AAAA,IAChE;AACA,QAAI,IAAI,oBAAoB,KAAK,IAAI,oBAAoB,KAAK;AAC5D,YAAM,IAAI,gBAAgB,6CAA6C;AAAA,IACzE;AAAA,EACF;AAGA,MAAI,IAAI,qBAAqB,QAAW;AACtC,QAAI,OAAO,IAAI,qBAAqB,WAAW;AAC7C,YAAM,IAAI,gBAAgB,oCAAoC;AAAA,IAChE;AAAA,EACF;AAGA,MAAI,IAAI,kBAAkB,QAAW;AACnC,UAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,QAAI,CAAC,aAAa,SAAS,IAAI,aAA2B,GAAG;AAC3D,YAAM,IAAI;AAAA,QACR,0BAA0B,IAAI,aAAa,qBAAqB,aAAa,KAAK,IAAI,CAAC;AAAA,MACzF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,IAAI,mBAAmB,QAAW;AACpC,QAAI,CAAC,MAAM,QAAQ,IAAI,cAAc,GAAG;AACtC,YAAM,IAAI,gBAAgB,iCAAiC;AAAA,IAC7D;AACA,UAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,eAAW,UAAU,IAAI,gBAAgB;AACvC,UAAI,CAAC,aAAa,SAAS,MAAM,GAAG;AAClC,cAAM,IAAI;AAAA,UACR,qCAAqC,MAAM,qBAAqB,aAAa,KAAK,IAAI,CAAC;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,iBAAiB,CAAC,gBAAgB,sBAAsB,gBAAgB;AAC9E,aAAW,SAAS,gBAAgB;AAClC,QAAI,IAAI,KAAK,MAAM,QAAW;AAC5B,UAAI,OAAO,IAAI,KAAK,MAAM,UAAU;AAClC,cAAM,IAAI,gBAAgB,GAAG,KAAK,mBAAmB;AAAA,MACvD;AAEA,YAAM,QAAQ,IAAI,KAAK;AACvB,UAAI,CAAC,MAAM,MAAM,mCAAmC,GAAG;AACrD,cAAM,IAAI,gBAAgB,WAAW,KAAK,KAAK,KAAK,EAAE;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,CAAC,yBAAyB,qBAAqB;AACrE,aAAW,SAAS,eAAe;AACjC,QAAI,IAAI,KAAK,MAAM,UAAa,OAAO,IAAI,KAAK,MAAM,WAAW;AAC/D,YAAM,IAAI,gBAAgB,GAAG,KAAK,oBAAoB;AAAA,IACxD;AAAA,EACF;AACF;AA3IA,IAUI;AAVJ;AAAA;AAAA;AAAA;AAEA;AACA;AAOA,IAAI,cAAiD,oBAAI,IAAI;AAAA;AAAA;;;ACV7D,OAAO,UAAU;AACjB,SAAS,gBAAgB,kBAAkB,aAAa,kBAAkB;AAC1E,SAAS,YAAY,WAAW,cAAc,eAAe,kBAAkB;AAC/E,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AAJrB,IA0Ba,gBAyYA;AAnab;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AAmBO,IAAM,iBAAN,MAAqB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAER,cAAc;AAEZ,aAAK,SAAS,IAAI,KAAqB;AAAA,UACrC,aAAa;AAAA,UACb,UAAU;AAAA,QACZ,CAAC;AAGD,aAAK,iBAAiBA,MAAK,QAAQ,GAAG,cAAc,eAAe;AACnE,aAAK,sBAAsBA,MAAK,KAAK,gBAAgB,cAAc,gBAAgB;AAGnF,aAAK,iBAAiB;AACtB,aAAK,qBAAqB;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAKQ,uBAA6B;AACnC,YAAI,CAAC,WAAW,KAAK,cAAc,GAAG;AACpC,oBAAU,KAAK,gBAAgB,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAAA,QACjE;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,MAAc,KAA4B;AACxD,cAAM,KAAK,YAAY,kBAAkB,SAAS;AAClD,cAAM,SAAS,eAAe,kBAAkB,WAAW,KAAK,IAAI;AAAA,UAClE,eAAe,kBAAkB;AAAA,QACnC,CAAC;AAED,YAAI,YAAY,OAAO,OAAO,MAAM,QAAQ,KAAK;AACjD,qBAAa,OAAO,MAAM,KAAK;AAE/B,cAAM,UAAU,OAAO,WAAW;AAElC,eAAO;AAAA,UACL;AAAA,UACA,IAAI,GAAG,SAAS,KAAK;AAAA,UACrB,SAAS,QAAQ,SAAS,KAAK;AAAA,UAC/B,MAAM;AAAA;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,eAA8B,KAAqB;AACjE,cAAM,WAAW;AAAA,UACf,kBAAkB;AAAA,UAClB;AAAA,UACA,OAAO,KAAK,cAAc,IAAI,KAAK;AAAA,UACnC;AAAA,YACE,eAAe,kBAAkB;AAAA,UACnC;AAAA,QACF;AAEA,iBAAS,WAAW,OAAO,KAAK,cAAc,SAAS,KAAK,CAAC;AAE7D,YAAI,YAAY,SAAS,OAAO,cAAc,WAAW,OAAO,MAAM;AACtE,qBAAa,SAAS,MAAM,MAAM;AAElC,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKQ,oBAAoB,MAAsB;AAEhD,cAAM,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAAC,IAAI,QAAQ,QAAQ;AAC7D,eAAO,WAAW,UAAU,MAAM,kBAAkB,UAAU;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAAe,aAA+C;AAClE,cAAM,OAAO,KAAK,UAAU,WAAW;AAGvC,cAAM,OAAO,YAAY,kBAAkB,WAAW;AACtD,cAAM,MAAM,KAAK,oBAAoB,IAAI;AACzC,cAAM,YAAY,KAAK,QAAQ,MAAM,GAAG;AACxC,kBAAU,OAAO,KAAK,SAAS,KAAK;AAEpC,sBAAc,KAAK,qBAAqB,KAAK,UAAU,SAAS,GAAG;AAAA,UACjE,MAAM;AAAA,UACN,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAoD;AACxD,YAAI,CAAC,WAAW,KAAK,mBAAmB,GAAG;AACzC,iBAAO;AAAA,QACT;AAEA,YAAI;AACF,gBAAM,gBAA+B,KAAK;AAAA,YACxC,aAAa,KAAK,qBAAqB,MAAM;AAAA,UAC/C;AACA,gBAAM,OAAO,OAAO,KAAK,cAAc,MAAM,KAAK;AAClD,gBAAM,MAAM,KAAK,oBAAoB,IAAI;AACzC,gBAAM,YAAY,KAAK,QAAQ,eAAe,GAAG;AACjD,iBAAO,KAAK,MAAM,SAAS;AAAA,QAC7B,SAAS,OAAO;AACd,kBAAQ,MAAM,kCAAkC,KAAK;AACrD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,oBAAmC;AAEvC,YAAI,WAAW,KAAK,mBAAmB,GAAG;AACxC,cAAI;AACF,uBAAW,KAAK,mBAAmB;AAAA,UACrC,SAAS,OAAO;AACd,oBAAQ,MAAM,sCAAsC,KAAK;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAAoC;AAExC,eAAO,KAAK,uBAAuB,UAAU;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,SAA0D;AACpF,cAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,YAAI,CAAC,YAAa,QAAO;AAGzB,YAAI,YAAY,cAAc,YAAY,eAAe,CAAC,YAAY,UAAU;AAC9E,iBAAO;AAAA,YACL,aAAa,YAAY;AAAA,YACzB,cAAc,YAAY;AAAA,YAC1B,WAAW,YAAY;AAAA,UACzB;AAAA,QACF;AAEA,eAAO,YAAY,WAAW,OAAO,KAAK;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,SAAsB,OAA0C;AAC1F,YAAI,WAAW,MAAM,KAAK,eAAe;AAGzC,YAAI,YAAY,SAAS,eAAe,CAAC,SAAS,UAAU;AAC1D,qBAAW;AAAA,YACT,UAAU;AAAA,cACR,UAAU;AAAA,gBACR,aAAa,SAAS;AAAA,gBACtB,cAAc,SAAS;AAAA,gBACvB,WAAW,SAAS;AAAA,cACtB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,UAA6B;AAAA,UACjC,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,UAAU;AAAA,YACb,CAAC,OAAO,GAAG;AAAA,UACb;AAAA,QACF;AAEA,cAAM,KAAK,eAAe,OAAO;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,yBAAyB,SAAqC;AAClE,cAAM,WAAW,MAAM,KAAK,eAAe;AAC3C,YAAI,CAAC,UAAU,WAAW,OAAO,EAAG;AAEpC,eAAO,SAAS,SAAS,OAAO;AAChC,cAAM,KAAK,eAAe,QAAQ;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,uBAAuB,SAAwC;AACnE,cAAM,QAAQ,MAAM,KAAK,sBAAsB,OAAO;AACtD,YAAI,CAAC,OAAO,YAAa,QAAO;AAGhC,YAAI,MAAM,aAAa,MAAM,YAAY,KAAK,IAAI,EAAG,QAAO;AAE5D,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,2BAAmD;AACvD,cAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,YAAI,CAAC,YAAa,QAAO,CAAC;AAG1B,YAAI,YAAY,eAAe,CAAC,YAAY,UAAU;AACpD,iBAAO,CAAC,UAAU;AAAA,QACpB;AAEA,YAAI,CAAC,YAAY,SAAU,QAAO,CAAC;AAEnC,cAAM,WAA0B,CAAC;AACjC,mBAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,YAAY,QAAQ,GAAG;AACnE,cAAI,OAAO,aAAa;AACtB,qBAAS,KAAK,OAAsB;AAAA,UACtC;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,UAA0B;AACpC,aAAK,OAAO,IAAI,YAAoC,QAAe;AAAA,MACrE;AAAA;AAAA;AAAA;AAAA,MAKA,cAA+B;AAC7B,eAAQ,KAAK,OAAO,IAAI,UAAkC,KAAa;AAAA,MACzE;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAuB;AACrB,aAAK,OAAO,OAAO,UAAkC;AAAA,MACvD;AAAA;AAAA;AAAA;AAAA,MAKA,cAAc,OAAyB;AACrC,aAAK,OAAO,IAAI,cAAsC,KAAY;AAAA,MACpE;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAmC;AACjC,eAAQ,KAAK,OAAO,IAAI,YAAoC,KAAa;AAAA,MAC3E;AAAA;AAAA;AAAA;AAAA,MAKA,mBAAyB;AACvB,aAAK,OAAO,OAAO,YAAoC;AAAA,MACzD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,uBAAuD,KAAoC;AAE/F,cAAM,YAAY,cAAc;AAChC,cAAM,SAAS,QAAQ,kBAAkB,WAAW;AACpD,YAAI,UAAU,MAAgC,MAAM,QAAW;AAC7D,iBAAO,UAAU,MAAgC;AAAA,QACnD;AAGA,cAAM,gBAAgB,MAAM,kBAAkB;AAC9C,YAAI,iBAAiB,cAAc,GAAG,MAAM,QAAW;AACrD,iBAAO,cAAc,GAAG;AAAA,QAC1B;AAGA,cAAM,YAAY,KAAK,OAAO,IAAI,GAAG;AACrC,YAAI,cAAc,QAAW;AAC3B,iBAAO;AAAA,QACT;AAGA,eAAO,eAAe,GAAG;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,UAA0C,KAA2B;AACnE,eAAO,KAAK,OAAO,IAAI,GAAG;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAKA,UAA0C,KAAQ,OAAgC;AAChF,aAAK,OAAO,IAAI,KAAK,KAAK;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,4BAAqD;AACzD,cAAM,YAAY,cAAc;AAChC,cAAM,gBAAgB,MAAM,kBAAkB;AAC9C,cAAM,aAAa,KAAK,OAAO;AAG/B,eAAO;AAAA,UACL,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAI,UAAU,UAAU,EAAE,eAAe,UAAU,OAAO;AAAA,UAC1D,GAAI,UAAU,gBAAgB,EAAE,cAAc,UAAU,aAAa;AAAA,UACrE,GAAI,UAAU,sBAAsB,EAAE,oBAAoB,UAAU,mBAAmB;AAAA,UACvF,GAAI,UAAU,kBAAkB,EAAE,gBAAgB,UAAU,eAAe;AAAA,UAC3E,GAAI,UAAU,sBAAsB,UAAa;AAAA,YAC/C,mBAAmB,UAAU;AAAA,UAC/B;AAAA,UACA,GAAI,UAAU,qBAAqB,UAAa;AAAA,YAC9C,kBAAkB,UAAU;AAAA,UAC9B;AAAA,UACA,GAAI,UAAU,kBAAkB,EAAE,gBAAgB,UAAU,eAAe;AAAA,QAC7E;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,eAA+B;AAC7B,eAAO,KAAK,OAAO;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,cAAoB;AAClB,aAAK,OAAO,MAAM;AAElB,eAAO,QAAQ,cAAc,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACvD,cAAI,UAAU,QAAW;AACvB,iBAAK,OAAO,IAAI,KAA6B,KAAY;AAAA,UAC3D;AAAA,QACF,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,oBAAoC;AAClC,eAAO,KAAK;AAAA,MACd;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,WAA0B;AAC9B,cAAM,KAAK,kBAAkB;AAC7B,aAAK,eAAe;AACpB,aAAK,iBAAiB;AACtB,aAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAGO,IAAM,iBAAiB,IAAI,eAAe;AAAA;AAAA;;;ACnajD,OAAO,WAAW;AAAlB,IAKa;AALb;AAAA;AAAA;AAAA;AAKO,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA,MAIpB,OAAO,CAAC,YAAoB,SAAsB;AAChD,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,IAAI,MAAM,KAAK,WAAW,OAAO,EAAE,GAAG,GAAG,IAAI;AAAA,QACvD;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,CAAC,YAA0B;AAC/B,gBAAQ,IAAI,MAAM,KAAK,UAAK,OAAO,EAAE,CAAC;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,SAAS,CAAC,YAA0B;AAClC,gBAAQ,IAAI,MAAM,MAAM,UAAK,OAAO,EAAE,CAAC;AAAA,MACzC;AAAA;AAAA;AAAA;AAAA,MAKA,SAAS,CAAC,YAA0B;AAClC,gBAAQ,KAAK,MAAM,OAAO,UAAK,OAAO,EAAE,CAAC;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,CAAC,YAA0B;AAChC,gBAAQ,MAAM,MAAM,IAAI,UAAK,OAAO,EAAE,CAAC;AAAA,MACzC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,CAAC,YAA0B;AAC9B,gBAAQ,IAAI,OAAO;AAAA,MACrB;AAAA,IACF;AAAA;AAAA;;;ACjDA,SAAS,oBAA4E;AACrF,SAAS,aAAa;AAiBtB,eAAe,oBAAqC;AAClD,QAAM,EAAE,UAAU,SAAS,IAAI;AAE/B,WAAS,OAAO,UAAU,QAAQ,UAAU,QAAQ;AAClD,QAAI;AACF,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,cAAM,aAAa,aAAa;AAChC,mBAAW,KAAK,SAAS,MAAM;AAC/B,mBAAW,KAAK,aAAa,MAAM;AACjC,qBAAW,MAAM,MAAM,QAAQ,CAAC;AAAA,QAClC,CAAC;AACD,mBAAW,OAAO,MAAM,WAAW;AAAA,MACrC,CAAC;AACD,aAAO;AAAA,IACT,QAAQ;AAEN;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,WAAW,qCAAqC,QAAQ,IAAI,QAAQ,EAAE;AAClF;AA+HA,eAAsB,yBACpB,eAC8B;AAC9B,QAAM,OAAO,MAAM,kBAAkB;AACrC,QAAM,UAAU,aAAa;AAE7B,SAAO,IAAI,QAA6B,CAAC,SAAS,WAAW;AAC3D,QAAI,SAAwB;AAC5B,QAAI,YAA6D;AAEjE,UAAM,UAAU,MAAM;AACpB,UAAI,WAAW;AACb,mBAAW,aAAa,SAAS;AAAA,MACnC;AACA,UAAI,QAAQ;AAEV,YAAI,OAAQ,OAAe,wBAAwB,YAAY;AAC7D,UAAC,OAAe,oBAAoB;AAAA,QACtC;AACA,eAAO,MAAM,MAAM;AACjB,iBAAO,MAAM,qBAAqB;AAAA,QACpC,CAAC;AACD,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,KAAsB,QAAwB;AACnE,YAAM,YAAY,MAAM,IAAI,OAAO,IAAI,IAAI;AAE3C,aAAO,MAAM,4BAA4B,IAAI,GAAG,EAAE;AAGlD,UAAI,UAAU,aAAa,aAAa,eAAe;AACrD,cAAM,EAAE,MAAM,OAAO,OAAO,kBAAkB,IAAI,UAAU;AAG5D,YAAI,OAAO;AACT,gBAAM,WAAW,qBAAqB;AACtC,iBAAO,MAAM,gBAAgB,QAAQ,EAAE;AAEvC,cAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,cAAI,IAAI,WAAW,OAAO,QAAQ,CAAC,CAAC;AAEpC,kBAAQ;AACR,iBAAO,IAAI,WAAW,gBAAgB,QAAQ,EAAE,CAAC;AACjD;AAAA,QACF;AAGA,YAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,gBAAM,WAAW;AACjB,iBAAO,MAAM,QAAQ;AAErB,cAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,cAAI,IAAI,WAAW,QAAQ,CAAC;AAE5B,kBAAQ;AACR,iBAAO,IAAI,WAAW,QAAQ,CAAC;AAC/B;AAAA,QACF;AAGA,YAAI,UAAU,eAAe;AAC3B,gBAAM,WAAW;AACjB,iBAAO,MAAM,QAAQ;AAErB,cAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,cAAI,IAAI,WAAW,QAAQ,CAAC;AAE5B,kBAAQ;AACR,iBAAO,IAAI,WAAW,QAAQ,CAAC;AAC/B;AAAA,QACF;AAGA,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI,IAAI,YAAY;AAGpB,mBAAW,WAAW,MAAM;AAC1B,kBAAQ;AACR,kBAAQ;AAAA,YACN,MAAM,OAAO,IAAI;AAAA,YACjB,OAAO,OAAO,KAAK;AAAA,YACnB;AAAA,UACF,CAAC;AAAA,QACH,GAAG,GAAG;AACN;AAAA,MACF;AAGA,UAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,UAAI,IAAI,WAAW;AAAA,IACrB;AAGA,aAAS,aAAa,aAAa;AAGnC,WAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,aAAO,MAAM,uBAAuB,MAAM,OAAO,EAAE;AACnD,cAAQ;AACR,aAAO,IAAI,WAAW,uBAAuB,MAAM,OAAO,EAAE,CAAC;AAAA,IAC/D,CAAC;AAGD,WAAO,OAAO,MAAM,aAAa,MAAM;AACrC,aAAO;AAAA,QACL,uDAAuD,IAAI,GAAG,aAAa,aAAa;AAAA,MAC1F;AAAA,IACF,CAAC;AAGD,gBAAY,WAAW,WAAW,MAAM;AACtC,aAAO,MAAM,wBAAwB;AACrC,cAAQ;AACR,aAAO,IAAI,WAAW,gEAAgE,CAAC;AAAA,IACzF,GAAG,OAAO;AAAA,EACZ,CAAC;AACH;AAKA,eAAsB,iBAAkC;AACtD,QAAM,OAAO,MAAM,kBAAkB;AACrC,SAAO,oBAAoB,IAAI,GAAG,aAAa,aAAa;AAC9D;AArSA,IA4CM,cA2DA;AAvGN;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAwCA,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2DrB,IAAM,aAAa,CAAC,UAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAsDL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC7JtC,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAQ1B,eAAsB,YAAY,KAA4B;AAC5D,QAAM,WAAW,QAAQ;AACzB,MAAI;AAGJ,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,gBAAU,SAAS,GAAG;AACtB;AAAA,IACF,KAAK;AACH,gBAAU,aAAa,GAAG;AAC1B;AAAA,IACF;AACE,gBAAU,aAAa,GAAG;AAC1B;AAAA,EACJ;AAEA,MAAI;AACF,WAAO,MAAM,iCAAiC,OAAO,EAAE;AACvD,UAAM,UAAU,OAAO;AACvB,WAAO,MAAM,6BAA6B;AAAA,EAC5C,SAAS,OAAO;AACd,WAAO,MAAM,2BAA2B,KAAK,EAAE;AAC/C,UAAM,IAAI,MAAM;AAAA,EAAyE,GAAG,EAAE;AAAA,EAChG;AACF;AAlCA,IAIM;AAJN;AAAA;AAAA;AAAA;AAEA;AAEA,IAAM,YAAY,UAAU,IAAI;AAAA;AAAA;;;ACJhC,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,iBAAAC,gBAAe,uBAAuB;AAC/C,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,cAAc;AAevB,SAAS,eAAuB;AAC9B,MAAI;AAEF,UAAMC,mBAAkBD,MAAKE,YAAW,oBAAoB;AAC5D,UAAMC,eAAc,KAAK,MAAMN,cAAaI,kBAAiB,OAAO,CAAC;AACrE,UAAMG,WAAUD,aAAY;AAC5B,UAAM,WAAW,QAAQ;AACzB,UAAM,OAAO,QAAQ;AACrB,WAAO,gBAAgBC,QAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,EACrD,QAAQ;AACN,WAAO,MAAM,qCAAqC;AAClD,WAAO;AAAA,EACT;AACF;AAhCA,IAaMC,aACAH,YAkCO,aA2OA;AA3Rb;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AAGA,IAAMG,cAAaP,eAAc,YAAY,GAAG;AAChD,IAAMI,aAAYH,SAAQM,WAAU;AAkC7B,IAAM,cAAN,MAAkB;AAAA,MACf;AAAA,MAER,cAAc;AAEZ,aAAK,aAAa,QAAQ,IAAI,gBAAgB;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA,MAKQ,gBAAwB;AAC9B,eAAOT,aAAY,EAAE,EAAE,SAAS,KAAK;AAAA,MACvC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,aAAa,OAAe,aAAsC;AAC9E,cAAM,SAAS,IAAI,gBAAgB;AAAA,UACjC,WAAW,aAAa;AAAA,UACxB,cAAc;AAAA,UACd;AAAA,QACF,CAAC;AAED,eAAO,GAAG,KAAK,UAAU,GAAG,cAAc,KAAK,QAAQ,IAAI,OAAO,SAAS,CAAC;AAAA,MAC9E;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,qBAAqB,MAAc,aAA6C;AAC5F,YAAI;AACF,iBAAO,MAAM,yCAAyC;AAEtD,gBAAM,WAAW,MAAM;AAAA,YACrB,GAAG,KAAK,UAAU,GAAG,cAAc,KAAK,KAAK;AAAA,YAC7C;AAAA,cACE,QAAQ;AAAA,cACR,MAAM;AAAA,gBACJ;AAAA,gBACA,cAAc;AAAA,gBACd,WAAW,aAAa;AAAA,gBACxB,YAAY;AAAA,cACd;AAAA,cACA,SAAS;AAAA,gBACP,gBAAgB;AAAA,gBAChB,cAAc,aAAa;AAAA,cAC7B;AAAA,YACF;AAAA,UACF;AAEA,iBAAO,MAAM,2BAA2B;AACxC,iBAAO;AAAA,QACT,SAAS,OAAY;AACnB,iBAAO,MAAM,0BAA0B,MAAM,OAAO,EAAE;AAEtD,cAAI,MAAM,UAAU;AAClB,kBAAM,IAAI;AAAA,cACR,0BAA0B,MAAM,SAAS,cAAc,eAAe;AAAA,cACtE;AAAA,gBACE,YAAY,MAAM,SAAS;AAAA,gBAC3B,MAAM,MAAM,SAAS;AAAA,cACvB;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,IAAI,aAAa,8CAA8C;AAAA,YACnE,eAAe,MAAM;AAAA,UACvB,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAA2B;AAC/B,eAAO,MAAM,2BAA2B;AAGxC,cAAM,QAAQ,KAAK,cAAc;AACjC,cAAM,cAAc,MAAM,eAAe;AAGzC,uBAAe,cAAc;AAAA,UAC3B;AAAA,UACA,WAAW,KAAK,IAAI;AAAA,QACtB,CAAC;AAED,eAAO,MAAM,gBAAgB,KAAK,EAAE;AACpC,eAAO,MAAM,iBAAiB,WAAW,EAAE;AAG3C,cAAM,UAAU,MAAM,KAAK,aAAa,OAAO,WAAW;AAC1D,eAAO,MAAM,sBAAsB,OAAO,EAAE;AAG5C,cAAM,gBAAgB,yBAAyB,KAAK;AAGpD,YAAI;AACF,gBAAM,YAAY,OAAO;AAAA,QAC3B,QAAQ;AAEN,iBAAO,QAAQ,sCAAsC;AACrD,iBAAO,KAAK,uCAAuC;AACnD,iBAAO,IAAI,OAAO;AAAA,QACpB;AAGA,YAAI;AACJ,YAAI;AACF,2BAAiB,MAAM;AAAA,QACzB,SAAS,OAAY;AACnB,yBAAe,iBAAiB;AAChC,gBAAM;AAAA,QACR;AAGA,uBAAe,iBAAiB;AAGhC,cAAM,gBAAgB,MAAM,KAAK,qBAAqB,eAAe,MAAM,WAAW;AAGtF,cAAM,YAAY,cAAc,aAC5B,KAAK,IAAI,IAAI,cAAc,aAAa,MACxC;AAGJ,cAAM,cAAkC;AAAA,UACtC,aAAa,cAAc;AAAA,UAC3B,cAAc,cAAc;AAAA,UAC5B;AAAA,QACF;AACA,cAAM,eAAe,sBAAsB,YAAY,WAAW;AAGlE,YAAI,cAAc,MAAM;AACtB,yBAAe,YAAY,cAAc,IAAI;AAAA,QAC/C;AAEA,eAAO,MAAM,kBAAkB;AAE/B,eAAO,cAAc,QAAQ,EAAE,IAAI,WAAW,OAAO,WAAW,MAAM,eAAe;AAAA,MACvF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAAwB;AAC5B,eAAO,MAAM,aAAa;AAE1B,cAAM,eAAe,kBAAkB;AACvC,uBAAe,eAAe;AAC9B,uBAAe,iBAAiB;AAEhC,eAAO,MAAM,iBAAiB;AAAA,MAChC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAAoC;AACxC,eAAO,eAAe,gBAAgB;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAyC;AAC7C,cAAM,cAAc,MAAM,eAAe,sBAAsB,UAAU;AACzE,eAAO,aAAa,eAAe;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKA,cAA+B;AAC7B,eAAO,eAAe,YAAY;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAA8B;AAClC,eAAO,MAAM,yBAAyB;AAEtC,cAAM,cAAc,MAAM,eAAe,sBAAsB,UAAU;AACzE,YAAI,CAAC,aAAa,cAAc;AAC9B,gBAAM,IAAI,oBAAoB,4BAA4B;AAAA,QAC5D;AAEA,YAAI;AACF,gBAAM,WAAW,MAAM;AAAA,YACrB,GAAG,KAAK,UAAU,GAAG,cAAc,KAAK,KAAK;AAAA,YAC7C;AAAA,cACE,QAAQ;AAAA,cACR,MAAM;AAAA,gBACJ,eAAe,YAAY;AAAA,gBAC3B,WAAW,aAAa;AAAA,gBACxB,YAAY;AAAA,cACd;AAAA,cACA,SAAS;AAAA,gBACP,gBAAgB;AAAA,gBAChB,cAAc,aAAa;AAAA,cAC7B;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,YAAY,SAAS,aAAa,KAAK,IAAI,IAAI,SAAS,aAAa,MAAO;AAGlF,gBAAM,iBAAqC;AAAA,YACzC,aAAa,SAAS;AAAA,YACtB,cAAc,SAAS,iBAAiB,YAAY;AAAA,YACpD;AAAA,UACF;AACA,gBAAM,eAAe,sBAAsB,YAAY,cAAc;AAErE,iBAAO,MAAM,0BAA0B;AAAA,QACzC,SAAS,OAAY;AACnB,iBAAO,MAAM,yBAAyB,MAAM,OAAO,EAAE;AAGrD,gBAAM,KAAK,OAAO;AAClB,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGO,IAAM,cAAc,IAAI,YAAY;AAAA;AAAA;;;AC3R3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,gBAAAU,qBAAoB;AAC7B,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,OAAOC,YAAW;AAClB,OAAOC,YAAW;AAWX,SAAS,oBAA4B;AAC1C,MAAI;AAEF,UAAMC,mBAAkBH,MAAKI,YAAW,oBAAoB;AAC5D,UAAMC,eAAc,KAAK,MAAMR,cAAaM,kBAAiB,OAAO,CAAC;AACrE,WAAOE,aAAY;AAAA,EACrB,QAAQ;AACN,WAAO,MAAM,qCAAqC;AAClD,WAAO;AAAA,EACT;AACF;AAcO,SAAS,gBAAgB,IAAY,IAAoB;AAC9D,QAAM,SAAS,GAAG,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AACvD,QAAM,SAAS,GAAG,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAEvD,WAAS,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM,GAAG,KAAK;AAC/D,UAAM,QAAQ,OAAO,CAAC,KAAK;AAC3B,UAAM,QAAQ,OAAO,CAAC,KAAK;AAE3B,QAAI,QAAQ,MAAO,QAAO;AAC1B,QAAI,QAAQ,MAAO,QAAO;AAAA,EAC5B;AAEA,SAAO;AACT;AAKA,eAAsB,gBACpB,UAGI,CAAC,GACiF;AACtF,QAAM,EAAE,SAAS,OAAO,QAAQ,MAAM,IAAI;AAE1C,MAAI;AAEF,QAAI,CAAC,OAAO;AACV,YAAM,mBAAmB,eAAe,UAAU,kBAAkB;AACpE,UAAI,CAAC,kBAAkB;AACrB,eAAO,MAAM,kCAAkC;AAC/C,eAAO;AAAA,UACL,iBAAiB;AAAA,UACjB,eAAe;AAAA,UACf,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM,6BAA6B;AAG1C,UAAM,WAAW,MAAM,WAAW,aAAa;AAC/C,UAAM,gBAAgB,SAAS;AAC/B,UAAM,iBAAiB;AAEvB,WAAO,MAAM,oBAAoB,cAAc,qBAAqB,aAAa,EAAE;AAEnF,UAAM,kBAAkB,gBAAgB,eAAe,cAAc,IAAI;AAGzE,QAAI,CAAC,UAAU,iBAAiB;AAC9B,gCAA0B,gBAAgB,eAAe,SAAS,eAAe;AAAA,IACnF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,OAAY;AACnB,WAAO,MAAM,yBAAyB,MAAM,OAAO,EAAE;AAErD,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,gBAAgB;AAAA,IAClB;AAAA,EACF;AACF;AAKA,SAAS,0BACP,gBACA,eACA,WAAoB,OACd;AACN,QAAM,UAAU,WACZJ,OAAM,IAAI,KAAK,iBAAiB,IAChCA,OAAM,OAAO,KAAK,kBAAkB;AACxC,QAAM,UACJ,GAAG,OAAO;AAAA;AAAA,mBACUA,OAAM,IAAI,cAAc,CAAC;AAAA,mBACzBA,OAAM,MAAM,aAAa,CAAC;AAAA;AAAA,eAC9BA,OAAM,KAAK,qCAAqC,CAAC;AAEnE,UAAQ,IAAI,EAAE;AACd,UAAQ;AAAA,IACNC,OAAM,SAAS;AAAA,MACb,SAAS;AAAA,MACT,QAAQ,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE;AAAA,MAC/C,aAAa;AAAA,MACb,aAAa,WAAW,QAAQ;AAAA,IAClC,CAAC;AAAA,EACH;AACA,UAAQ,IAAI,EAAE;AAEd,MAAI,UAAU;AACZ,WAAO,QAAQ,+DAA+D;AAC9E,YAAQ,IAAI,EAAE;AAAA,EAChB;AACF;AAKO,SAAS,cAAc,gBAAyB,MAAc;AACnE,QAAM,SAAS,gBAAgB,MAAM;AACrC,SAAO,GAAG,MAAM,GAAG,OAAO;AAC5B;AAvJA,IASMI,aACAF,YAoBO;AA9Bb;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AAEA,IAAME,cAAaR,eAAc,YAAY,GAAG;AAChD,IAAMM,aAAYL,SAAQO,WAAU;AAoB7B,IAAM,UAAU,kBAAkB;AAAA;AAAA;;;AC9BzC,SAAS,UAAAC,eAAiC;AAC1C,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,WAAAC,UAAS,QAAAC,aAAY;AA0B9B,SAAS,gBAAwB;AAC/B,MAAI;AAEF,UAAMC,mBAAkBD,MAAKE,YAAW,oBAAoB;AAC5D,UAAMC,eAAc,KAAK,MAAMP,cAAaK,kBAAiB,OAAO,CAAC;AACrE,WAAOE,aAAY;AAAA,EACrB,QAAQ;AACN,WAAO,MAAM,qCAAqC;AAClD,WAAO;AAAA,EACT;AACF;AAKA,SAAS,kBAA0B;AACjC,QAAM,WAAW,QAAQ;AACzB,QAAM,OAAO,QAAQ;AACrB,SAAO,GAAG,QAAQ,IAAI,IAAI;AAC5B;AAjDA,IAwBMC,aACAF,YA6BO,YA0WA;AAhab;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AACA;AAgBA,IAAME,cAAaP,eAAc,YAAY,GAAG;AAChD,IAAMK,aAAYH,SAAQK,WAAU;AA6B7B,IAAM,aAAN,MAAiB;AAAA,MACd;AAAA,MACA;AAAA,MAER,cAAc;AAEZ,aAAK,UAAU,QAAQ,IAAI,gBAAgB;AAG3C,aAAK,SAAST,QAAO,OAAO;AAAA,UAC1B,SAAS,KAAK;AAAA;AAAA,UAGd,WAAW,OAAO,EAAE,SAAS,QAAQ,MAAM;AACzC,mBAAO,MAAM,gBAAgB,QAAQ,UAAU,KAAK,IAAI,OAAO,EAAE;AAGjE,kBAAM,aAAa,cAAc;AACjC,kBAAM,WAAW,gBAAgB;AACjC,kBAAM,YAAY,gBAAgB,UAAU,KAAK,QAAQ;AAGzD,kBAAM,QAAQ,MAAM,YAAY,eAAe;AAG/C,kBAAM,aAAqC;AAAA,cACzC,cAAc;AAAA,YAChB;AAGA,gBAAI,QAAQ,SAAS;AACnB,kBAAI,OAAO,QAAQ,YAAY,YAAY,CAAC,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAC1E,uBAAO,QAAQ,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACxD,sBAAI,OAAO,UAAU,UAAU;AAC7B,+BAAW,GAAG,IAAI;AAAA,kBACpB;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAEA,gBAAI,OAAO;AACT,yBAAW,gBAAgB,UAAU,KAAK;AAAA,YAC5C;AAGA,gBAAI,QAAQ,UAAU,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,QAAQ,MAAM,GAAG;AACvE,yBAAW,cAAc,IAAI;AAAA,YAC/B;AAEA,oBAAQ,UAAU;AAAA,UACpB;AAAA;AAAA,UAGA,YAAY,CAAC,EAAE,SAAS,MAAM;AAC5B,mBAAO,MAAM,iBAAiB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,UACxE;AAAA;AAAA,UAGA,iBAAiB,OAAO,EAAE,SAAS,SAAS,MAAM;AAChD,kBAAM,SAAS,SAAS;AAExB,mBAAO,MAAM,cAAc,MAAM,IAAI,SAAS,UAAU,MAAM,OAAO,EAAE;AAGvE,gBAAI,WAAW,YAAY,cAAc;AACvC,qBAAO,MAAM,mCAAmC;AAEhD,kBAAI;AAEF,sBAAM,YAAY,aAAa;AAG/B,uBAAO,MAAM,mCAAmC;AAChD,sBAAM,IAAI,MAAM,sBAAsB;AAAA,cACxC,SAAS,OAAY;AACnB,oBAAI,MAAM,YAAY,wBAAwB;AAC5C,wBAAM;AAAA,gBACR;AAEA,sBAAM,IAAI;AAAA,kBACR;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,eAAe;AACnB,gBAAI;AAEJ,gBAAI;AACF,oBAAM,YAAY,SAAS;AAC3B,kBAAI,aAAa,UAAU,SAAS;AAClC,+BAAe,UAAU;AACzB,+BAAe,UAAU;AAAA,cAC3B;AAAA,YACF,QAAQ;AAEN,6BAAe,SAAS,cAAc;AAAA,YACxC;AAEA,kBAAM,IAAI,SAAS,cAAc,QAAQ,YAAY;AAAA,UACvD;AAAA;AAAA,UAGA,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,kBAAkB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA;AAAA,UAGzD,SAAS;AAAA;AAAA,QACX,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,YAAe,KAAa,UAAwB,CAAC,GAAe;AAChF,YAAI;AACF,iBAAQ,MAAM,KAAK,OAAO,KAAK,OAAO;AAAA,QACxC,SAAS,OAAY;AAEnB,cAAI,MAAM,YAAY,wBAAwB;AAC5C,mBAAO,MAAM,uCAAuC;AACpD,mBAAQ,MAAM,KAAK,OAAO,KAAK,OAAO;AAAA,UACxC;AAGA,cAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,gBAAgB;AAChE,kBAAM,IAAI,aAAa,qCAAqC;AAAA,cAC1D,eAAe,MAAM;AAAA,cACrB,SAAS,KAAK;AAAA,YAChB,CAAC;AAAA,UACH;AAEA,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,SAA2D;AAC3E,cAAM,kBAAkB;AAExB,cAAM,iBAAiB;AAAA,UACrB,GAAG;AAAA,UACH,OAAO,QAAQ,MAAM,IAAI,CAAC,UAA+C;AAAA,YACvE,GAAG;AAAA,YACH,MACE,KAAK,QAAQ,KAAK,KAAK,SAAS,kBAC5B,KAAK,KAAK,UAAU,GAAG,eAAe,IACtC,KAAK;AAAA,UACb,EAAE;AAAA,QACJ;AAEA,eAAO,MAAM,YAAY,eAAe,MAAM,MAAM,QAAQ;AAE5D,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAiC,cAAc,MAAM,QAAQ;AAAA,YACvF,QAAQ;AAAA,YACR,MAAM;AAAA,UACR,CAAC;AAED,iBAAO,MAAM,wBAAwB,SAAS,cAAc,MAAM,QAAQ;AAC1E,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,wBAAwB;AACrC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,cAAc,SAA+D;AACjF,eAAO,MAAM,kEAAkE;AAC/E,eAAO,MAAM,YAAY,QAAQ,QAAQ,MAAM,UAAU;AAEzD,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAmC,cAAc,QAAQ,QAAQ;AAAA,YAC3F,QAAQ;AAAA,YACR,MAAM;AAAA,UACR,CAAC;AAED,iBAAO,MAAM,wBAAwB,SAAS,gBAAgB,MAAM,UAAU;AAC9E,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,0BAA0B;AACvC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,SAA2D;AAC3E,eAAO,MAAM,YAAY,QAAQ,MAAM,MAAM,QAAQ;AACrD,eAAO,MAAM,iBAAiB,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC,EAAE;AAEhE,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAiC,cAAc,MAAM,QAAQ;AAAA,YACvF,QAAQ;AAAA,YACR,MAAM;AAAA,UACR,CAAC;AACD,iBAAO,MAAM,aAAa,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC,EAAE;AAE7D,iBAAO,MAAM,wBAAwB,SAAS,OAAO,QAAQ;AAC7D,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,wBAAwB;AACrC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,UAAU,SAA0B,CAAC,GAA+B;AACxE,cAAM,EAAE,QAAQ,IAAI,SAAS,GAAG,MAAM,OAAO,IAAI;AAEjD,eAAO,MAAM,wBAAwB,KAAK,YAAY,MAAM,EAAE;AAE9D,YAAI;AAEF,gBAAM,cAAc,IAAIG,iBAAgB;AAAA,YACtC,OAAO,MAAM,SAAS;AAAA,YACtB,QAAQ,OAAO,SAAS;AAAA,UAC1B,CAAC;AAED,cAAI,QAAQ;AACV,wBAAY,OAAO,UAAU,MAAM;AAAA,UACrC;AAEA,cAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,iBAAK,QAAQ,CAAC,QAAQ,YAAY,OAAO,UAAU,GAAG,CAAC;AAAA,UACzD;AAEA,gBAAM,MAAM,GAAG,cAAc,MAAM,IAAI,IAAI,YAAY,SAAS,CAAC;AAEjE,gBAAM,WAAW,MAAM,KAAK,YAA+B,KAAK;AAAA,YAC9D,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO;AAAA,YACL,wBAAwB,SAAS,MAAM,MAAM,kBAAkB,SAAS,KAAK;AAAA,UAC/E;AACA,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,sBAAsB;AACnC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,QAAoD;AAC9E,eAAO,MAAM,mCAAmC,MAAM,EAAE;AAExD,YAAI;AACF,gBAAM,MAAM,cAAc,cAAc,KAAK,QAAQ,YAAY,MAAM;AAEvE,gBAAM,WAAW,MAAM,KAAK,YAAuC,KAAK;AAAA,YACtE,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO,MAAM,wBAAwB,SAAS,MAAM,MAAM,gBAAgB;AAC1E,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,8BAA8B;AAC3C,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,wBAAgE;AACpE,eAAO,MAAM,qCAAqC,cAAc,aAAa,MAAM,EAAE;AAErF,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAGzB,cAAc,aAAa,QAAQ;AAAA,YACpC,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO,MAAM,8BAA8B,KAAK,UAAU,QAAQ,CAAC,EAAE;AAGrE,gBAAM,mBAAmB,SAAS;AAElC,iBAAO;AAAA,YACL,sBAAsB,iBAAiB,IAAI,aAAa,iBAAiB,MAAM;AAAA,UACjF;AACA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,iBAAO,MAAM,wCAAwC,KAAK,EAAE;AAC5D,iBAAO,MAAM,kBAAkB,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC,EAAE;AAC/D,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAA8C;AAClD,eAAO,MAAM,0BAA0B;AAEvC,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAkC,cAAc,SAAS;AAAA,YACnF,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO,MAAM,mBAAmB,SAAS,cAAc,EAAE;AACzD,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO,MAAM,yBAAyB;AAGtC,gBAAM,EAAE,SAAAO,SAAQ,IAAI,MAAM;AAC1B,iBAAO;AAAA,YACL,gBAAgBA;AAAA,YAChB,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAmC;AACvC,YAAI;AACF,gBAAM,KAAK,aAAa;AACxB,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,WAAW,KAAmB;AAC5B,aAAK,UAAU;AAEf,aAAK,SAASV,QAAO,OAAO;AAAA,UAC1B,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,aAAqB;AACnB,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAGO,IAAM,aAAa,IAAI,WAAW;AAAA;AAAA;;;AChazC;AAAA,SAAS,eAAe;AACxB,SAAS,gBAAAW,qBAAoB;AAC7B,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,aAAY;;;ACH9B;AAGA;AACA;AAJA,OAAO,WAAW;AAClB,OAAOC,YAAW;AAClB,SAAS,aAAa;;;ACFtB;AAEA;AACA;AAHA,SAAS,QAAAC,aAAY;AACrB,SAAS,aAAAC,kBAAiB;;;ACD1B;AAAA,OAAO,eAA2D;;;ACAlE;AAEA;AAFA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,QAAAC,aAAY;AAMd,SAAS,sBAAsBC,OAAoB;AACxD,QAAM,SAASD,MAAKC,OAAM,MAAM;AAEhC,MAAI,CAACF,YAAW,MAAM,GAAG;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAAE;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;ADjBA;AACA;AAWO,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EACA;AAAA,EAER,YAAY,WAAmB,QAAQ,IAAI,GAAG;AAC5C,SAAK,WAAW;AAChB,SAAK,MAAM,UAAU,QAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAoC;AACxC,QAAI;AACF,4BAAsB,KAAK,QAAQ;AACnC,YAAM,SAAS,MAAM,KAAK,IAAI,YAAY;AAE1C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,SAAS,8BAA8B;AAAA,UAC/C,MAAM,KAAK;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAY;AACnB,UAAI,iBAAiB,UAAU;AAC7B,cAAM;AAAA,MACR;AACA,YAAM,IAAI,SAAS,qCAAqC;AAAA,QACtD,eAAe,MAAM;AAAA,QACrB,MAAM,KAAK;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAgD;AACpD,QAAI;AACF,YAAM,KAAK,mBAAmB;AAE9B,YAAM,SAAS,MAAM,KAAK,IAAI,OAAO;AACrC,YAAM,UAAU,MAAM,KAAK,IAAI,WAAW,IAAI;AAC9C,YAAM,gBAAgB,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAE7D,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,eAAe,OAAO,WAAW;AAAA,QACjC,WAAW,eAAe,MAAM,SAAS,eAAe,MAAM;AAAA,QAC9D,SAAS,OAAO,QAAQ;AAAA,MAC1B;AAAA,IACF,SAAS,OAAY;AACnB,UAAI,iBAAiB,UAAU;AAC7B,cAAM;AAAA,MACR;AACA,YAAM,IAAI,SAAS,wCAAwC;AAAA,QACzD,eAAe,MAAM;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,UAA+B,CAAC,GAAyB;AAC9E,UAAM,EAAE,OAAO,IAAI,OAAO,OAAO,IAAI;AAErC,QAAI;AACF,YAAM,KAAK,mBAAmB;AAE9B,aAAO,MAAM,8BAA8B,IAAI,OAAO;AAGtD,YAAM,QAAQ,oBAAI,KAAK;AACvB,YAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI;AAGpC,YAAM,aAAkB;AAAA,QACtB,WAAW,MAAM,YAAY;AAAA,QAC7B,eAAe;AAAA,MACjB;AAEA,UAAI,OAAO;AACT,mBAAW,WAAW;AAAA,MACxB;AAEA,UAAI,QAAQ;AACV,mBAAW,UAAU,IAAI;AAAA,MAC3B;AAGA,YAAM,MAAmC,MAAM,KAAK,IAAI,IAAI,UAAU;AAEtE,aAAO,MAAM,SAAS,IAAI,IAAI,MAAM,UAAU;AAG9C,YAAM,UAAuB,IAAI,IAAI,IAAI,CAAC,YAAY;AAAA,QACpD,KAAK,OAAO;AAAA,QACZ,SAAS,OAAO;AAAA,QAChB,QAAQ,OAAO;AAAA,QACf,aAAa,OAAO;AAAA,QACpB,MAAM,OAAO;AAAA,MACf,EAAE;AAEF,aAAO;AAAA,IACT,SAAS,OAAY;AACnB,UAAI,iBAAiB,UAAU;AAC7B,cAAM;AAAA,MACR;AACA,YAAM,IAAI,SAAS,2BAA2B;AAAA,QAC5C,eAAe,MAAM;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,KAAiC;AACpD,QAAI;AACF,aAAO,MAAM,4BAA4B,GAAG,EAAE;AAG9C,YAAM,cAAc,MAAM,KAAK,IAAI,YAAY,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC;AAE/D,YAAM,QAAmB;AAAA,QACvB,cAAc,YAAY,MAAM;AAAA,QAChC,YAAY,YAAY;AAAA,QACxB,WAAW,YAAY;AAAA,MACzB;AAEA,aAAO;AAAA,QACL,UAAU,GAAG,KAAK,MAAM,YAAY,YAAY,MAAM,UAAU,KAAK,MAAM,SAAS;AAAA,MACtF;AAEA,aAAO;AAAA,IACT,SAAS,OAAY;AAEnB,UAAI,MAAM,WAAW,MAAM,QAAQ,SAAS,kBAAkB,GAAG;AAC/D,eAAO,MAAM,UAAU,GAAG,+BAA+B;AAEzD,YAAI;AACF,gBAAM,cAAc,MAAM,KAAK,IAAI,YAAY,CAAC,GAAG,CAAC;AACpD,iBAAO;AAAA,YACL,cAAc,YAAY,MAAM;AAAA,YAChC,YAAY,YAAY;AAAA,YACxB,WAAW,YAAY;AAAA,UACzB;AAAA,QACF,QAAQ;AAEN,iBAAO;AAAA,YACL,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAEA,YAAM,IAAI,SAAS,mCAAmC;AAAA,QACpD,eAAe,MAAM;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,UAA+B,CAAC,GAAyB;AACjF,UAAM,UAAU,MAAM,KAAK,iBAAiB,OAAO;AAEnD,WAAO,MAAM,2BAA2B,QAAQ,MAAM,UAAU;AAGhE,UAAM,mBAAmB,MAAM,QAAQ;AAAA,MACrC,QAAQ,IAAI,OAAO,WAAW;AAC5B,YAAI;AACF,gBAAM,QAAQ,MAAM,KAAK,eAAe,OAAO,GAAG;AAClD,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,WAAW;AAAA,UACb;AAAA,QACF,QAAQ;AACN,iBAAO,MAAM,kCAAkC,OAAO,GAAG,4BAA4B;AACrF,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBAA8C;AAClD,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,YAAY,CAAC;AACzD,aAAO,MAAM,KAAK,KAAK;AAAA,IACzB,QAAQ;AACN,aAAO,MAAM,8BAA8B;AAC3C,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAA6C;AACjD,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,WAAW,CAAC;AACvD,aAAO,KAAK,KAAK,KAAK;AAAA,IACxB,QAAQ;AACN,aAAO,MAAM,6BAA6B;AAC1C,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAwB,UAA+B,CAAC,GAAyB;AACrF,UAAM,YAAY,MAAM,KAAK,oBAAoB;AAEjD,QAAI,CAAC,WAAW;AACd,aAAO,QAAQ,2DAA2D;AAC1E,aAAO,KAAK,oBAAoB,OAAO;AAAA,IACzC;AAEA,WAAO,MAAM,8BAA8B,SAAS,EAAE;AAEtD,WAAO,KAAK,oBAAoB;AAAA,MAC9B,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAGO,IAAM,aAAa,IAAI,WAAW;;;ADrPzC,IAAMC,aAAYC,WAAUC,KAAI;AAKzB,IAAM,gBAAN,MAAoB;AAAA,EACR,kBAAkB;AAAA,EAClB,mBACf;AAAA;AAAA;AAAA;AAAA,EAKF,MAAc,iBAAmC;AAC/C,QAAI;AACF,YAAMF,WAAU,sBAAsB;AACtC,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAiC;AAC7C,UAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,YAAY,oCAAoC;AAAA,QACxD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,sBAAwC;AACpD,QAAI;AACF,YAAMA,WAAU,wBAAwB;AACxC,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,uBAAsC;AAClD,UAAM,kBAAkB,MAAM,KAAK,oBAAoB;AACvD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,YAAY,iCAAiC;AAAA,QACrD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAyE;AAC7E,UAAM,YAAY,MAAM,KAAK,eAAe;AAC5C,QAAI,CAAC,WAAW;AACd,aAAO,EAAE,WAAW,OAAO,eAAe,MAAM;AAAA,IAClD;AAEA,UAAM,gBAAgB,MAAM,KAAK,oBAAoB;AACrD,WAAO,EAAE,WAAW,cAAc;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,2BAA0C;AAC9C,QAAI;AACF,YAAM,KAAK,gBAAgB;AAC3B,YAAM,KAAK,qBAAqB;AAGhC,YAAM,WAAW,mBAAmB;AAGpC,YAAM,EAAE,OAAO,IAAI,MAAMA,WAAU,iCAAiC;AACpE,YAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,UAAI,CAAC,KAAK,KAAK;AACb,cAAM,IAAI,YAAY,2CAA2C;AAAA,UAC/D,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAY;AACnB,UAAI,iBAAiB,eAAe,iBAAiB,UAAU;AAC7D,cAAM;AAAA,MACR;AAGA,UAAI,MAAM,SAAS,SAAS,sBAAsB,GAAG;AACnD,cAAM,IAAI,YAAY,wBAAwB;AAAA,UAC5C,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAEA,UAAI,MAAM,SAAS,SAAS,mCAAmC,GAAG;AAChE,cAAM,IAAI,YAAY,2CAA2C;AAAA,UAC/D,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAEA,YAAM,IAAI,YAAY,wCAAwC;AAAA,QAC5D,eAAe,MAAM;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAmD;AACvD,QAAI;AACF,YAAM,KAAK,gBAAgB;AAG3B,YAAM,EAAE,OAAO,IAAI,MAAMA;AAAA,QACvB;AAAA,MACF;AACA,YAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,aAAO;AAAA,QACL,OAAO,KAAK,MAAM;AAAA,QAClB,MAAM,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,QACf,KAAK,KAAK;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,IACF,SAAS,OAAY;AACnB,UAAI,iBAAiB,eAAe,iBAAiB,UAAU;AAC7D,cAAM;AAAA,MACR;AACA,YAAM,IAAI,YAAY,+CAA+C;AAAA,QACnE,eAAe,MAAM;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAA+C;AACnD,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAMA,WAAU,iCAAiC;AACpE,aAAO,OAAO,KAAK,KAAK;AAAA,IAC1B,QAAQ;AACN,aAAO,MAAM,2BAA2B;AACxC,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,UAA2B,CAAC,GAAwB;AACrE,UAAM,EAAE,OAAO,IAAI,OAAO,OAAO,IAAI;AAErC,QAAI;AACF,YAAM,KAAK,gBAAgB;AAC3B,YAAM,KAAK,qBAAqB;AAEhC,aAAO,MAAM,qCAAqC,IAAI,OAAO;AAG7D,YAAM,QAAQ,oBAAI,KAAK;AACvB,YAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI;AACpC,YAAM,YAAY,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAGlD,UAAI,cAAc,YAAY,SAAS;AACvC,UAAI,QAAQ;AACV,uBAAe,WAAW,MAAM;AAAA,MAClC;AAGA,YAAM,WAAW,QAAQ,WAAW,KAAK,KAAK;AAC9C,YAAM,UAAU,4CAA4C,KAAK,gBAAgB,cAAc,WAAW,KAAK,QAAQ;AAEvH,aAAO,MAAM,YAAY,OAAO,EAAE;AAElC,YAAM,EAAE,OAAO,IAAI,MAAMA,WAAU,OAAO;AAC1C,YAAM,MAAkB,KAAK,MAAM,MAAM;AAEzC,aAAO,MAAM,SAAS,IAAI,MAAM,aAAa;AAE7C,aAAO;AAAA,IACT,SAAS,OAAY;AACnB,UAAI,iBAAiB,eAAe,iBAAiB,UAAU;AAC7D,cAAM;AAAA,MACR;AACA,YAAM,IAAI,YAAY,mCAAmC;AAAA,QACvD,eAAe,MAAM;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,UAA2B,CAAC,GAAwB;AAC5E,UAAM,cAAc,MAAM,KAAK,qBAAqB;AAEpD,QAAI,CAAC,aAAa;AAChB,aAAO,QAAQ,oDAAoD;AACnE,aAAO,KAAK,aAAa,OAAO;AAAA,IAClC;AAEA,WAAO,MAAM,4BAA4B,WAAW,EAAE;AAGtD,WAAO,KAAK,aAAa;AAAA,MACvB,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBAAoB,IAAyB;AAE3C,UAAM,QAAQ,GAAG;AACjB,UAAM,OAAO,GAAG,QAAQ;AAGxB,UAAM,gBACJ,KAAK,SAAS,KAAK,kBACf,KAAK,UAAU,GAAG,KAAK,eAAe,IAAI,mBAC1C;AAEN,UAAM,UAAU,gBAAgB,GAAG,KAAK;AAAA;AAAA,EAAO,aAAa,KAAK;AAEjE,WAAO;AAAA,MACL,KAAK,MAAM,GAAG,MAAM;AAAA,MACpB;AAAA,MACA,QAAQ,GAAG,OAAO;AAAA,MAClB,aAAa;AAAA;AAAA,MACb,MAAM,GAAG;AAAA,MACT,KAAK,GAAG;AAAA,MACR,WAAW;AAAA,QACT,cAAc,GAAG;AAAA,QACjB,YAAY,GAAG;AAAA,QACf,WAAW,GAAG;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,gBAAgB,IAAI,cAAc;;;ADrQ/C;;;AINA;AAAA,OAAOG,YAAW;AAKX,IAAM,SAAS;AAAA;AAAA,EAEpB,SAASA,OAAM;AAAA;AAAA,EAGf,SAASA,OAAM;AAAA,EACf,aAAaA,OAAM,MAAM;AAAA;AAAA,EAGzB,SAASA,OAAM;AAAA,EACf,aAAaA,OAAM,OAAO;AAAA;AAAA,EAG1B,OAAOA,OAAM;AAAA,EACb,WAAWA,OAAM,IAAI;AAAA;AAAA,EAGrB,MAAMA,OAAM;AAAA,EACZ,SAASA,OAAM;AAAA;AAAA,EAGf,WAAWA,OAAM,OAAO;AAAA,EACxB,eAAeA,OAAM,KAAK;AAAA;AAAA,EAG1B,MAAMA,OAAM;AAAA,EACZ,KAAKA,OAAM;AAAA;AAAA,EAGX,OAAOA,OAAM;AAAA,EACb,MAAMA,OAAM;AAAA;AAAA,EAGZ,MAAMA,OAAM,KAAK;AACnB;AAKO,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA,EAInB,SAAS,CAAC,SAAiB,OAAO,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA,EAK9C,SAAS,CAAC,SAAiB,OAAO,QAAQ,UAAK,IAAI,EAAE;AAAA,EACrD,aAAa,CAAC,SAAiB,OAAO,YAAY,UAAK,IAAI,EAAE;AAAA;AAAA;AAAA;AAAA,EAK7D,OAAO,CAAC,SAAiB,OAAO,MAAM,UAAK,IAAI,EAAE;AAAA,EACjD,WAAW,CAAC,SAAiB,OAAO,UAAU,UAAK,IAAI,EAAE;AAAA;AAAA;AAAA;AAAA,EAKzD,SAAS,CAAC,SAAiB,OAAO,QAAQ,UAAK,IAAI,EAAE;AAAA;AAAA;AAAA;AAAA,EAKrD,MAAM,CAAC,SAAiB,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA,EAKxC,OAAO,CAAC,SAAiB,OAAO,KAAK,GAAG,IAAI,GAAG;AAAA;AAAA;AAAA;AAAA,EAK/C,OAAO,CAAC,SAAiB,OAAO,UAAU,IAAI;AAAA;AAAA;AAAA;AAAA,EAK9C,OAAO,CAAC,QAAgB,OAAO,cAAc,IAAI,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA,EAK3D,MAAM,CAAC,SAAiB,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA,EAKxC,MAAM,CAAC,SAAiB,UAAkB,OAAO,QAAQ,IAAI,OAAO,IAAI,KAAK,GAAG;AAAA;AAAA;AAAA;AAAA,EAKhF,UAAU,CAAC,SAAiB,OAAO,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA,EAK/C,UAAU,CAAC,SAAiB,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA,EAK5C,WAAW,CAAC,SAAiB,OAAO,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAK5C,aAAa,CAAC,SAAiB,OAAO,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA,EAKlD,KAAK,CAAC,SAAiB,OAAO,MAAM,IAAI;AAC1C;AAKO,IAAM,YAAY;AAAA,EACvB,SAAS;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAAA,EAEA,OAAO;AAAA,IACL,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAAA,EAEA,SAAS;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAAA,EAEA,MAAM;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAAA,EAEA,OAAO;AAAA,IACL,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AACF;AAKO,IAAM,cAAc;AAAA,EACzB,SAAS;AAAA,IACP,OAAO;AAAA,MACL,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC,MAAM;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,SAAS;AAAA,IACP,OAAO;AAAA,MACL,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC,KAAK;AAAA,MACd,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAKO,IAAM,iBAAiB;AAAA,EAC5B,OAAO,OAAO,QAAQ,QAAG;AAAA,EACzB,QAAQ,OAAO,QAAQ,QAAG;AAAA,EAC1B,OAAO,OAAO,MAAM,QAAG;AACzB;AAKO,SAAS,iBAAiB,YAAoB,WAA2B;AAC9E,QAAM,QAAQ,aAAa;AAE3B,MAAI,QAAQ,IAAI;AACd,WAAO,GAAG,eAAe,KAAK;AAAA,EAChC,WAAW,QAAQ,KAAK;AACtB,WAAO,GAAG,eAAe,MAAM;AAAA,EACjC,OAAO;AACL,WAAO,GAAG,eAAe,KAAK;AAAA,EAChC;AACF;AAKO,SAAS,gBAAgB,YAAoB,WAA2B;AAC7E,SAAO,GAAG,OAAO,QAAQ,IAAI,UAAU,EAAE,CAAC,IAAI,OAAO,MAAM,IAAI,SAAS,EAAE,CAAC;AAC7E;;;AJpMA,eAAsB,YAAY,YAAoC;AAEpE,MAAI,CAAC,cAAc,eAAe,SAAS;AACzC,UAAM,UAAU;AAAA,EAClB,WAAW,eAAe,UAAU;AAClC,UAAM,WAAW;AAAA,EACnB,WAAW,eAAe,aAAa;AACrC,UAAM,cAAc;AAAA,EACtB,WAAW,eAAe,UAAU;AAClC,UAAM,WAAW;AAAA,EACnB,WAAW,eAAe,aAAa;AACrC,UAAM,cAAc;AAAA,EACtB,OAAO;AACL,WAAO,MAAM,4BAA4B,UAAU,EAAE;AACrD,WAAO,KAAK,oEAAoE;AAChF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,eAAe,YAA2B;AACxC,SAAO,IAAI,EAAE;AACb,SAAO,KAAK,iCAAiC;AAC7C,SAAO,IAAI,EAAE;AAGb,QAAM,kBAAkB,MAAM,eAAe,uBAAuB,UAAU;AAC9E,MAAI,iBAAiB;AACnB,UAAM,WAAW,YAAY,YAAY;AACzC,QAAI,UAAU;AACZ,aAAO;AAAA,QACL;AAAA,UACE,GAAGC,OAAM,OAAO,wBAAwB,CAAC;AAAA;AAAA,EACpCA,OAAM,KAAK,OAAO,CAAC,IAAI,SAAS,IAAI;AAAA,EACpCA,OAAM,KAAK,QAAQ,CAAC,IAAI,SAAS,KAAK;AAAA;AAAA,EACtCA,OAAM,IAAI,KAAK,CAAC,IAAIA,OAAM,KAAK,iBAAiB,CAAC,IAAIA,OAAM,IAAI,aAAa,CAAC;AAAA,UAClF;AAAA,YACE,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AACF,UAAM,WAAW,MAAM,YAAY,MAAM;AAEzC,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL;AAAA,QACE,GAAGA,OAAM,MAAM,KAAK,oCAA+B,CAAC;AAAA;AAAA,EAC/CA,OAAM,KAAK,UAAU,CAAC,IAAIA,OAAM,KAAK,SAAS,IAAI,CAAC;AAAA,EACnDA,OAAM,KAAK,QAAQ,CAAC,IAAI,SAAS,KAAK;AAAA;AAAA,EACtCA,OAAM,IAAI,KAAK,CAAC,IAAIA,OAAM,KAAK,eAAe,CAAC,IAAIA,OAAM,IAAI,iBAAiB,CAAC;AAAA,QACpF;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AAAA,EACf,SAAS,OAAO;AACd,UAAM,MAAM;AACZ,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL,MAAM,GAAGA,OAAM,IAAI,KAAK,8BAAyB,CAAC;AAAA;AAAA,EAAY,IAAI,OAAO,IAAI;AAAA,QAC3E,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,eAAe,aAA4B;AACzC,SAAO,IAAI,EAAE;AACb,SAAO,KAAK,wBAAwB;AACpC,SAAO,IAAI,EAAE;AAEb,QAAM,WAAW,MAAM,eAAe,yBAAyB;AAG/D,QAAM,eAAe,MAAM,eAAe,uBAAuB,UAAU;AAC3E,MAAI,cAAc;AAChB,UAAM,WAAW,YAAY,YAAY;AACzC,WAAO,KAAK,GAAG,OAAO,QAAQ,QAAG,CAAC,cAAc,UAAU,QAAQ,eAAe,EAAE;AAAA,EACrF,OAAO;AACL,WAAO,KAAK,GAAG,OAAO,MAAM,QAAG,CAAC,8BAA8B;AAAA,EAChE;AAGA,QAAM,WAAW,MAAM,cAAc,cAAc;AACnD,MAAI,SAAS,WAAW;AACtB,QAAI,SAAS,eAAe;AAC1B,aAAO,KAAK,GAAG,OAAO,QAAQ,QAAG,CAAC,iCAAiC;AAAA,IACrE,OAAO;AACL,aAAO,KAAK,GAAG,OAAO,MAAM,QAAG,CAAC,qCAAqC;AACrE,aAAO,KAAK,MAAM,UAAU,sBAAsB,CAAC;AAAA,IACrD;AAAA,EACF,OAAO;AACL,WAAO,KAAK,GAAG,OAAO,MAAM,QAAG,CAAC,iCAAiC;AACjE,WAAO,KAAK,MAAM,UAAU,wCAAwC,CAAC;AAAA,EACvE;AAGA,aAAW,WAAW,UAAU;AAC9B,QAAI,YAAY,YAAY;AAC1B,aAAO,KAAK,GAAG,OAAO,QAAQ,QAAG,CAAC,IAAI,OAAO,iBAAiB;AAAA,IAChE;AAAA,EACF;AAEA,SAAO,IAAI,EAAE;AAGb,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,KAAK,OAAO,MAAM,QAAQ,qBAAqB,CAAC,gCAAgC;AACvF,WAAO,IAAI,EAAE;AAAA,EACf;AACF;AAKA,eAAe,gBAA+B;AAC5C,SAAO,IAAI,EAAE;AACb,SAAO;AAAA,IACL;AAAA,MACE,MAAM,KAAK,oCAAoC,IAC7C,kCAEA,OAAO,UAAU,sDAAsD,IACvE,yGAKA,MAAM,QAAQ,sCAAsC;AAAA,MACtD,UAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AAEb,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM;AAAA,MACxB,SAAS;AAAA,MACT,UAAU,CAAC,UAAW,MAAM,SAAS,GAAG,IAAI,OAAO;AAAA,IACrD,CAAC;AAED,UAAM,WAAW,MAAM,MAAM;AAAA,MAC3B,SAAS;AAAA,MACT,UAAU,CAAC,UAAW,MAAM,SAAS,IAAI,OAAO;AAAA,IAClD,CAAC;AAED,UAAM,cAAc,MAAM,MAAM;AAAA,MAC9B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO;AACnB,cAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,eAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO;AAAA,MACzC;AAAA,IACF,CAAC;AAGD,UAAM,OAAO,OAAO,KAAK,GAAG,KAAK,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAClE,UAAM,WAAW,MAAM,MAAM,sCAAsC;AAAA,MACjE,SAAS,EAAE,eAAe,SAAS,IAAI,GAAG;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,aAAO,IAAI,EAAE;AACb,aAAO;AAAA,QACL;AAAA,UACE,MAAM,MAAM,8BAAyB,IAAI;AAAA,UACzC,UAAU;AAAA,QACZ;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AACb,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAGlC,UAAM,cAAkC;AAAA,MACtC,aAAa;AAAA,MACb,UAAU;AAAA;AAAA,IACZ;AAGA,QAAI,aAAa;AACf,YAAM,aAAa,IAAI,KAAK,WAAW;AACvC,kBAAY,YAAY,WAAW,QAAQ;AAAA,IAC7C;AAEA,UAAM,eAAe,sBAAsB,aAAa,WAAW;AAEnE,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL;AAAA,QACE,MAAM,QAAQ,kDAA6C,IACzD;AAAA;AAAA,SACU,KAAK;AAAA,QACN,KAAK,YAAY;AAAA,KACzB,cAAc,YAAY,WAAW,KAAK;AAAA,QAC7C,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AAAA,EACf,SAAS,OAAO;AACd,UAAM,MAAM;AACZ,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL;AAAA,QACE,MAAM,MAAM,8BAAyB,IAAI,UAAU,IAAI,WAAW;AAAA,QAClE,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AACb,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,eAAe,aAA4B;AACzC,SAAO,IAAI,EAAE;AACb,SAAO;AAAA,IACL;AAAA,MACE,MAAM,KAAK,6CAA6C,IACtD,6CAEA,OAAO,UAAU,qDAAqD,IACtE,gIAKA,MAAM,QAAQ,kDAAkD;AAAA,MAClE,UAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AAEb,MAAI;AACF,UAAM,cAAc,MAAM,MAAM;AAAA,MAC9B,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAED,UAAM,cAAc,MAAM,MAAM;AAAA,MAC9B,SAAS;AAAA,MACT,UAAU,CAAC,UAAW,MAAM,SAAS,IAAI,OAAO;AAAA,IAClD,CAAC;AAGD,UAAM,UAAU,GAAG,YAAY,QAAQ,OAAO,EAAE,CAAC;AACjD,UAAM,WAAW,MAAM,MAAM,SAAS;AAAA,MACpC,SAAS,EAAE,iBAAiB,YAAY;AAAA,IAC1C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,aAAO,IAAI,EAAE;AACb,aAAO;AAAA,QACL;AAAA,UACE,MAAM,MAAM,8BAAyB,IAAI;AAAA,UACzC,UAAU;AAAA,QACZ;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AACb,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAGlC,UAAM,cAAkC;AAAA,MACtC;AAAA,MACA,aAAa,gBAAgB,uBAAuB,SAAY;AAAA,IAClE;AAEA,UAAM,eAAe,sBAAsB,UAAU,WAAW;AAEhE,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL;AAAA,QACE,MAAM,QAAQ,+CAA0C,IACtD;AAAA;AAAA,YACa,WAAW;AAAA,QACf,KAAK,IAAI,MAAM,KAAK,QAAQ;AAAA,QACvC,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AAAA,EACf,SAAS,OAAO;AACd,UAAM,MAAM;AACZ,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL;AAAA,QACE,MAAM,MAAM,8BAAyB,IAAI,UAAU,IAAI,WAAW;AAAA,QAClE,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AACb,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,eAAe,gBAA+B;AAC5C,SAAO,IAAI,EAAE;AACb,SAAO;AAAA,IACL;AAAA,MACE,MAAM,KAAK,oCAAoC,IAC7C,0FAGA,OAAO,UAAU,6DAA6D,IAC9E;AAAA,MAKF,UAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AAEb,MAAI;AACF,UAAM,cAAc,MAAM,MAAM;AAAA,MAC9B,SAAS;AAAA,MACT,UAAU,CAAC,UAAW,MAAM,SAAS,IAAI,OAAO;AAAA,IAClD,CAAC;AAED,UAAM,QAAQ,MAAM,MAAM;AAAA,MACxB,SAAS;AAAA,MACT,UAAU,CAAC,UAAW,MAAM,SAAS,GAAG,IAAI,OAAO;AAAA,IACrD,CAAC;AAED,UAAM,WAAW,MAAM,MAAM;AAAA,MAC3B,SAAS;AAAA,MACT,UAAU,CAAC,UAAW,MAAM,SAAS,IAAI,OAAO;AAAA,IAClD,CAAC;AAGD,UAAM,kBAAkB,YAAY,WAAW,MAAM,IAAI,cAAc,WAAW,WAAW;AAC7F,UAAM,OAAO,OAAO,KAAK,GAAG,KAAK,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAClE,UAAM,WAAW,MAAM,MAAM,GAAG,eAAe,sBAAsB;AAAA,MACnE,SAAS,EAAE,eAAe,SAAS,IAAI,GAAG;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,aAAO,IAAI,EAAE;AACb,aAAO;AAAA,QACL;AAAA,UACE,MAAM,MAAM,8BAAyB,IACnC;AAAA,UAGF,UAAU;AAAA,QACZ;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AACb,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAGlC,UAAM,cAAkC;AAAA,MACtC,aAAa;AAAA,MACb,UAAU;AAAA,MACV,aAAa,YAAY,WAAW,MAAM,IAAI,cAAc,WAAW,WAAW;AAAA,IACpF;AAEA,UAAM,eAAe,sBAAsB,QAAQ,WAAW;AAC9D,UAAM,eAAe,sBAAsB,cAAc,WAAW;AAEpE,UAAM,eAAe,sBAAsB,aAAa;AAAA,MACtD,GAAG;AAAA,MACH,aAAa;AAAA;AAAA,IACf,CAAC;AAED,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL;AAAA,QACE,MAAM,QAAQ,kDAA6C,IACzD;AAAA;AAAA,YACa,WAAW;AAAA,QACf,KAAK,WAAW;AAAA,SACf,KAAK,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAK7B,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AAAA,EACf,SAAS,OAAO;AACd,UAAM,MAAM;AACZ,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL;AAAA,QACE,MAAM,MAAM,8BAAyB,IAAI,UAAU,IAAI,WAAW;AAAA,QAClE,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AACb,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AK7bA;;;ACAA;AAQO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EACzC,OAAO;AAAA,EACP,UAAU;AACd;;;ADRA;AACA;AACA;AACA;AACA;AANA,SAAS,UAAAC,eAAc;AACvB,OAAOC,YAAW;;;AEFlB;;;ACAA;AAOO,IAAM,oBAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EAEhB,MAAM,WAA0B;AAC9B,UAAM,cAAc,yBAAyB;AAAA,EAC/C;AAAA,EAEA,MAAM,oBAAoB;AACxB,UAAM,OAAO,MAAM,cAAc,kBAAkB;AACnD,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAsD;AAEzE,QAAI;AACJ,QAAI,QAAQ,QAAQ;AAClB,YAAM,MAAM,cAAc,aAAa;AAAA,QACrC,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,MAAM,cAAc,oBAAoB;AAAA,QAC5C,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH;AAGA,WAAO,IAAI,IAAI,CAAC,OAAO,cAAc,oBAAoB,EAAE,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,kBAAoC;AACxC,QAAI;AACF,YAAM,cAAc,yBAAyB;AAC7C,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,iBAAyC;AAC7C,WAAO,cAAc,qBAAqB;AAAA,EAC5C;AACF;AAEO,IAAM,oBAAoB,IAAI,kBAAkB;;;AC1DvD;;;ACAA;AAEA;AACA;AACA;AAJA,SAAS,QAAAC,aAAY;AACrB,SAAS,aAAAC,kBAAiB;AAc1B,IAAMC,aAAYC,WAAUC,KAAI;AAKzB,IAAM,mBAAN,MAAuB;AAAA,EACX,qBAAqB;AAAA,EACrB,yBAAyB;AAAA;AAAA;AAAA;AAAA,EAK1C,MAAc,iBAA+D;AAC3E,UAAM,QAAQ,MAAM,eAAe,sBAAsB,WAAW;AACpE,QAAI,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,MAAM,aAAa;AACnD,YAAM,IAAI,eAAe,oCAAoC;AAAA,QAC3D,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAGA,QAAI,MAAM,aAAa,MAAM,YAAY,KAAK,IAAI,GAAG;AACnD,YAAM,IAAI,eAAe,yBAAyB;AAAA,QAChD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,OAAO,MAAM;AAAA;AAAA,MACb,UAAU,MAAM;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QAAW,UAA8B;AACrD,UAAM,EAAE,OAAO,SAAS,IAAI,MAAM,KAAK,eAAe;AACtD,UAAM,OAAO,OAAO,KAAK,GAAG,KAAK,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAElE,WAAO,MAAM,sBAAsB,QAAQ,EAAE;AAE7C,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,kBAAkB,GAAG,QAAQ,IAAI;AAAA,MACpE,SAAS;AAAA,QACP,eAAe,SAAS,IAAI;AAAA,QAC5B,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,aAAa,SAAS;AAC5B,YAAM,SAAS,SAAS;AAExB,UAAI,WAAW,KAAK;AAClB,cAAM,IAAI,eAAe,gCAAgC;AAAA,UACvD,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,eAAe,uCAAuC;AAAA,UAC9D,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,eAAe,oCAAoC;AAAA,UAC3D,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,eAAe,uBAAuB;AAAA,UAC9C,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,YAAM,IAAI,eAAe,uBAAuB,UAAU,IAAI;AAAA,QAC5D,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,KAAyD;AAE9E,UAAM,QAAQ,IAAI,MAAM,qCAAqC;AAC7D,QAAI,SAAS,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG;AACjC,aAAO;AAAA,QACL,WAAW,MAAM,CAAC;AAAA,QAClB,MAAM,MAAM,CAAC,EAAE,QAAQ,UAAU,EAAE;AAAA,MACrC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAA+D;AAC3E,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAMF,WAAU,mCAAmC;AACtE,YAAM,YAAY,OAAO,KAAK;AAE9B,YAAM,SAAS,KAAK,eAAe,SAAS;AAC5C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,eAAe,wDAAwD;AAAA,UAC/E,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT,SAAS,OAAgB;AACvB,UAAI,iBAAiB,gBAAgB;AACnC,cAAM;AAAA,MACR;AACA,YAAM,IAAI,SAAS,8BAA8B;AAAA,IACnD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,8BAA6C;AAEjD,UAAM,WAAW,mBAAmB;AAGpC,UAAM,EAAE,WAAW,KAAK,IAAI,MAAM,KAAK,eAAe;AAGtD,QAAI;AACF,YAAM,KAAK,QAA6B,iBAAiB,SAAS,IAAI,IAAI,EAAE;AAAA,IAC9E,SAAS,OAAgB;AACvB,UAAI,iBAAiB,gBAAgB;AACnC,cAAM;AAAA,MACR;AACA,YAAM,IAAI,eAAe,iDAAiD;AAAA,QACxE,MAAM;AAAA,QACN,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACtE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAKH;AACD,UAAM,EAAE,WAAW,KAAK,IAAI,MAAM,KAAK,eAAe;AAEtD,UAAM,gBAAgB,MAAM,KAAK;AAAA,MAC/B,iBAAiB,SAAS,IAAI,IAAI;AAAA,IACpC;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM,cAAc;AAAA,MACpB,UAAU,cAAc;AAAA,MACxB,KAAK,cAAc,MAAM,KAAK;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,0BAA2C;AACvD,UAAM,OAAO,MAAM,KAAK,QAAuB,OAAO;AACtD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAA+C;AACnD,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,QAAuB,OAAO;AACtD,aAAO,KAAK;AAAA,IACd,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,UAAoC,CAAC,GAAoC;AAC1F,UAAM,EAAE,WAAW,KAAK,IAAI,MAAM,KAAK,eAAe;AAGtD,UAAM,UAAU,CAAC,gBAAgB;AAGjC,QAAI,QAAQ,MAAM;AAChB,YAAM,QAAQ,oBAAI,KAAK;AACvB,YAAM,QAAQ,MAAM,QAAQ,IAAI,QAAQ,IAAI;AAC5C,cAAQ,KAAK,eAAe,MAAM,YAAY,CAAC,EAAE;AAAA,IACnD;AAGA,QAAI,QAAQ,QAAQ;AAClB,cAAQ,KAAK,sBAAsB,QAAQ,MAAM,GAAG;AAAA,IACtD;AAEA,UAAM,cAAc,QAAQ,KAAK,OAAO;AAGxC,UAAM,SAAiC,CAAC;AACxC,QAAI,WAAW,iBAAiB,SAAS,IAAI,IAAI,mBAAmB,mBAAmB,WAAW,CAAC;AAEnG,WAAO,UAAU;AACf,YAAM,WACJ,MAAM,KAAK,QAA0D,QAAQ;AAE/E,aAAO,KAAK,GAAG,SAAS,MAAM;AAE9B,aAAO;AAAA,QACL,WAAW,SAAS,OAAO,MAAM,gBAAgB,OAAO,MAAM,IAAI,SAAS,OAAO,4BAA4B,EAAE;AAAA,MAClH;AAGA,UAAI,QAAQ,SAAS,OAAO,UAAU,QAAQ,OAAO;AACnD,eAAO,OAAO,MAAM,GAAG,QAAQ,KAAK;AAAA,MACtC;AAGA,UAAI,SAAS,MAAM;AACjB,cAAM,MAAM,IAAI,IAAI,SAAS,IAAI;AACjC,mBAAW,IAAI,WAAW,IAAI;AAAA,MAChC,OAAO;AACL,mBAAW;AAAA,MACb;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBACJ,UAAoD,CAAC,GACpB;AACjC,UAAM,YAAY,MAAM,KAAK,wBAAwB;AACrD,WAAO,KAAK,aAAa;AAAA,MACvB,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,IAAqC;AAEvD,QAAI,UAAU,GAAG;AACjB,QAAI,GAAG,aAAa;AAClB,YAAM,gBAAgB,GAAG,YAAY,UAAU,GAAG,KAAK,sBAAsB;AAC7E,gBAAU,GAAG,GAAG,KAAK;AAAA;AAAA,EAAO,aAAa;AAAA,IAC3C;AAEA,WAAO;AAAA,MACL,KAAK,MAAM,GAAG,EAAE;AAAA,MAChB;AAAA,MACA,QAAQ,GAAG,OAAO;AAAA,MAClB,aAAa;AAAA;AAAA,MACb,MAAM,GAAG;AAAA,MACT,KAAK,GAAG,MAAM,KAAK;AAAA,MACnB,WAAW;AAAA,QACT,cAAc;AAAA;AAAA,QACd,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,mBAAmB,IAAI,iBAAiB;;;ADlS9C,IAAM,uBAAN,MAAkD;AAAA,EAC9C,OAAO;AAAA,EAEhB,MAAM,WAA0B;AAC9B,UAAM,iBAAiB,4BAA4B;AAAA,EACrD;AAAA,EAEA,MAAM,oBAAoB;AACxB,UAAM,OAAO,MAAM,iBAAiB,kBAAkB;AACtD,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAsD;AACzE,QAAI;AACJ,QAAI,QAAQ,QAAQ;AAClB,YAAM,MAAM,iBAAiB,aAAa;AAAA,QACxC,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,MAAM,iBAAiB,oBAAoB;AAAA,QAC/C,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,IAAI,CAAC,OAAO,iBAAiB,oBAAoB,EAAE,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,kBAAoC;AACxC,QAAI;AACF,YAAM,iBAAiB,4BAA4B;AACnD,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,iBAAyC;AAC7C,WAAO,iBAAiB,qBAAqB;AAAA,EAC/C;AACF;AAEO,IAAM,uBAAuB,IAAI,qBAAqB;;;AExD7D;;;ACAA;AAGA;AACA;AACA;AALA,SAAS,QAAAG,aAAY;AACrB,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,mBAAAC,wBAAuB;AAahC,IAAMC,aAAYC,WAAUC,KAAI;AAKzB,IAAM,gBAAN,MAAoB;AAAA,EACR,mBAAmB;AAAA,EACnB,yBAAyB;AAAA;AAAA;AAAA;AAAA,EAK1C,MAAc,iBAAwE;AACpF,UAAM,QAAQ,MAAM,eAAe,sBAAsB,QAAQ;AACjE,QAAI,CAAC,SAAS,CAAC,MAAM,aAAa;AAChC,YAAM,IAAI,YAAY,iCAAiC;AAAA,QACrD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAGA,QAAI,MAAM,aAAa,MAAM,YAAY,KAAK,IAAI,GAAG;AACnD,YAAM,IAAI,YAAY,4BAA4B;AAAA,QAChD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,aAAa,MAAM;AAAA,MACnB,aAAa,MAAM,eAAe,KAAK;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QAAW,UAA8B;AACrD,UAAM,EAAE,aAAa,YAAY,IAAI,MAAM,KAAK,eAAe;AAC/D,UAAM,UAAU,GAAG,WAAW;AAC9B,UAAM,MAAM,GAAG,OAAO,GAAG,QAAQ;AAEjC,WAAO,MAAM,mBAAmB,QAAQ,EAAE;AAE1C,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,aAAa,SAAS;AAC5B,YAAM,SAAS,SAAS;AAExB,UAAI,WAAW,KAAK;AAClB,cAAM,IAAI,YAAY,mCAAmC;AAAA,UACvD,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,YAAY,kCAAkC;AAAA,UACtD,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,YAAY,sBAAsB;AAAA,UAC1C,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,YAAY,uBAAuB;AAAA,UAC3C,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,YAAM,IAAI,YAAY,uBAAuB,UAAU,IAAI;AAAA,QACzD,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,KAA4D;AAKjF,UAAM,QAAQ,IAAI,MAAM,oCAAoC;AAC5D,QAAI,SAAS,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG;AACjC,aAAO;AAAA,QACL,WAAW,MAAM,CAAC;AAAA,QAClB,SAAS,MAAM,CAAC;AAAA,MAClB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,oBAIX;AACD,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAMF,WAAU,2BAA2B;AAC9D,YAAM,YAAY,OAAO,KAAK;AAE9B,YAAM,SAAS,KAAK,eAAe,SAAS;AAC5C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,YAAY,kDAAkD;AAAA,UACtE,KAAK;AAAA,QACP,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,GAAG,OAAO,SAAS,IAAI,OAAO,OAAO;AAAA,MACpD;AAAA,IACF,SAAS,OAAgB;AACvB,UAAI,iBAAiB,aAAa;AAChC,cAAM;AAAA,MACR;AACA,YAAM,IAAI,SAAS,8BAA8B;AAAA,IACnD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,2BAA0C;AAE9C,UAAM,WAAW,mBAAmB;AAGpC,UAAM,EAAE,YAAY,IAAI,MAAM,KAAK,kBAAkB;AAGrD,UAAM,cAAc,mBAAmB,WAAW;AAClD,QAAI;AACF,YAAM,KAAK,QAAuB,aAAa,WAAW,EAAE;AAAA,IAC9D,SAAS,OAAgB;AACvB,UAAI,iBAAiB,aAAa;AAChC,cAAM;AAAA,MACR;AACA,YAAM,IAAI,YAAY,2CAA2C;AAAA,QAC/D,MAAM;AAAA,QACN,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACtE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAKH;AACD,UAAM,EAAE,YAAY,IAAI,MAAM,KAAK,kBAAkB;AACrD,UAAM,cAAc,mBAAmB,WAAW;AAClD,UAAM,UAAU,MAAM,KAAK,QAAuB,aAAa,WAAW,EAAE;AAE5E,UAAM,CAAC,OAAO,IAAI,IAAI,YAAY,MAAM,GAAG;AAE3C,WAAO;AAAA,MACL,OAAO,SAAS;AAAA,MAChB,MAAM,QAAQ;AAAA,MACd,UAAU,QAAQ;AAAA,MAClB,KAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,UAAiC,CAAC,GAAkC;AACrF,UAAM,EAAE,YAAY,IAAI,MAAM,KAAK,kBAAkB;AACrD,UAAM,cAAc,mBAAmB,WAAW;AAGlD,UAAM,SAAS,IAAIG,iBAAgB;AAAA,MACjC,OAAO;AAAA,MACP,UAAU;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,IACZ,CAAC;AAGD,QAAI,QAAQ,MAAM;AAChB,YAAM,QAAQ,oBAAI,KAAK;AACvB,YAAM,QAAQ,MAAM,QAAQ,IAAI,QAAQ,IAAI;AAC5C,aAAO,OAAO,iBAAiB,MAAM,YAAY,CAAC;AAAA,IACpD;AAGA,QAAI,QAAQ,QAAQ;AAClB,aAAO,OAAO,mBAAmB,QAAQ,MAAM;AAAA,IACjD;AAGA,UAAM,SAA+B,CAAC;AACtC,QAAI,OAAO;AAEX,WAAO,MAAM;AACX,aAAO,IAAI,QAAQ,KAAK,SAAS,CAAC;AAClC,YAAM,WAAW,aAAa,WAAW,mBAAmB,MAAM;AAElE,YAAM,MAAM,MAAM,KAAK,QAA8B,QAAQ;AAC7D,aAAO,KAAK,GAAG,GAAG;AAElB,aAAO;AAAA,QACL,WAAW,IAAI,MAAM,gBAAgB,OAAO,MAAM,IAAI,IAAI,WAAW,MAAM,4BAA4B,EAAE;AAAA,MAC3G;AAGA,UAAI,QAAQ,SAAS,OAAO,UAAU,QAAQ,OAAO;AACnD,eAAO,OAAO,MAAM,GAAG,QAAQ,KAAK;AAAA,MACtC;AAGA,UAAI,IAAI,SAAS,KAAK;AACpB;AAAA,MACF;AAEA;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,UAAiC,CAAC,GAAkC;AAC5F,UAAM,WAAW,MAAM,KAAK,qBAAqB;AACjD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,YAAY,qCAAqC;AAAA,IAC7D;AACA,WAAO,KAAK,aAAa;AAAA,MACvB,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAA+C;AACnD,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,QAAoB,OAAO;AACnD,aAAO,KAAK;AAAA,IACd,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,IAAmC;AACrD,UAAM,UAAU,KAAK,cAAc,GAAG,OAAO,GAAG,WAAW;AAE3D,WAAO;AAAA,MACL,KAAK,MAAM,GAAG,GAAG;AAAA;AAAA,MACjB;AAAA,MACA,QAAQ,GAAG,OAAO;AAAA,MAClB,aAAa;AAAA;AAAA,MACb,MAAM,GAAG;AAAA,MACT,KAAK,GAAG;AAAA,MACR,WAAW;AAAA,QACT,cAAc,GAAG,YAAY,cAAc;AAAA,QAC3C,YAAY,GAAG,YAAY,aAAa;AAAA,QACxC,WAAW,GAAG,YAAY,aAAa;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,OAAe,aAAoC;AACvE,QAAI,CAAC,YAAa,QAAO;AACzB,UAAM,YAAY,YAAY,UAAU,GAAG,KAAK,sBAAsB;AACtE,WAAO,GAAG,KAAK;AAAA;AAAA,EAAO,SAAS;AAAA,EACjC;AACF;AAEO,IAAM,gBAAgB,IAAI,cAAc;;;ADhTxC,IAAM,oBAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EAEhB,MAAM,WAA0B;AAC9B,UAAM,cAAc,yBAAyB;AAAA,EAC/C;AAAA,EAEA,MAAM,oBAAoB;AACxB,UAAM,OAAO,MAAM,cAAc,kBAAkB;AACnD,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAsD;AACzE,QAAI;AACJ,QAAI,QAAQ,QAAQ;AAClB,YAAM,MAAM,cAAc,aAAa;AAAA,QACrC,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,MAAM,cAAc,oBAAoB;AAAA,QAC5C,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH;AACA,WAAO,IAAI,IAAI,CAAC,OAAO,cAAc,oBAAoB,EAAE,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,kBAAoC;AACxC,QAAI;AACF,YAAM,cAAc,yBAAyB;AAC7C,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,iBAAyC;AAC7C,WAAO,cAAc,qBAAqB;AAAA,EAC5C;AACF;AAEO,IAAM,oBAAoB,IAAI,kBAAkB;;;AEvDvD;;;ACAA;AAAA;AACA;AACA;AAYO,IAAM,cAAN,MAAkB;AAAA,EACN,yBAAyB;AAAA;AAAA;AAAA;AAAA,EAK1C,MAAc,iBAIX;AACD,UAAM,QAAQ,MAAM,eAAe,sBAAsB,MAAM;AAC/D,QAAI,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,MAAM,eAAe,CAAC,MAAM,aAAa;AACzE,YAAM,IAAI,UAAU,+BAA+B;AAAA,QACjD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAGA,QAAI,MAAM,aAAa,MAAM,YAAY,KAAK,IAAI,GAAG;AACnD,YAAM,IAAI,UAAU,yBAAyB;AAAA,QAC3C,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,aAAa,MAAM;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QAAW,UAAkB,SAAS,OAAO,MAA4B;AACrF,UAAM,EAAE,OAAO,UAAU,YAAY,IAAI,MAAM,KAAK,eAAe;AACnE,UAAM,OAAO,OAAO,KAAK,GAAG,KAAK,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAGlE,UAAM,UAAU,YAAY,WAAW,MAAM,IAAI,cAAc,WAAW,WAAW;AAErF,WAAO,MAAM,aAAa,MAAM,IAAI,QAAQ,EAAE;AAE9C,UAAM,UAAuC;AAAA,MAC3C;AAAA,MACA,SAAS;AAAA,QACP,eAAe,SAAS,IAAI;AAAA,QAC5B,gBAAgB;AAAA,QAChB,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,QAAI,MAAM;AACR,cAAQ,OAAO,KAAK,UAAU,IAAI;AAAA,IACpC;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,IAAI,OAAO;AAE7D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,aAAa,SAAS;AAC5B,YAAM,SAAS,SAAS;AAExB,UAAI,WAAW,KAAK;AAClB,cAAM,IAAI,UAAU,gCAAgC;AAAA,UAClD,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,UAAU,uCAAuC;AAAA,UACzD,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,UAAU,sBAAsB;AAAA,UACxC,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,UAAU,uBAAuB;AAAA,UACzC,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,YAAM,IAAI,UAAU,uBAAuB,UAAU,IAAI;AAAA,QACvD,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAsC;AAC1C,QAAI;AACF,YAAM,KAAK,QAAkB,oBAAoB;AAAA,IACnD,SAAS,OAAgB;AACvB,UAAI,iBAAiB,WAAW;AAC9B,cAAM;AAAA,MACR;AACA,YAAM,IAAI,UAAU,0CAA0C;AAAA,QAC5D,MAAM;AAAA,QACN,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACtE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAyC;AAC7C,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,QAAkB,oBAAoB;AAC9D,aAAO,KAAK;AAAA,IACd,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS,SAAyC;AACxD,UAAM,UAAoB,CAAC;AAG3B,YAAQ,KAAK,oCAAoC;AAGjD,QAAI,QAAQ,MAAM;AAChB,cAAQ,KAAK,eAAe,QAAQ,IAAI,GAAG;AAAA,IAC7C;AAGA,QAAI,QAAQ,QAAQ;AAClB,cAAQ,KAAK,cAAc,QAAQ,MAAM,GAAG;AAAA,IAC9C;AAGA,QAAI,QAAQ,KAAK;AACf,cAAQ,KAAK,IAAI,QAAQ,GAAG,GAAG;AAAA,IACjC;AAEA,WAAO,QAAQ,KAAK,OAAO;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,OAA0B;AACnD,UAAM,aAAqC;AAAA,MACzC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,YAAY;AAAA,IACd;AAEA,WAAO,WAAW,MAAM,OAAO,UAAU,IAAI,KAAK;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,UAAkC,CAAC,GAAyB;AAC1E,UAAM,MAAM,KAAK,SAAS,OAAO;AACjC,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,YAAyB,CAAC;AAChC,QAAI,UAAU;AACd,UAAM,aAAa;AAGnB,WAAO,MAAM;AACX,YAAM,WAAW,0BAA0B,mBAAmB,GAAG,CAAC,YAAY,OAAO,eAAe,UAAU,WAAW,OAAO,KAAK,GAAG,CAAC;AAEzI,YAAM,WAAW,MAAM,KAAK,QAA4B,QAAQ;AAEhE,gBAAU,KAAK,GAAG,SAAS,MAAM;AAEjC,aAAO;AAAA,QACL,WAAW,SAAS,OAAO,MAAM,mBAAmB,UAAU,MAAM,OAAO,SAAS,KAAK,IAAI,UAAU,aAAa,SAAS,QAAQ,4BAA4B,EAAE;AAAA,MACrK;AAGA,UAAI,UAAU,cAAc,SAAS,OAAO;AAC1C;AAAA,MACF;AAGA,UAAI,QAAQ,SAAS,UAAU,UAAU,QAAQ,OAAO;AACtD,eAAO,UAAU,MAAM,GAAG,QAAQ,KAAK,EAAE,IAAI,CAAC,UAAU,KAAK,uBAAuB,KAAK,CAAC;AAAA,MAC5F;AAEA,iBAAW;AAAA,IACb;AAEA,WAAO,UAAU,IAAI,CAAC,UAAU,KAAK,uBAAuB,KAAK,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBACJ,UAAkD,CAAC,GAC7B;AACtB,UAAM,QAAQ,MAAM,KAAK,eAAe;AACxC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,UAAU,4BAA4B;AAAA,IAClD;AAEA,WAAO,KAAK,UAAU;AAAA,MACpB,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB,OAAkB,aAAiC;AAExE,QAAI,UAAU,MAAM,OAAO;AAC3B,QAAI,MAAM,OAAO,aAAa;AAC5B,YAAM,gBAAgB,MAAM,OAAO,YAAY,UAAU,GAAG,KAAK,sBAAsB;AACvF,gBAAU,GAAG,MAAM,OAAO,OAAO;AAAA;AAAA,EAAO,aAAa;AAAA,IACvD;AAGA,UAAM,OAAO,MAAM,OAAO,kBAAkB,MAAM,OAAO;AAGzD,QAAI,UAAU;AACd,QAAI,aAAa;AACf,gBAAU,YAAY,WAAW,MAAM,IAAI,cAAc,WAAW,WAAW;AAAA,IACjF,OAAO;AACL,UAAI;AACF,cAAM,QAAQ,eAAe,sBAAsB,MAAM;AAGzD,YAAI,OAAO,aAAa;AACtB,oBAAU,MAAM,YAAY,WAAW,MAAM,IACzC,MAAM,cACN,WAAW,MAAM,WAAW;AAAA,QAClC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,MAAM,GAAG,OAAO,WAAW,MAAM,GAAG;AAE1C,WAAO;AAAA,MACL,KAAK,MAAM;AAAA,MACX;AAAA,MACA,QAAQ,MAAM,OAAO,QAAQ;AAAA,MAC7B,aAAa,MAAM,OAAO,QAAQ;AAAA,MAClC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,cAAc;AAAA,QACd,YAAY,KAAK,mBAAmB,KAAK;AAAA,QACzC,WAAW;AAAA,MACb;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,aAAa;AAAA,IACf;AAAA,EACF;AACF;AAEO,IAAM,cAAc,IAAI,YAAY;;;ADjSpC,IAAM,kBAA+B;AAAA,EAC1C,MAAM;AAAA,EAEN,MAAM,WAA0B;AAC9B,UAAM,YAAY,qBAAqB;AAAA,EACzC;AAAA,EAEA,MAAM,oBAKH;AACD,UAAM,OAAO,MAAM,YAAY,eAAe;AAE9C,UAAM,QAAQ,MACZ,YACA,eAAe;AAEjB,UAAM,WAAW,QAAQ;AACzB,UAAM,UAAU,MAAM,YAAY,WAAW,MAAM,IAC/C,MAAM,cACN,WAAW,MAAM,WAAW;AAEhC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,UAAU,GAAG,QAAQ;AAAA,MACrB,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAsD;AAEzE,UAAM,SAAS,QAAQ,WAAW,YAAY,MAAM,KAAK,eAAe,IAAI,QAAQ;AAEpF,WAAO,YAAY,UAAU;AAAA,MAC3B,MAAM,QAAQ;AAAA,MACd,OAAO,QAAQ;AAAA,MACf,QAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBAAoC;AACxC,QAAI;AACF,YAAM,KAAK,SAAS;AACpB,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,iBAAyC;AAC7C,WAAO,YAAY,eAAe;AAAA,EACpC;AACF;;;AE9DA;;;ACAA;AAAA;AACA;AACA;AAWO,IAAM,oBAAN,MAAwB;AAAA;AAAA;AAAA;AAAA,EAI7B,MAAc,iBAIX;AACD,UAAM,QAAQ,MAAM,eAAe,sBAAsB,YAAY;AACrE,QAAI,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,MAAM,eAAe,CAAC,MAAM,aAAa;AACzE,YAAM,IAAI,gBAAgB,qCAAqC;AAAA,QAC7D,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAGA,QAAI,MAAM,aAAa,MAAM,YAAY,KAAK,IAAI,GAAG;AACnD,YAAM,IAAI,gBAAgB,yBAAyB;AAAA,QACjD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,aAAa,MAAM;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QAAW,UAAkB,SAAS,OAAO,MAA4B;AACrF,UAAM,EAAE,OAAO,UAAU,YAAY,IAAI,MAAM,KAAK,eAAe;AACnE,UAAM,OAAO,OAAO,KAAK,GAAG,KAAK,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAGlE,UAAM,UAAU,YAAY,WAAW,MAAM,IAAI,cAAc,WAAW,WAAW;AAErF,WAAO,MAAM,mBAAmB,MAAM,IAAI,QAAQ,EAAE;AAEpD,UAAM,UAAuC;AAAA,MAC3C;AAAA,MACA,SAAS;AAAA,QACP,eAAe,SAAS,IAAI;AAAA,QAC5B,gBAAgB;AAAA,QAChB,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,QAAI,MAAM;AACR,cAAQ,OAAO,KAAK,UAAU,IAAI;AAAA,IACpC;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,IAAI,OAAO;AAE7D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,aAAa,SAAS;AAC5B,YAAM,SAAS,SAAS;AAExB,UAAI,WAAW,KAAK;AAClB,cAAM,IAAI,gBAAgB,gCAAgC;AAAA,UACxD,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,gBAAgB,uCAAuC;AAAA,UAC/D,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,gBAAgB,sBAAsB;AAAA,UAC9C,eAAe;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,WAAW,KAAK;AACzB,cAAM,IAAI,gBAAgB,uBAAuB;AAAA,UAC/C,MAAM;AAAA,UACN,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,YAAM,IAAI,gBAAgB,uBAAuB,UAAU,IAAI;AAAA,QAC7D,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,6BAA4C;AAChD,QAAI;AAEF,YAAM,KAAK,QAAkC,0CAA0C;AAAA,IACzF,SAAS,OAAgB;AACvB,UAAI,iBAAiB,iBAAiB;AACpC,cAAM;AAAA,MACR;AACA,YAAM,IAAI,gBAAgB,gDAAgD;AAAA,QACxE,MAAM;AAAA,QACN,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACtE,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAyC;AAC7C,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,eAAe;AACxC,aAAO,MAAM;AAAA,IACf,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS,SAA8C;AAC7D,UAAM,UAAoB,CAAC;AAG3B,YAAQ,KAAK,WAAW;AAGxB,QAAI,QAAQ,MAAM;AAChB,cAAQ,KAAK,yBAAyB,QAAQ,IAAI,KAAK;AAAA,IACzD;AAGA,QAAI,QAAQ,QAAQ;AAClB,cAAQ,KAAK,cAAc,QAAQ,MAAM,GAAG;AAAA,IAC9C;AAGA,QAAI,QAAQ,KAAK;AACf,cAAQ,KAAK,IAAI,QAAQ,GAAG,GAAG;AAAA,IACjC;AAEA,WAAO,QAAQ,KAAK,OAAO;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,MAA8B;AACrD,UAAM,UAAU,KAAK,MAAM,SAAS,SAAS;AAE7C,WAAO,KAAK,KAAK,QAAQ,SAAS,EAAE;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,UAAuC,CAAC,GAAyB;AAC9E,UAAM,MAAM,KAAK,SAAS,OAAO;AAEjC,UAAM,WAA6B,CAAC;AACpC,QAAI,QAAQ;AACZ,UAAM,QAAQ;AAGd,WAAO,MAAM;AACX,YAAM,SAAiC;AAAA,QACrC,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO,MAAM,SAAS;AAAA,QACtB,OAAO,MAAM,SAAS;AAAA,QACtB,QAAQ;AAAA,MACV;AAEA,UAAI,KAAK;AACP,eAAO,MAAM;AAAA,MACf;AAEA,YAAM,cAAc,OAAO,QAAQ,MAAM,EACtC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,KAAK,CAAC,EAAE,EAC/E,KAAK,GAAG;AAEX,YAAM,WAAW,0BAA0B,WAAW;AAEtD,YAAM,WAAW,MAAM,KAAK,QAAkC,QAAQ;AAEtE,eAAS,KAAK,GAAG,SAAS,OAAO;AAEjC,aAAO;AAAA,QACL,WAAW,SAAS,QAAQ,MAAM,kBAAkB,SAAS,MAAM,IAAI,SAAS,QAAQ,WAAW,QAAQ,4BAA4B,EAAE;AAAA,MAC3I;AAGA,UAAI,SAAS,QAAQ,SAAS,OAAO;AACnC;AAAA,MACF;AAGA,UAAI,QAAQ,SAAS,SAAS,UAAU,QAAQ,OAAO;AACrD,eAAO,SAAS,MAAM,GAAG,QAAQ,KAAK,EAAE,IAAI,CAAC,SAAS,KAAK,sBAAsB,IAAI,CAAC;AAAA,MACxF;AAEA,eAAS;AAAA,IACX;AAEA,WAAO,SAAS,IAAI,CAAC,SAAS,KAAK,sBAAsB,IAAI,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBACJ,UAAuD,CAAC,GAClC;AACtB,UAAM,QAAQ,MAAM,KAAK,eAAe;AACxC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,gBAAgB,4BAA4B;AAAA,IACxD;AAEA,WAAO,KAAK,SAAS;AAAA,MACnB,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,MAAsB,aAAiC;AAE3E,UAAM,UAAU,GAAG,KAAK,KAAK;AAAA;AAAA,oBAAyB,KAAK,QAAQ,MAAM;AAGzE,QAAI,UAAU;AACd,QAAI,aAAa;AACf,gBAAU,YAAY,WAAW,MAAM,IAAI,cAAc,WAAW,WAAW;AAAA,IACjF,OAAO;AACL,UAAI;AACF,cAAM,QAAQ,eAAe,sBAAsB,YAAY;AAG/D,YAAI,OAAO,aAAa;AACtB,oBAAU,MAAM,YAAY,WAAW,MAAM,IACzC,MAAM,cACN,WAAW,MAAM,WAAW;AAAA,QAClC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,OAAO,KAAK;AAE/C,WAAO;AAAA,MACL,KAAK,KAAK;AAAA,MACV;AAAA,MACA,QAAQ,KAAK,QAAQ,GAAG;AAAA,MACxB,aAAa,KAAK,QAAQ,GAAG;AAAA,MAC7B,MAAM,KAAK,QAAQ;AAAA,MACnB;AAAA,MACA,WAAW;AAAA,QACT,cAAc;AAAA,QACd,YAAY,KAAK,iBAAiB,IAAI;AAAA,QACtC,WAAW;AAAA,MACb;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,aAAa;AAAA,IACf;AAAA,EACF;AACF;AAEO,IAAM,oBAAoB,IAAI,kBAAkB;;;ADxRhD,IAAM,wBAAqC;AAAA,EAChD,MAAM;AAAA,EAEN,MAAM,WAA0B;AAC9B,UAAM,kBAAkB,2BAA2B;AAAA,EACrD;AAAA,EAEA,MAAM,oBAKH;AACD,UAAM,OAAO,MAAM,kBAAkB,eAAe;AAEpD,UAAM,QAAQ,MACZ,kBACA,eAAe;AAEjB,UAAM,WAAW,QAAQ;AACzB,UAAM,UAAU,MAAM,YAAY,WAAW,MAAM,IAC/C,MAAM,cACN,WAAW,MAAM,WAAW;AAEhC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,UAAU,GAAG,QAAQ;AAAA,MACrB,KAAK,GAAG,OAAO;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,SAAsD;AAEzE,UAAM,SAAS,QAAQ,WAAW,YAAY,MAAM,KAAK,eAAe,IAAI,QAAQ;AAEpF,WAAO,kBAAkB,SAAS;AAAA,MAChC,MAAM,QAAQ;AAAA,MACd,OAAO,QAAQ;AAAA,MACf,QAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBAAoC;AACxC,QAAI;AACF,YAAM,KAAK,SAAS;AACpB,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,iBAAyC;AAC7C,WAAO,kBAAkB,eAAe;AAAA,EAC1C;AACF;;;ARnDO,IAAM,iBAAN,MAAqB;AAAA;AAAA;AAAA;AAAA,EAI1B,OAAO,WAAW,QAAiC;AACjD,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,cAAM,IAAI,MAAM,wBAAwB,MAAM,EAAE;AAAA,IACpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,YAAY,QAA6B;AAC9C,WACE,WAAW,YACX,WAAW,eACX,WAAW,eACX,WAAW,YACX,WAAW,UACX,WAAW;AAAA,EAEf;AACF;;;AFrCA;;;AYTA;AACA;AADA,OAAOC,YAAW;;;ACAlB;AAGA;AACA;AAJA,OAAO,SAAS;AAChB,OAAOC,YAAW;AAClB,OAAOC,YAAW;AAQlB,eAAsB,cAA6B;AAEjD,SAAO,IAAI,EAAE;AACb,SAAO;AAAA,IACLD;AAAA,MACEC,OAAM,OAAO,KAAK,2BAAsB,IACtC;AAAA;AAAA,MACOA,OAAM,KAAK,MAAM,CAAC;AAAA,aACXA,OAAM,KAAK,qBAAqB,CAAC;AAAA;AAAA,IAC/CA,OAAM,IAAI,wCAAwC;AAAA,MACpD;AAAA,QACE,SAAS;AAAA,QACT,aAAa;AAAA,QACb,aAAa;AAAA,QACb,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AAEb,SAAO,KAAK,iCAAiC;AAC7C,SAAO,IAAI,EAAE;AAGb,QAAM,kBAAkB,MAAM,YAAY,gBAAgB;AAC1D,MAAI,iBAAiB;AACnB,UAAM,WAAW,YAAY,YAAY;AACzC,QAAI,UAAU;AACZ,aAAO;AAAA,QACLD;AAAA,UACE,GAAGC,OAAM,OAAO,wBAAwB,CAAC;AAAA;AAAA,EACpCA,OAAM,KAAK,OAAO,CAAC,IAAI,SAAS,IAAI;AAAA,EACpCA,OAAM,KAAK,QAAQ,CAAC,IAAI,SAAS,KAAK;AAAA;AAAA,EACtCA,OAAM,IAAI,KAAK,CAAC,IAAIA,OAAM,KAAK,iBAAiB,CAAC,IAAIA,OAAM,IAAI,aAAa,CAAC;AAAA,UAClF;AAAA,YACE,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AACb,iBAAW,WAAW,MAAM;AAC1B,gBAAQ,KAAK,CAAC;AAAA,MAChB,GAAG,GAAG;AACN;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,uCAAuC,EAAE,MAAM;AAEnE,MAAI;AAEF,YAAQ,OAAO;AACf,UAAM,WAAW,MAAM,YAAY,MAAM;AAEzC,YAAQ,QAAQ,4BAA4B;AAC5C,WAAO,IAAI,EAAE;AAGb,WAAO;AAAA,MACLD;AAAA,QACE,GAAGC,OAAM,MAAM,KAAK,oCAA+B,CAAC;AAAA;AAAA,EAC/CA,OAAM,KAAK,UAAU,CAAC,IAAIA,OAAM,KAAK,SAAS,IAAI,CAAC;AAAA,EACnDA,OAAM,KAAK,QAAQ,CAAC,IAAI,SAAS,KAAK;AAAA;AAAA,EACtCA,OAAM,IAAI,iBAAiB,CAAC,IAAIA,OAAM,KAAK,eAAe,CAAC,IAAIA,OAAM,IAAI,kBAAkB,CAAC;AAAA,QACjG;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AAIb,eAAW,WAAW,MAAM;AAC1B,cAAQ,KAAK,CAAC;AAAA,IAChB,GAAG,GAAG;AAGN;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,uBAAuB;AACpC,WAAO,IAAI,EAAE;AAEb,UAAM,MAAM;AAGZ,WAAO;AAAA,MACLD;AAAA,QACE,GAAGC,OAAM,IAAI,KAAK,8BAAyB,CAAC;AAAA;AAAA,EACvC,IAAI,OAAO;AAAA;AAAA,EACXA,OAAM,IAAI,OAAO,CAAC,IAAI,aAAa,GAAG,CAAC;AAAA,QAC5C;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,SAAS,aAAa,OAA8B;AAClD,MAAI,MAAM,SAAS,cAAc;AAC/B,QAAI,MAAM,QAAQ,SAAS,SAAS,GAAG;AACrC,aAAO;AAAA,IACT;AACA,QAAI,MAAM,QAAQ,SAAS,MAAM,GAAG;AAClC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,gBAAgB;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,uBAAuB;AACxC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AD5IA;;;AEHA;AAAA,SAAS,UAAU,SAAS,SAAAC,QAAO,QAAQ,cAAc;AACzD,OAAOC,YAAW;;;ACDlB;AAAA,OAAO,WAAW;AAClB,OAAO,kBAAkB;AAQlB,SAAS,mBAAmB,QAA2B;AAE5D,MAAI;AACJ,MAAI,OAAO,IAAI,WAAW,KAAK,GAAG;AAChC,UAAM,WAAW,OAAO,IAAI,QAAQ,OAAO,GAAG;AAC9C,iBAAa,OAAO,UAAU,QAAQ;AAAA,EACxC,OAAO;AACL,iBAAa,OAAO,UAAU,OAAO,IAAI,UAAU,GAAG,CAAC,CAAC;AAAA,EAC1D;AAEA,QAAM,QAAQ,OAAO,QAAQ,MAAM,IAAI;AACvC,QAAM,QAAQ,MAAM,CAAC;AAGrB,MAAI,cAAc;AAClB,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,KAAK;AAC3C,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,UAAU,KAAK,SAAS,KAAK,KAAK,UAAU,GAAG,EAAE,IAAI,QAAQ;AACnE,oBAAc;AAAA,MAAS,OAAO,QAAQ,OAAO,CAAC;AAAA,IAChD;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,KAAK,MAAM,OAAO,MAAM,EAAE;AAChD,QAAM,OAAO,OAAO,KAAK,IAAI,KAAK,OAAO,IAAI,EAAE,mBAAmB,CAAC;AAEnE,MAAI,QAAQ;AACZ,MAAI,gBAAgB;AACpB,MAAI,OAAO,WAAW;AACpB,UAAM,EAAE,cAAc,YAAY,UAAU,IAAI,OAAO;AACvD,oBAAgB,IAAI,iBAAiB,YAAY,SAAS,CAAC;AAC3D,YAAQ,OAAO,KAAK,KAAK,YAAY,WAAW,gBAAgB,YAAY,SAAS,CAAC,GAAG;AAAA,EAC3F;AAEA,SAAO,GAAG,UAAU,IAAI,KAAK,GAAG,aAAa,GAAG,KAAK;AAAA,MAAS,MAAM,WAAM,IAAI,GAAG,WAAW;AAC9F;AAKO,SAAS,0BACd,OACA,iBACQ;AACR,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB,MAAM;AAAA,MACJ,OAAO,QAAQ,KAAK;AAAA,MACpB,OAAO,QAAQ,UAAU;AAAA,MACzB,OAAO,QAAQ,eAAe;AAAA,MAC9B,OAAO,QAAQ,aAAa;AAAA,MAC5B,OAAO,QAAQ,MAAM;AAAA,IACvB;AAAA,IACA,WAAW,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE;AAAA,IAC9B,UAAU;AAAA,IACV,OAAO,YAAY,QAAQ;AAAA,EAC7B,CAAC;AAED,QAAM,QAAQ,CAAC,MAAM,UAAU;AAE7B,UAAM,gBAAgB,EAAE,SAAS;AAGjC,QAAI,aAAqB,IAAI,QAAQ,CAAC;AACtC,QAAI,iBAAiB,iBAAiB;AACpC,YAAM,SAAS,gBAAgB,KAAK;AACpC,UAAI,UAAU,OAAO,IAAI,WAAW,KAAK,GAAG;AAC1C,qBAAa,OAAO,IAAI,QAAQ,OAAO,GAAG;AAAA,MAC5C,WAAW,QAAQ;AACjB,qBAAa,OAAO,IAAI,UAAU,GAAG,CAAC;AAAA,MACxC;AAAA,IACF,WAAW,CAAC,eAAe;AACzB,YAAM,SAAS;AACf,UAAI,OAAO,IAAI,WAAW,KAAK,GAAG;AAChC,qBAAa,OAAO,IAAI,QAAQ,OAAO,GAAG;AAAA,MAC5C,OAAO;AACL,qBAAa,OAAO,IAAI,UAAU,GAAG,CAAC;AAAA,MACxC;AAAA,IACF,OAAO;AACL,mBAAa,IAAI,QAAQ,CAAC;AAAA,IAC5B;AAGA,UAAM,WAAW,gBACb,OAAQ,KAAqB,mBAAmB,WAC7C,KAAqB,eAAe,MAAM,IAAI,EAAE,CAAC,KAAK,KACvD,cACD,KAAuB,iBAAiB,MAAM,IAAI,EAAE,CAAC,KAAK;AAE/D,UAAM,QAAQ,KAAK;AACnB,UAAM,cACJ,KAAK,oBAAoB,SAAS,MAC9B,KAAK,oBAAoB,UAAU,GAAG,EAAE,IAAI,QAC5C,KAAK;AACX,UAAM,QAAQ,KAAK,kBAAkB,CAAC,GAAG,KAAK,IAAI,KAAK;AAGvD,UAAM,SAAS,OAAO,QAAQ,GAAG,QAAQ,CAAC,GAAG;AAE7C,UAAM,KAAK;AAAA,MACT,GAAG,MAAM,IAAI,OAAO,UAAU,UAAU,CAAC;AAAA,MACzC,OAAO,KAAK,QAAQ;AAAA,MACpB,OAAO,MAAM,KAAK;AAAA,MAClB,OAAO,IAAI,WAAW;AAAA,MACtB,OAAO,QAAQ,IAAI;AAAA,IACrB,CAAC;AAAA,EACH,CAAC;AAED,SAAO,MAAM,SAAS;AACxB;AAKO,SAAS,kBAAkB,SAA8B;AAC9D,QAAM,aAAa,QAAQ,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,WAAW,gBAAgB,IAAI,CAAC;AACvF,QAAM,kBAAkB,QAAQ,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,WAAW,cAAc,IAAI,CAAC;AAC1F,QAAM,iBAAiB,QAAQ,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,WAAW,aAAa,IAAI,CAAC;AAExF,SACE,OAAO,KAAK,iBAAiB,IAC7B,OAAO,MAAM,GAAG,UAAU,QAAQ,IAClC,OAAO,KAAK,IAAI,IAChB,gBAAgB,iBAAiB,cAAc;AAEnD;AAKO,SAAS,uBAAuB,OAAe,SAA8B;AAClF,QAAM,aAAa,QAAQ,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,WAAW,gBAAgB,IAAI,CAAC;AACvF,QAAM,kBAAkB,QAAQ,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,WAAW,cAAc,IAAI,CAAC;AAC1F,QAAM,iBAAiB,QAAQ,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,WAAW,aAAa,IAAI,CAAC;AAExF,QAAM,eAAe,MAAM,QAAQ,YAAY,MAAM,MAAM,KAAK,CAAC,MAAM,QAAQ,IAAI,MAAM,EAAE,EAAE;AAC7F,QAAM,QAAQ,GAAG,MAAM,MAAM,UAAU,CAAC,mBAAmB,gBAAgB,iBAAiB,cAAc,CAAC;AAE3G,SAAO;AAAA,EAAK,YAAY,KAAK,KAAK;AACpC;AAKO,SAAS,qBAAqB,OAAuB;AAC1D,QAAM,QAAQ;AACd,QAAM,QAAQ,OAAO;AAAA,IACnB,GAAG,KAAK,yBAAyB,KAAK,QAAQ,QAAQ,IAAI,MAAM,EAAE;AAAA,EACpE;AACA,QAAM,UAAU,OAAO,MAAM,0DAA0D;AACvF,QAAM,OACJ,MAAM,UAAU,QAAQ,IACxB,MAAM,QAAQ,eAAe,IAC7B,MAAM,UAAU,wBAAwB;AAO1C,QAAM,MAAM;AACZ,QAAM,eAAe,aAAa,KAAK,KAAK;AAAA,IAC1C,UAAU,MAAM,OAAO,QAAQ,GAAG;AAAA,EACpC,CAAC;AACD,QAAM,SACJ,MAAM,UAAU,gBAAgB,IAAI,eAAe,MAAM,UAAU,wBAAwB;AAE7F,SAAO,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM;AAC3C;AAKO,SAAS,mBAAmB,SAAiB,MAAuB;AACzE,QAAM,QAAQ,OAAO,UAAU,cAAS;AACxC,QAAM,QAAQ,OAAO,MAAM,OAAO;AAClC,QAAM,WAAW,OAAO,MAAM,UAAU,YAAY,IAAI,MAAM,QAAQ,IAAI,IAAI;AAE9E,SAAO,GAAG,KAAK;AAAA;AAAA,EAAO,KAAK,GAAG,QAAQ;AACxC;;;ADjLA,eAAsB,oBAAoB,SAAyC;AACjF,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,QAAQ,IAAI,CAAC,YAAY;AAAA,IACvC,MAAM,mBAAmB,MAAM;AAAA,IAC/B,OAAO,OAAO;AAAA,IACd,SAAS;AAAA,EACX,EAAE;AAEF,QAAM,WAAW,MAAM,SAAS;AAAA,IAC9B,SAAS;AAAA,IACT;AAAA,IACA,UAAU;AAAA,IACV,MAAM;AAAA,EACR,CAAC;AAED,SAAO;AACT;AAKA,eAAsB,cACpB,SACA,eAAwB,MACN;AAClB,SAAO,MAAM,QAAQ;AAAA,IACnB;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;AA4BA,eAAsB,iBAAiB,cAAsB,IAAqB;AAChF,QAAM,UAAU;AAAA,IACd,EAAE,MAAM,UAAU,OAAO,KAAK,aAAa,YAAY;AAAA,IACvD,EAAE,MAAM,yBAAyB,OAAO,MAAM,aAAa,aAAa;AAAA,IACxE,EAAE,MAAM,WAAW,OAAO,MAAM,aAAa,gBAAgB;AAAA,IAC7D,EAAE,MAAM,WAAW,OAAO,MAAM,aAAa,gBAAgB;AAAA,IAC7D,EAAE,MAAM,UAAU,OAAO,UAAU,aAAa,8BAA8B;AAAA,EAChF;AAEA,QAAM,WAAW,MAAM,OAAO;AAAA,IAC5B,SAAS;AAAA,IACT;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AAED,MAAI,aAAa,UAAU;AACzB,UAAM,aAAa,MAAMC,OAAM;AAAA,MAC7B,SAAS;AAAA,MACT,SAAS,YAAY,SAAS;AAAA,MAC9B,UAAU,CAAC,UAAU;AACnB,cAAM,MAAM,SAAS,OAAO,EAAE;AAC9B,YAAI,MAAM,GAAG,KAAK,OAAO,GAAG;AAC1B,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AACD,WAAO,SAAS,YAAY,EAAE;AAAA,EAChC;AAEA,SAAO,SAAS,UAAU,EAAE;AAC9B;AAKA,eAAsB,mBAAgE;AACpF,QAAM,UAAU;AAAA,IACd;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAAA,IACA,EAAE,MAAM,2BAA2B,OAAO,QAAiB,aAAa,qBAAqB;AAAA,IAC7F,EAAE,MAAM,yBAAyB,OAAO,SAAkB,aAAa,qBAAqB;AAAA,IAC5F,EAAE,MAAM,cAAc,OAAO,QAAiB,aAAa,sBAAsB;AAAA,EACnF;AAEA,SAAO,MAAM,OAAO;AAAA,IAClB,SAAS;AAAA,IACT;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;AAKA,eAAsB,yBACpB,eACwB;AACxB,QAAM,UAAU;AAAA,IACd,EAAE,MAAM,cAAc,OAAO,OAAgB;AAAA,IAC7C,GAAG,cAAc,IAAI,CAAC,SAAS;AAAA,MAC7B,MAAM,IAAI;AAAA,MACV,OAAO,IAAI;AAAA,IACb,EAAE;AAAA,EACJ;AAEA,QAAM,WAAW,MAAM,OAAO;AAAA,IAC5B,SAAS;AAAA,IACT;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AAED,SAAO,aAAa,SAAS,OAAO;AACtC;AAKA,eAAsB,kBACpB,cACA,iBAC0C;AAC1C,QAAM,gBAAiD,CAAC;AAExD,UAAQ,IAAI,OAAO,MAAM,KAAK,mCAAmC,IAAI,IAAI;AAEzE,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,QAAI,cAAc,aAAa,CAAC;AAChC,UAAM,UAAU,IAAI;AACpB,UAAM,QAAQ,aAAa;AAC3B,QAAI,gBAAgB;AAGpB,WAAO,eAAe;AAEpB,YAAM,gBAAgB,EAAE,SAAS;AAGjC,UAAI,aAAqB,IAAI,IAAI,CAAC;AAClC,UAAI;AAEJ,UAAI,iBAAiB,iBAAiB;AACpC,cAAM,SAAS,gBAAgB,CAAC;AAChC,YAAI,QAAQ;AACV,uBAAa,OAAO,IAAI,WAAW,KAAK,IACpC,OAAO,IAAI,QAAQ,OAAO,GAAG,IAC7B,OAAO,IAAI,UAAU,GAAG,CAAC;AAC7B,kBAAQ,OAAO;AAAA,QACjB;AAAA,MACF,WAAW,CAAC,eAAe;AACzB,cAAM,SAAS;AACf,qBAAa,OAAO,IAAI,WAAW,KAAK,IACpC,OAAO,IAAI,QAAQ,OAAO,GAAG,IAC7B,OAAO,IAAI,UAAU,GAAG,CAAC;AAC7B,gBAAQ,OAAO;AAAA,MACjB,OAAO;AACL,qBAAa,IAAI,IAAI,CAAC;AAAA,MACxB;AAGA,YAAM,cAAc,gBACf,YAA4B,uBAAuB,SAAS,KAAK,QACjE,YAA8B,cAAc,SAAS,KAAK;AAE/D,UAAI,cACF,GAAG,MAAM,KAAK,SAAS,KAAK,CAAC,IAAI,OAAO,UAAU,UAAU,CAAC;AAAA;AAAA,EAC1D,MAAM,MAAM,OAAO,CAAC,IAAI,OAAO,MAAM,YAAY,aAAa,CAAC;AAAA;AAAA,EAC/D,MAAM,MAAM,aAAa,CAAC;AAAA,EAAK,OAAO,MAAM,YAAY,mBAAmB,CAAC;AAAA;AAAA,EAC5E,MAAM,MAAM,MAAM,CAAC,IAAI,OAAO,SAAS,YAAY,kBAAkB,CAAC,GAAG,KAAK,IAAI,KAAK,MAAM,CAAC;AAAA;AAAA,EAC9F,MAAM,MAAM,cAAc,CAAC,IAAI,OAAO,UAAU,WAAW,CAAC;AAGjE,UAAI,OAAO;AACT,uBAAe;AAAA;AAAA,EAAO,MAAM,MAAM,SAAS,CAAC,IAAI,OAAO,KAAK,KAAK,CAAC;AAAA,MACpE;AAEA,cAAQ,IAAIC,OAAM,aAAa,UAAU,IAAI,CAAC;AAC9C,cAAQ,IAAI,EAAE;AAGd,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,MAAM,iBAAY,OAAO,UAAU,aAAa,sBAAsB;AAAA,UACxE,EAAE,MAAM,qBAAgB,OAAO,cAAc,aAAa,mBAAmB;AAAA,UAC7E;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,aAAa;AAAA,UACf;AAAA,UACA,EAAE,MAAM,oBAAe,OAAO,aAAa,aAAa,+BAA+B;AAAA,UACvF,EAAE,MAAM,eAAU,OAAO,QAAQ,aAAa,iBAAiB;AAAA,UAC/D,GAAI,UAAU,QACV;AAAA,YACE;AAAA,cACE,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACf;AAAA,UACF,IACA,CAAC;AAAA,UACL,EAAE,MAAM,iBAAY,OAAO,UAAU,aAAa,+BAA+B;AAAA,QACnF;AAAA,MACF,CAAC;AAED,UAAI,WAAW,UAAU;AACvB,eAAO,CAAC;AAAA,MACV;AAEA,UAAI,WAAW,cAAc;AAC3B,sBAAc,KAAK,WAAW;AAE9B,iBAAS,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAChD,wBAAc,KAAK,aAAa,CAAC,CAAC;AAAA,QACpC;AACA,wBAAgB;AAEhB,YAAI,aAAa,SAAS;AAC1B;AAAA,MACF;AAEA,UAAI,WAAW,QAAQ;AACrB,wBAAgB;AAChB;AAAA,MACF;AAEA,UAAI,WAAW,UAAU;AACvB,sBAAc,KAAK,WAAW;AAC9B,wBAAgB;AAChB;AAAA,MACF;AAGA,UAAI,aAAa,EAAE,GAAG,YAAY;AAElC,UAAI,WAAW,gBAAgB,WAAW,aAAa;AACrD,gBAAQ,IAAI,EAAE;AACd,cAAM,WAAW,MAAMD,OAAM;AAAA,UAC3B,SAAS;AAAA,UACT,SAAS,YAAY;AAAA,QACvB,CAAC;AACD,mBAAW,gBAAgB;AAAA,MAC7B;AAEA,UAAI,WAAW,eAAe,WAAW,aAAa;AACpD,gBAAQ,IAAI,EAAE;AACd,cAAM,UAAU,MAAM,OAAO;AAAA,UAC3B,SAAS;AAAA,UACT,SAAS,YAAY;AAAA,QACvB,CAAC;AACD,mBAAW,sBAAsB;AAAA,MACnC;AAGA,oBAAc;AACd,cAAQ,IAAI,OAAO,MAAM,QAAQ,0CAAqC,IAAI,IAAI;AAAA,IAChF;AAAA,EACF;AAEA,SAAO;AACT;;;AF1RA,eAAsB,sBAAwC;AAC5D,QAAM,kBAAkB,MAAM,YAAY,gBAAgB;AAE1D,MAAI,iBAAiB;AACnB,WAAO;AAAA,EACT;AAGA,SAAO,IAAI,EAAE;AACb,SAAO;AAAA,IACLE;AAAA,MACE,MAAM,QAAQ,mBAAmB,IAC/B;AAAA,MAGF,UAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AAEb,QAAM,aAAa,MAAM,cAAc,qBAAqB,IAAI;AAEhE,MAAI,CAAC,YAAY;AACf,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL,MAAM,UAAU,8BAA8B,IAC5C,MAAM,QAAQ,qBAAqB,IACnC,MAAM,UAAU,qCAAqC;AAAA,IACzD;AACA,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,EACT;AAGA,MAAI;AACF,UAAM,YAAY;AAClB,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;;;AIpDA;AAAA,OAAOC,UAAkB;AAMlB,SAAS,cAAc,MAAmB;AAC/C,SAAOC,KAAI;AAAA,IACT;AAAA,IACA,OAAO;AAAA,IACP,SAAS;AAAA,EACX,CAAC;AACH;AAKO,SAAS,kBAAkB,aAAqB,YAAoB,MAAmB;AAC5F,QAAM,gBAAgB,MAAM,KAAK,aAAa,UAAU;AACxD,SAAOA,KAAI;AAAA,IACT,MAAM,GAAG,aAAa,IAAI,IAAI;AAAA,IAC9B,OAAO;AAAA,IACP,SAAS;AAAA,EACX,CAAC;AACH;AA8CO,SAAS,uBAA4B;AAC1C,SAAO,cAAc,wBAAwB;AAC/C;AAYO,SAAS,eAAe,SAAc,MAAqB;AAChE,MAAI,MAAM;AACR,YAAQ,QAAQ,OAAO,QAAQ,IAAI,CAAC;AAAA,EACtC,OAAO;AACL,YAAQ,QAAQ;AAAA,EAClB;AACF;AAKO,SAAS,YAAY,SAAc,MAAqB;AAC7D,MAAI,MAAM;AACR,YAAQ,KAAK,OAAO,MAAM,IAAI,CAAC;AAAA,EACjC,OAAO;AACL,YAAQ,KAAK;AAAA,EACf;AACF;AAgBO,SAAS,mBACd,SACA,aACA,YACA,MACM;AACN,QAAM,gBAAgB,MAAM,KAAK,aAAa,UAAU;AACxD,UAAQ,QAAQ,GAAG,aAAa,IAAI,OAAO,QAAQ,IAAI,CAAC,EAAE;AAC5D;AAKO,SAAS,gBACd,SACA,aACA,YACA,MACM;AACN,QAAM,gBAAgB,MAAM,KAAK,aAAa,UAAU;AACxD,UAAQ,KAAK,GAAG,aAAa,IAAI,OAAO,MAAM,IAAI,CAAC,EAAE;AACvD;;;AhBvFA,eAAe,sBAAmD;AAEhE,QAAM,cAA4B;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,wBAAwB,MAAM,eAAe,yBAAyB;AAG5E,QAAM,4BAA4B,sBAAsB;AAAA,IACtD,CAAC,YACC,YAAY,cAAc,YAAY,SAAS,OAAqB;AAAA,EACxE;AAGA,QAAM,iBAAiB,MAAM,QAAQ;AAAA,IACnC,YAAY,IAAI,OAAO,YAAY;AACjC,YAAM,SAAS,MAAM,eAAe,uBAAuB,OAAO;AAClE,YAAM,YAAY,SAAS,WAAM;AACjC,YAAM,eAAe,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AAEtE,aAAO;AAAA,QACL,MAAM,GAAG,SAAS,IAAI,YAAY;AAAA,QAClC,OAAO;AAAA,QACP,aAAa,SAAS,kBAAkB;AAAA,MAC1C;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,0BAA0B,SAAS,GAAG;AACxC,UAAM,eAAe,0BAClB,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EACjD,KAAK,IAAI;AAEZ,mBAAe,KAAK;AAAA,MAClB,MAAM,sCAAiC,YAAY;AAAA,MACnD,OAAO;AAAA,MACP,aAAa,YAAY,0BAA0B,MAAM,yBAAyB,0BAA0B,SAAS,IAAI,MAAM,EAAE;AAAA,IACnI,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,MAAMC,QAAO;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,SAAO;AACT;AAKA,eAAe,kBACb,YACA,SACA,aACqB;AAErB,QAAM,UAAU,eAAe,WAAW,UAAU;AACpD,QAAM,cAAc,kBAAkB,GAAG,aAAa,uBAAuB;AAC7E,cAAY,MAAM;AAElB,QAAM,QAAQ,SAAS;AACvB,QAAM,WAAW,MAAM,QAAQ,kBAAkB;AAEjD,qBAAmB,aAAa,GAAG,aAAa,eAAe,MAAM,MAAM,SAAS,QAAQ,CAAC,EAAE;AAC/F,SAAO,IAAI,EAAE;AAGb,MAAI,OAAO,QAAQ;AACnB,MAAI,CAAC,MAAM;AACT,UAAM,cAAc,eAAe,UAAU,mBAAmB;AAChE,WAAO,MAAM,iBAAiB,WAAW;AACzC,WAAO,IAAI,EAAE;AAAA,EACf;AAGA,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA,qCAAqC,IAAI;AAAA,EAC3C;AACA,eAAa,MAAM;AAEnB,QAAM,YAAY,MAAM,QAAQ,eAAe;AAAA,IAC7C;AAAA,IACA,QAAQ,QAAQ,MAAM,SAAa,MAAM,QAAQ,eAAe,KAAM;AAAA,EACxE,CAAC;AAED,MAAI,UAAU,WAAW,GAAG;AAC1B,oBAAgB,cAAc,GAAG,aAAa,mCAAmC,IAAI,OAAO;AAC5F,WAAO,IAAI,EAAE;AACb,WAAO,KAAK,0DAA0D;AACtE,WAAO,EAAE,SAAS,GAAG,SAAS,EAAE;AAAA,EAClC;AAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,MAAM,MAAM,UAAU,MAAM,CAAC,aAAa,UAAU,SAAS,IAAI,MAAM,EAAE;AAAA,EACpF;AACA,SAAO,IAAI,EAAE;AAGb,SAAO,IAAI,kBAAkB,SAAS,CAAC;AACvC,SAAO,IAAI,EAAE;AAGb,MAAI,gBAAgB,CAAC,GAAG,SAAS;AACjC,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,aAAa,MAAM,iBAAiB;AAC1C,WAAO,IAAI,EAAE;AAGb,QAAI,eAAe,QAAQ;AACzB,oBAAc,KAAK,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,IAAI,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC;AAAA,IACtF,WAAW,eAAe,QAAQ;AAChC,oBAAc,KAAK,CAAC,GAAG,MAAM;AAC3B,cAAM,SAAS,EAAE,WAAW,cAAc,MAAM,EAAE,WAAW,aAAa;AAC1E,cAAM,SAAS,EAAE,WAAW,cAAc,MAAM,EAAE,WAAW,aAAa;AAC1E,eAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH,WAAW,eAAe,SAAS;AACjC,oBAAc,KAAK,CAAC,GAAG,MAAM;AAC3B,cAAM,SAAS,EAAE,WAAW,gBAAgB;AAC5C,cAAM,SAAS,EAAE,WAAW,gBAAgB;AAC5C,eAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,oBAAoB,aAAa;AAE5D,MAAI,aAAa,WAAW,GAAG;AAC7B,WAAO,IAAI,EAAE;AACb,WAAO,KAAK,MAAM,UAAU,yCAAyC,CAAC;AACtE,WAAO,IAAI,EAAE;AACb,WAAO,EAAE,SAAS,GAAG,SAAS,EAAE;AAAA,EAClC;AAEA,QAAM,kBAAkB,cAAc,OAAO,CAAC,MAAM,aAAa,SAAS,EAAE,GAAG,CAAC;AAGhF,SAAO,IAAI,uBAAuB,gBAAgB,QAAQ,eAAe,CAAC;AAC1E,SAAO,IAAI,EAAE;AAGb,QAAM,gBAAgB,MAAM,WAAW,UAAU,EAAE,OAAO,IAAI,CAAC;AAC/D,SAAO,MAAM,WAAW,cAAc,MAAM,MAAM,iBAAiB;AAEnE,QAAM,eAAe,IAAI,IAAI,cAAc,MAAM,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;AACpF,SAAO,MAAM,iCAAiC,aAAa,IAAI,EAAE;AAEjE,QAAM,aAAa,gBAAgB,OAAO,CAAC,MAAM,EAAE,OAAO,aAAa,IAAI,EAAE,GAAG,CAAC;AACjF,QAAM,aAAa,gBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE,GAAG,CAAC;AAEnF,SAAO,MAAM,eAAe,WAAW,MAAM,UAAU,WAAW,MAAM,EAAE;AAE1E,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL,OAAO;AAAA,QACL,GAAG,WAAW,MAAM,aAAa,WAAW,SAAS,IAAI,MAAM,EAAE;AAAA,MACnE;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AAAA,EACf;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACL,MAAM,UAAU,uEAAuE;AAAA,IACzF;AACA,WAAO,IAAI,EAAE;AACb,WAAO,EAAE,SAAS,GAAG,SAAS,WAAW,OAAO;AAAA,EAClD;AAGA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA;AAAA,IACA,YAAY,MAAM,MAAM,WAAW,MAAM,CAAC,aAAa,WAAW,SAAS,IAAI,MAAM,EAAE;AAAA,EACzF;AACA,gBAAc,MAAM;AAEpB,QAAM,gBAAgB;AAAA,IACpB,OAAO,WAAW,IAAI,CAAC,OAAO;AAAA,MAC5B,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,OAAO,EAAE,QAAQ,MAAM,IAAI,EAAE,CAAC;AAAA,IAChC,EAAE;AAAA,EACJ;AAEA,QAAM,iBAAiB,MAAM,WAAW,YAAY,aAAa;AACjE,MAAI,eAAe,eAAe;AAElC,qBAAmB,eAAe,GAAG,aAAa,iCAAiC;AACnF,SAAO,IAAI,EAAE;AAGb,SAAO,KAAK,2BAA2B;AACvC,SAAO,IAAI,EAAE;AACb,SAAO,IAAI,0BAA0B,cAAc,UAAU,CAAC;AAC9D,SAAO,IAAI,EAAE;AAEb,QAAM,gBAAgB,MAAM,kBAAkB,cAAc,UAAU;AAEtE,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO,IAAI,EAAE;AACb,WAAO,KAAK,MAAM,UAAU,iDAAiD,CAAC;AAC9E,WAAO,IAAI,EAAE;AACb,WAAO,EAAE,SAAS,GAAG,SAAS,WAAW,OAAO;AAAA,EAClD;AAEA,SAAO,IAAI,EAAE;AAGb,MAAI,gBAA+B;AACnC,QAAM,WAAW,YAAY,YAAY;AACzC,MAAI,UAAU,IAAI;AAChB,QAAI;AACF,YAAM,eAAe,MAAM,WAAW,sBAAsB,SAAS,EAAE;AACvE,UAAI,aAAa,MAAM,SAAS,GAAG;AACjC,wBAAgB,MAAM,yBAAyB,aAAa,KAAK;AACjE,eAAO,IAAI,EAAE;AAAA,MACf;AAAA,IACF,QAAQ;AACN,aAAO,MAAM,uDAAuD;AAAA,IACtE;AAAA,EACF;AAGA,QAAMC,iBAAgB;AAAA,IACpB;AAAA,IACA;AAAA,IACA,YAAY,MAAM,MAAM,cAAc,MAAM,CAAC,QAAQ,cAAc,SAAS,IAAI,MAAM,EAAE;AAAA,EAC1F;AACA,EAAAA,eAAc,MAAM;AAEpB,QAAM,gBAAgB;AAAA,IACpB,OAAO,cAAc,IAAI,CAAC,SAAsB,UAAkC;AAChF,YAAM,iBAAiB,WAAW,KAAK;AACvC,aAAO;AAAA,QACL,YAAY,gBAAgB,OAAO,QAAQ,KAAK;AAAA,QAChD,OAAO,QAAQ;AAAA,QACf,aAAa,QAAQ;AAAA,QACrB,MAAM,QAAQ;AAAA,QACd,YAAY,SAAS;AAAA,QACrB,MAAM,gBAAgB,QAAQ;AAAA,QAC9B,YAAY,gBAAgB,OAAO;AAAA,QACnC,cAAc,QAAQ;AAAA,QACtB,oBAAoB,QAAQ;AAAA,QAC5B,aAAa,gBAAgB,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC;AAAA,QAC3D,OAAO,iBAAiB;AAAA;AAAA,QAExB,YAAY,gBAAgB;AAAA,QAC5B,cAAc,gBAAgB;AAAA,QAC9B,gBAAgB,gBAAgB;AAAA,QAChC,aAAa,gBAAgB;AAAA,MAC/B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,iBAAiB,MAAM,WAAW,YAAY,aAAa;AAEjE;AAAA,IACEA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,MAAM,MAAM,eAAe,OAAO,CAAC,QAAQ,eAAe,UAAU,IAAI,MAAM,EAAE;AAAA,EAC7F;AACA,SAAO,IAAI,EAAE;AAEb,SAAO,EAAE,SAAS,eAAe,SAAS,SAAS,WAAW,OAAO;AACvE;AAKA,eAAe,6BAA6B,SAA4C;AACtF,QAAM,cAAc;AACpB,QAAM,cAA4B;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,wBAAwB,MAAM,eAAe,yBAAyB;AAG5E,QAAM,iBAAiB,sBAAsB;AAAA,IAC3C,CAAC,YACC,YAAY,cAAc,YAAY,SAAS,OAAqB;AAAA,EACxE;AAEA,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO,IAAI,EAAE;AACb,WAAO,MAAM,kCAAkC;AAC/C,WAAO,IAAI,EAAE;AACb,WAAO,KAAK,+BAA+B;AAC3C,WAAO,KAAK,KAAK,MAAM,QAAQ,sBAAsB,CAAC,EAAE;AACxD,WAAO,KAAK,KAAK,MAAM,QAAQ,yBAAyB,CAAC,EAAE;AAC3D;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,WAAW,eAAe,MAAM,yBAAyB,eAAe,SAAS,IAAI,MAAM,EAAE;AAAA,IAC/F;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AAEb,QAAM,UACJ,CAAC;AAGH,WAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,UAAM,UAAU,eAAe,CAAC;AAChC,UAAM,eAAe,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AAEtE,WAAO;AAAA,MACL,OAAO,UAAU,8BAAe,IAAI,CAAC,IAAI,eAAe,MAAM,KAAK,YAAY,qBAAM;AAAA,IACvF;AACA,WAAO,IAAI,EAAE;AAEb,QAAI;AACF,YAAM,SAAS,MAAM,kBAAkB,SAAS,SAAS,WAAW;AACpE,cAAQ,KAAK,EAAE,SAAS,SAAS,OAAO,SAAS,SAAS,OAAO,QAAQ,CAAC;AAC1E,aAAO,IAAI,EAAE;AAAA,IACf,SAAS,OAAO;AACd,YAAM,MAAM;AACZ,aAAO,IAAI,EAAE;AACb,aAAO,KAAK,kBAAkB,YAAY,KAAK,IAAI,OAAO,EAAE;AAC5D,aAAO,IAAI,EAAE;AACb,cAAQ,KAAK,EAAE,SAAS,SAAS,GAAG,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;AAAA,IACtE;AAAA,EACF;AAGA,SAAO,IAAI,EAAE;AACb,SAAO,IAAI,OAAO,UAAU,oDAAsB,CAAC;AACnD,SAAO,IAAI,EAAE;AAEb,QAAM,aAAa,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK;AACjD,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,KAAK;AAC5C,QAAM,eAAe,WAAW,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,SAAS,CAAC;AAErE,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,8BAAyB,WAAW,MAAM,IAAI,eAAe,MAAM,WAAW,eAAe,SAAS,IAAI,MAAM,EAAE;AAAA,MACpH;AAAA,IACF;AACA,eAAW,UAAU,YAAY;AAC/B,YAAM,eAAe,OAAO,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,QAAQ,MAAM,CAAC;AACpF,aAAO;AAAA,QACL,YAAO,YAAY,KAAK,OAAO,OAAO,QAAQ,OAAO,YAAY,IAAI,MAAM,EAAE,WAAW,OAAO,UAAU,IAAI,KAAK,OAAO,OAAO,aAAa,EAAE;AAAA,MACjJ;AAAA,IACF;AACA,WAAO,IAAI,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO;AAAA,MACL,OAAO,QAAQ,yBAAoB,OAAO,MAAM,WAAW,OAAO,SAAS,IAAI,MAAM,EAAE,GAAG;AAAA,IAC5F;AACA,eAAW,UAAU,QAAQ;AAC3B,YAAM,eAAe,OAAO,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,QAAQ,MAAM,CAAC;AACpF,aAAO,KAAK,YAAO,YAAY,KAAK,OAAO,KAAK,EAAE;AAAA,IACpD;AACA,WAAO,IAAI,EAAE;AAAA,EACf;AAEA,MAAI,eAAe,GAAG;AACpB,WAAO,IAAIC,OAAM,qBAAqB,YAAY,GAAG,UAAU,OAAO,CAAC;AAAA,EACzE,WAAW,WAAW,SAAS,GAAG;AAChC,WAAO;AAAA,MACLA;AAAA,QACE,MAAM,UAAU,gEAAgE;AAAA,QAChF,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAsB,YAAY,UAA8B,CAAC,GAAkB;AACjF,SAAO,IAAI,EAAE;AAEb,QAAM,cAAc;AACpB,MAAI;AAEJ,MAAI;AAEF,UAAM,kBAAkB,MAAM,oBAAoB;AAClD,QAAI,CAAC,iBAAiB;AACpB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,WAAO,MAAM,iCAAiC;AAC9C,UAAM,qBAAqB,MAAM,WAAW,sBAAsB;AAElE,WAAO,MAAM,iCAAiC,KAAK,UAAU,oBAAoB,MAAM,CAAC,CAAC;AAEzF,QAAI,mBAAmB,SAAS,QAAQ;AACtC,aAAO,MAAM,4CAA4C;AACzD,aAAO,IAAI,EAAE;AACb,aAAO;AAAA,QACLA;AAAA,UACE,MAAM,QAAQ,kCAAkC,IAC9C,wMAMA,OAAO,UAAU,6BAA6B;AAAA,UAChD;AAAA,YACE,GAAG,UAAU;AAAA,YACb,SAAS;AAAA,YACT,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAEA,WAAO,MAAM,sBAAsB,mBAAmB,IAAI,0BAA0B;AAGpF,QAAI;AAEJ,QAAI,QAAQ,QAAQ;AAElB,mBAAa,QAAQ;AAGrB,UAAI,CAAC,eAAe,YAAY,UAAU,GAAG;AAC3C,eAAO,IAAI,EAAE;AACb,eAAO,MAAM,uBAAuB,QAAQ,MAAM,EAAE;AACpD,eAAO,IAAI,EAAE;AACb,eAAO,KAAK,2EAA2E;AACvF;AAAA,MACF;AAEA,uBAAiB;AAAA,IACnB,OAAO;AAEL,aAAO,IAAI,EAAE;AACb,uBAAiB,MAAM,oBAAoB;AAC3C,aAAO,IAAI,EAAE;AAAA,IACf;AAGA,QAAI,mBAAmB,OAAO;AAE5B,YAAM,6BAA6B,OAAO;AAAA,IAC5C,OAAO;AAEL,YAAM,mBAAmB,kBAAkB,GAAG,aAAa,gBAAgB;AAC3E,uBAAiB,MAAM;AAEvB,mBAAa;AAGb,UAAI,eAAe,UAAU,eAAe,cAAc;AACxD,cAAM,QAAQ,MAAM,eAAe,sBAAsB,UAAU;AAGnE,cAAM,cACJ,cAAc,EAAE,GAAG,UAAU,UAAoD;AACnF,cAAM,gBAAgB,MAAM,kBAAkB;AAC9C,cAAM,iBACJ,gBAAgB,GAAG,UAAU,UAAwC;AAEvE,YAAI,CAAC,OAAO,eAAe,CAAC,eAAe,CAAC,gBAAgB;AAC1D,0BAAgB,kBAAkB,GAAG,aAAa,MAAM,UAAU,sBAAsB;AACxF,iBAAO,IAAI,EAAE;AACb,iBAAO,KAAK,yBAAyB;AACrC,iBAAO,KAAK,KAAK,MAAM,QAAQ,yBAAyB,CAAC,gBAAgB;AACzE,iBAAO;AAAA,YACL,KAAK,MAAM,QAAQ,uBAAuB,UAAU,gCAAgC,CAAC;AAAA,UACvF;AACA,iBAAO;AAAA,YACL,KAAK,MAAM,QAAQ,mBAAmB,WAAW,YAAY,CAAC,iCAAiC,CAAC;AAAA,UAClG;AACA;AAAA,QACF;AAAA,MACF;AAEA,yBAAmB,kBAAkB,GAAG,aAAa,WAAW,MAAM,MAAM,UAAU,CAAC,EAAE;AACzF,aAAO,IAAI,EAAE;AAGb,YAAM,SAAS,MAAM,kBAAkB,YAAY,SAAS,WAAW;AAGvE,UAAI,OAAO,UAAU,GAAG;AACtB,eAAO,IAAIA,OAAM,qBAAqB,OAAO,OAAO,GAAG,UAAU,OAAO,CAAC;AAAA,MAC3E;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,mBAAmB;AACtC,aAAO,IAAI,EAAE;AACb,aAAO,KAAK,MAAM,UAAU,iBAAiB,CAAC;AAC9C,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAEA,UAAM,MAAM;AACZ,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACLA,OAAM,mBAAmB,IAAI,SAASC,cAAa,KAAK,UAAU,CAAC,GAAG,UAAU,KAAK;AAAA,IACvF;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,SAASA,cAAa,OAAsB,YAAiC;AAC3E,MAAI,MAAM,SAAS,eAAe;AAChC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,YAAY;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,uBAAuB,MAAM,SAAS,uBAAuB;AAE9E,QAAI,eAAe,UAAU,eAAe,cAAc;AACxD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,gBAAgB;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,YAAY;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AiBvmBA;AAIA;AACA;AALA,SAAS,WAAAC,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAOhB,eAAsB,gBAA+B;AAEnD,QAAM,kBAAkB,MAAM,YAAY,gBAAgB;AAE1D,MAAI,CAAC,iBAAiB;AACpB,WAAO;AAAA,MACLF;AAAA,QACE,GAAGC,OAAM,OAAO,6BAA6B,CAAC;AAAA;AAAA,EAAOA,OAAM,IAAI,wBAAwB,CAAC;AAAA,QACxF;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AAGA,QAAM,WAAW,YAAY,YAAY;AACzC,QAAM,WAAW,UAAU,QAAQ;AAEnC,SAAO,IAAI,EAAE;AAGb,QAAM,eAAe,MAAMF,SAAQ;AAAA,IACjC,SAAS,qCAAqCE,OAAM,KAAK,QAAQ,CAAC;AAAA,IAClE,SAAS;AAAA,EACX,CAAC;AAED,MAAI,CAAC,cAAc;AACjB,WAAO,KAAK,kBAAkB;AAC9B;AAAA,EACF;AAEA,QAAM,UAAUC,KAAI,gBAAgB,EAAE,MAAM;AAE5C,MAAI;AACF,UAAM,YAAY,OAAO;AACzB,YAAQ,QAAQ,yBAAyB;AACzC,WAAO,IAAI,EAAE;AAEb,WAAO;AAAA,MACLF;AAAA,QACE,GAAGC,OAAM,MAAM,KAAK,gCAA2B,CAAC;AAAA;AAAA,EAC3CA,OAAM,IAAI,oCAAoC,CAAC;AAAA;AAAA,EAC/CA,OAAM,IAAI,KAAK,CAAC,IAAIA,OAAM,KAAK,eAAe,CAAC,IAAIA,OAAM,IAAI,gBAAgB,CAAC;AAAA,QACnF;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AACN,YAAQ,KAAK,eAAe;AAC5B,WAAO,MAAM,qCAAqC;AAClD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;ACvEA;AAAA,OAAOE,YAAW;AAClB,OAAOC,YAAW;AAGlB;AACA;AACA;AACA;AAWA;AAyBA,eAAsB,YAAY,UAA8B,CAAC,GAAkB;AAEjF,SAAO,IAAI,EAAE;AACb,SAAO;AAAA,IACLC;AAAA,MACEC,OAAM,OAAO,KAAK,2BAAsB,IACtC;AAAA;AAAA,MACOA,OAAM,KAAK,MAAM,CAAC;AAAA,aACXA,OAAM,KAAK,eAAe,CAAC;AAAA;AAAA,IACzCA,OAAM,IAAI,wCAAwC;AAAA,MACpD;AAAA,QACE,SAAS;AAAA,QACT,aAAa;AAAA,QACb,aAAa;AAAA,QACb,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AAEb,QAAM,cAAc;AAEpB,MAAI;AAEF,UAAM,kBAAkB,MAAM,oBAAoB;AAClD,QAAI,CAAC,iBAAiB;AACpB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,WAAO,MAAM,iCAAiC;AAC9C,UAAM,qBAAqB,MAAM,WAAW,sBAAsB;AAElE,WAAO,MAAM,iCAAiC,KAAK,UAAU,oBAAoB,MAAM,CAAC,CAAC;AACzF,WAAO;AAAA,MACL,mBAAmB,mBAAmB,IAAI,YAAY,OAAO,mBAAmB,IAAI;AAAA,IACtF;AACA,WAAO,MAAM,oBAAoB,mBAAmB,SAAS,MAAM,EAAE;AAErE,QAAI,mBAAmB,SAAS,QAAQ;AACtC,aAAO,MAAM,4CAA4C;AACzD,aAAO,IAAI,EAAE;AACb,aAAO;AAAA,QACLD;AAAA,UACE,MAAM,QAAQ,kCAAkC,IAC9C,iMAMA,OAAO,UAAU,8BAA8B;AAAA,UACjD;AAAA,YACE,GAAG,UAAU;AAAA,YACb,SAAS;AAAA,YACT,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AAEb,YAAM,oBAAoB,MAAM;AAAA,QAC9B;AAAA,QACA;AAAA,MACF;AAEA,UAAI,mBAAmB;AACrB,eAAO,IAAI,EAAE;AACb,cAAM,WAAW;AAEjB,YAAI;AACF,gBAAM,YAAY,QAAQ;AAC1B,iBAAO,KAAK,MAAM,UAAU,oBAAoB,CAAC;AAAA,QACnD,QAAQ;AACN,iBAAO,QAAQ,sCAAsC;AACrD,iBAAO,KAAK,iBAAiB,MAAM,MAAM,QAAQ,CAAC,EAAE;AAAA,QACtD;AAAA,MACF;AAEA,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAEA,WAAO,MAAM,sBAAsB,mBAAmB,IAAI,0BAA0B;AAGpF,UAAM,cAAc,kBAAkB,GAAG,aAAa,8BAA8B;AACpF,gBAAY,MAAM;AAElB,UAAM,cAAc,yBAAyB;AAC7C,UAAM,WAAW,MAAM,cAAc,kBAAkB;AAEvD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,MAAM,MAAM,SAAS,QAAQ,CAAC;AAAA,IAC/C;AACA,WAAO,IAAI,EAAE;AAGb,QAAI,OAAO,QAAQ;AACnB,QAAI,CAAC,MAAM;AACT,YAAM,cAAc,eAAe,UAAU,mBAAmB;AAChE,aAAO,MAAM,iBAAiB,WAAW;AACzC,aAAO,IAAI,EAAE;AAAA,IACf;AAGA,UAAM,YAAY;AAAA,MAChB;AAAA,MACA;AAAA,MACA,qCAAqC,IAAI;AAAA,IAC3C;AACA,cAAU,MAAM;AAEhB,QAAI;AACJ,QAAI,QAAQ,KAAK;AACf,YAAM,MAAM,cAAc,aAAa,EAAE,KAAK,CAAC;AAAA,IACjD,OAAO;AACL,YAAM,MAAM,cAAc,oBAAoB,EAAE,KAAK,CAAC;AAAA,IACxD;AAGA,UAAM,UAAuB,IAAI,IAAI,CAAC,OAAO,cAAc,oBAAoB,EAAE,CAAC;AAElF,QAAI,QAAQ,WAAW,GAAG;AACxB,sBAAgB,WAAW,GAAG,aAAa,mCAAmC,IAAI,OAAO;AACzF,aAAO,IAAI,EAAE;AACb,aAAO,KAAK,iEAAiE;AAC7E;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,MAAM,MAAM,QAAQ,MAAM,CAAC,MAAM,QAAQ,SAAS,IAAI,MAAM,EAAE;AAAA,IACzE;AACA,WAAO,IAAI,EAAE;AAGb,WAAO,IAAI,kBAAkB,OAAO,CAAC;AACrC,WAAO,IAAI,EAAE;AAGb,QAAI,gBAAgB,CAAC,GAAG,OAAO;AAC/B,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,aAAa,MAAM,iBAAiB;AAC1C,aAAO,IAAI,EAAE;AAGb,UAAI,eAAe,QAAQ;AACzB,sBAAc,KAAK,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,IAAI,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC;AAAA,MACtF,WAAW,eAAe,QAAQ;AAChC,sBAAc,KAAK,CAAC,GAAG,MAAM;AAC3B,gBAAM,SAAS,EAAE,WAAW,cAAc,MAAM,EAAE,WAAW,aAAa;AAC1E,gBAAM,SAAS,EAAE,WAAW,cAAc,MAAM,EAAE,WAAW,aAAa;AAC1E,iBAAO,QAAQ;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,eAAe,SAAS;AACjC,sBAAc,KAAK,CAAC,GAAG,MAAM;AAC3B,gBAAM,SAAS,EAAE,WAAW,gBAAgB;AAC5C,gBAAM,SAAS,EAAE,WAAW,gBAAgB;AAC5C,iBAAO,SAAS;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,eAAe,MAAM,oBAAoB,aAAa;AAE5D,QAAI,aAAa,WAAW,GAAG;AAC7B,aAAO,IAAI,EAAE;AACb,aAAO,KAAK,MAAM,UAAU,kCAAkC,CAAC;AAC/D,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAEA,UAAM,kBAAkB,cAAc,OAAO,CAAC,MAAM,aAAa,SAAS,EAAE,GAAG,CAAC;AAGhF,WAAO,IAAI,uBAAuB,gBAAgB,QAAQ,eAAe,CAAC;AAC1E,WAAO,IAAI,EAAE;AAGb,UAAM,gBAAgB,MAAM,WAAW,UAAU,EAAE,OAAO,IAAI,CAAC;AAC/D,WAAO,MAAM,WAAW,cAAc,MAAM,MAAM,iBAAiB;AAGnE,UAAM,eAAe,IAAI,IAAI,cAAc,MAAM,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;AACpF,WAAO,MAAM,oCAAoC,aAAa,IAAI,EAAE;AAEpE,UAAM,aAAa,gBAAgB,OAAO,CAAC,MAAM,EAAE,OAAO,aAAa,IAAI,EAAE,GAAG,CAAC;AACjF,UAAM,aAAa,gBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE,GAAG,CAAC;AAEnF,WAAO,MAAM,eAAe,WAAW,MAAM,UAAU,WAAW,MAAM,EAAE;AAE1E,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO,IAAI,EAAE;AACb,aAAO;AAAA,QACL,OAAO;AAAA,UACL,GAAG,WAAW,MAAM,MAAM,WAAW,SAAS,IAAI,MAAM,EAAE;AAAA,QAC5D;AAAA,MACF;AACA,aAAO,IAAI,EAAE;AAAA,IACf;AAEA,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO,IAAI,EAAE;AACb,aAAO;AAAA,QACL,MAAM,UAAU,gEAAgE;AAAA,MAClF;AACA,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAGA,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA,YAAY,MAAM,MAAM,WAAW,MAAM,CAAC,MAAM,WAAW,SAAS,IAAI,MAAM,EAAE;AAAA,IAClF;AACA,kBAAc,MAAM;AAEpB,UAAM,gBAAgB;AAAA,MACpB,OAAO,WAAW,IAAI,CAAC,OAAO;AAAA,QAC5B,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,OAAO,EAAE,QAAQ,MAAM,IAAI,EAAE,CAAC;AAAA;AAAA,MAChC,EAAE;AAAA,IACJ;AAEA,UAAM,iBAAiB,MAAM,WAAW,YAAY,aAAa;AACjE,QAAI,eAAe,eAAe;AAElC,uBAAmB,eAAe,GAAG,aAAa,0BAA0B;AAC5E,WAAO,IAAI,EAAE;AAGb,WAAO,KAAK,2BAA2B;AACvC,WAAO,IAAI,EAAE;AACb,WAAO,IAAI,0BAA0B,cAAc,UAAU,CAAC;AAC9D,WAAO,IAAI,EAAE;AAGb,UAAM,gBAAgB,MAAM,kBAAkB,cAAc,UAAU;AAEtE,QAAI,cAAc,WAAW,GAAG;AAC9B,aAAO,IAAI,EAAE;AACb,aAAO,KAAK,MAAM,UAAU,iDAAiD,CAAC;AAC9E,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAEA,WAAO,IAAI,EAAE;AAGb,QAAI,gBAA+B;AACnC,UAAM,WAAW,YAAY,YAAY;AACzC,QAAI,UAAU,IAAI;AAChB,UAAI;AACF,cAAM,eAAe,MAAM,WAAW,sBAAsB,SAAS,EAAE;AACvE,YAAI,aAAa,MAAM,SAAS,GAAG;AACjC,0BAAgB,MAAM,yBAAyB,aAAa,KAAK;AACjE,iBAAO,IAAI,EAAE;AAAA,QACf;AAAA,MACF,QAAQ;AACN,eAAO,MAAM,uDAAuD;AAAA,MACtE;AAAA,IACF;AAGA,UAAME,iBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA,YAAY,MAAM,MAAM,cAAc,MAAM,CAAC,QAAQ,cAAc,SAAS,IAAI,MAAM,EAAE;AAAA,IAC1F;AACA,IAAAA,eAAc,MAAM;AAEpB,UAAM,gBAAgB;AAAA,MACpB,OAAO,cAAc,IAAI,CAAC,SAAsB,UAAkC;AAChF,cAAM,iBAAiB,WAAW,KAAK;AACvC,eAAO;AAAA,UACL,YAAY,gBAAgB,OAAO,QAAQ,KAAK;AAAA,UAChD,OAAO,QAAQ;AAAA,UACf,aAAa,QAAQ;AAAA,UACrB,MAAM,QAAQ;AAAA,UACd,YAAY,SAAS;AAAA,UACrB,MAAM,gBAAgB,QAAQ;AAAA,UAC9B,YAAY,gBAAgB,OAAO;AAAA,UACnC,cAAc,QAAQ;AAAA,UACtB,oBAAoB,QAAQ;AAAA,UAC5B,aAAa,gBAAgB,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC;AAAA,UAC3D,OAAO,iBAAiB;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,iBAAiB,MAAM,WAAW,YAAY,aAAa;AAEjE;AAAA,MACEA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,MAAM,MAAM,eAAe,OAAO,CAAC,QAAQ,eAAe,UAAU,IAAI,MAAM,EAAE;AAAA,IAC7F;AACA,WAAO,IAAI,EAAE;AAGb,WAAO,IAAIF,OAAM,qBAAqB,eAAe,OAAO,GAAG,UAAU,OAAO,CAAC;AAAA,EACnF,SAAS,OAAO;AAEd,QAAI,iBAAiB,mBAAmB;AACtC,aAAO,IAAI,EAAE;AACb,aAAO,KAAK,MAAM,UAAU,iBAAiB,CAAC;AAC9C,aAAO,IAAI,EAAE;AACb;AAAA,IACF;AAEA,UAAM,MAAM;AAEZ,WAAO,IAAI,EAAE;AACb,WAAO,IAAIA,OAAM,mBAAmB,IAAI,SAASG,cAAa,GAAG,CAAC,GAAG,UAAU,KAAK,CAAC;AAErF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,SAASA,cAAa,OAA8B;AAClD,MAAI,MAAM,SAAS,eAAe;AAChC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,YAAY;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,uBAAuB,MAAM,SAAS,uBAAuB;AAC9E,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,gBAAgB;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,YAAY;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AC5YA;AAEA;AAFA,OAAOC,YAAW;AAClB,OAAOC,YAAW;AAGlB;AAqBA,eAAsB,YAAY,UAA8B,CAAC,GAAkB;AACjF,SAAO,IAAI,EAAE;AAEb,MAAI;AAEF,UAAM,kBAAkB,MAAM,oBAAoB;AAClD,QAAI,CAAC,iBAAiB;AACpB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,UAAM,QAAQ,QAAQ,SAAS;AAC/B,UAAM,SAAS,QAAQ,UAAU;AACjC,UAAM,OAAO,QAAQ,OAAO,QAAQ,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI;AAC3E,UAAM,SAAS,QAAQ;AAGvB,UAAM,UAAU,qBAAqB;AACrC,YAAQ,MAAM;AAEd,UAAM,WAAW,MAAM,WAAW,UAAU;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,SAAS,MAAM,WAAW,GAAG;AAC/B,kBAAY,SAAS,gBAAgB;AACrC,aAAO,IAAI,EAAE;AAEb,UAAI,UAAU,MAAM;AAClB,eAAO,KAAK,oEAAoE;AAAA,MAClF,OAAO;AACL,eAAO;AAAA,UACL,MAAM,UAAU,MAAM,IACpB,MAAM,QAAQ,eAAe,IAC7B,MAAM,UAAU,6BAA6B;AAAA,QACjD;AAAA,MACF;AACA;AAAA,IACF;AAEA,mBAAe,SAAS,SAAS,SAAS,KAAK,QAAQ,SAAS,QAAQ,IAAI,MAAM,EAAE,EAAE;AACtF,WAAO,IAAI,EAAE;AAGb,QAAI,QAAQ,SAAS;AACnB,aAAO,IAAI,mBAAmB,SAAS,KAAK,CAAC;AAAA,IAC/C,OAAO;AACL,aAAO,IAAI,iBAAiB,SAAS,KAAK,CAAC;AAAA,IAC7C;AACA,WAAO,IAAI,EAAE;AAGb,QAAI,SAAS,UAAU;AACrB,YAAM,aAAa,SAAS;AAC5B,aAAO;AAAA,QACL,WAAW,SAAS,CAAC,IAAI,SAAS,SAAS,MAAM,MAAM,OAAO,SAAS,KAAK;AAAA,MAC9E;AACA,aAAO;AAAA,QACL,MAAM,UAAU,MAAM,IACpB,MAAM,QAAQ,0BAA0B,UAAU,EAAE,IACpD,MAAM,UAAU,cAAc;AAAA,MAClC;AACA,aAAO,IAAI,EAAE;AAAA,IACf,WAAW,SAAS,GAAG;AACrB,aAAO;AAAA,QACL,WAAW,SAAS,CAAC,IAAI,SAAS,SAAS,MAAM,MAAM,OAAO,SAAS,KAAK;AAAA,MAC9E;AACA,aAAO,IAAI,EAAE;AAAA,IACf;AAGA,QAAI,UAAU,MAAM;AAClB,YAAM,aAAuB,CAAC;AAC9B,UAAI,OAAQ,YAAW,KAAK,YAAY,MAAM,GAAG;AACjD,UAAI,KAAM,YAAW,KAAK,SAAS,KAAK,KAAK,IAAI,CAAC,EAAE;AACpD,aAAO,KAAK,MAAM,KAAK,oBAAoB,WAAW,KAAK,IAAI,CAAC,EAAE,CAAC;AACnE,aAAO,IAAI,EAAE;AAAA,IACf;AAAA,EACF,SAAS,OAAO;AACd,UAAM,MAAM;AAEZ,WAAO,IAAI,EAAE;AACb,WAAO,IAAIC,OAAM,mBAAmB,IAAI,SAASC,cAAa,GAAG,CAAC,GAAG,UAAU,KAAK,CAAC;AAErF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,SAAS,iBAAiB,OAAuB;AAC/C,QAAM,QAAQ,IAAIC,OAAM;AAAA,IACtB,MAAM;AAAA,MACJ,OAAO,QAAQ,MAAM;AAAA,MACrB,OAAO,QAAQ,OAAO;AAAA,MACtB,OAAO,QAAQ,aAAa;AAAA,MAC5B,OAAO,QAAQ,MAAM;AAAA,MACrB,OAAO,QAAQ,YAAY;AAAA,IAC7B;AAAA,IACA,WAAW,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE;AAAA,IAC9B,UAAU;AAAA,IACV,OAAO,YAAY,QAAQ;AAAA,EAC7B,CAAC;AAED,QAAM,QAAQ,CAAC,SAAS;AACtB,UAAM,OAAO,IAAI,KAAK,KAAK,IAAI,EAAE,mBAAmB;AACpD,UAAM,QAAQ,KAAK;AACnB,UAAM,cAAc,aAAa,KAAK,aAAa,GAAG;AACtD,UAAM,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI,OAAO,IAAI,MAAM;AAC5E,UAAM,aAAa,KAAK,aACpB,aAAa,gBAAgB,KAAK,UAAU,GAAG,EAAE,IACjD,OAAO,IAAI,MAAM;AAErB,UAAM,KAAK;AAAA,MACT,OAAO,UAAU,IAAI;AAAA,MACrB,OAAO,MAAM,KAAK;AAAA,MAClB,OAAO,IAAI,WAAW;AAAA,MACtB,OAAO,QAAQ,IAAI;AAAA,MACnB,OAAO,KAAK,UAAU;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAED,SAAO,MAAM,SAAS;AACxB;AAKA,SAAS,mBAAmB,OAAuB;AACjD,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,UAAM,OAAO,IAAI,KAAK,KAAK,IAAI,EAAE,mBAAmB;AACpD,WAAO,GAAG,OAAO,UAAU,IAAI,CAAC,KAAK,OAAO,MAAM,KAAK,KAAK,CAAC;AAAA,EAC/D,CAAC,EACA,KAAK,IAAI;AACd;AAKA,SAAS,aAAa,MAAc,WAA2B;AAC7D,MAAI,KAAK,UAAU,WAAW;AAC5B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,UAAU,GAAG,YAAY,CAAC,IAAI;AAC5C;AAKA,SAAS,gBAAgB,KAAqB;AAC5C,MAAI;AAEF,UAAM,QAAQ,IAAI,MAAM,0BAA0B;AAClD,WAAO,QAAQ,MAAM,CAAC,IAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAASD,cAAa,OAA8B;AAClD,MAAI,MAAM,SAAS,uBAAuB,MAAM,SAAS,uBAAuB;AAC9E,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,gBAAgB;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,YAAY;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AC9MA;AAGA;AACA;AACA;AALA,OAAOE,aAAW;AAClB,OAAOC,YAAW;AAClB,OAAOC,YAAW;AAKlB;AAOA,IAAM,oBAAoB,OAAO,OAAO,WAAW;AAUnD,eAAsB,cACpB,YACA,KACA,OACe;AACf,SAAO,IAAI,EAAE;AAEb,MAAI;AAEF,QAAI,CAAC,YAAY;AACf,mBAAa;AAAA,IACf;AAEA,YAAQ,YAAY;AAAA,MAClB,KAAK;AACH,cAAM,iBAAiB;AACvB;AAAA,MAEF,KAAK;AACH,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,gBAAgB,0CAA0C;AAAA,QACtE;AACA,cAAM,gBAAgB,GAAG;AACzB;AAAA,MAEF,KAAK;AACH,YAAI,CAAC,OAAO,UAAU,QAAW;AAC/B,gBAAM,IAAI,gBAAgB,qDAAqD;AAAA,QACjF;AACA,cAAM,gBAAgB,KAAK,KAAK;AAChC;AAAA,MAEF;AACE,cAAM,IAAI;AAAA,UACR,wBAAwB,UAAU;AAAA,QACpC;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,UAAM,MAAM;AACZ,WAAO,IAAI,EAAE;AACb,WAAO;AAAA,MACLC,QAAM,mBAAmB,IAAI,SAAS,cAAc,GAAG,CAAC,GAAG;AAAA,QACzD,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,eAAe,mBAAkC;AAC/C,QAAMC,UAAS;AAAA,IACb,mBAAmB,eAAe,UAAU,mBAAmB;AAAA,IAC/D,kBAAkB,eAAe,UAAU,kBAAkB;AAAA,IAC7D,eAAe,eAAe,UAAU,eAAe;AAAA,IACvD,gBAAgB,eAAe,UAAU,gBAAgB;AAAA,IACzD,cAAc,eAAe,UAAU,cAAc;AAAA,IACrD,oBAAoB,eAAe,UAAU,oBAAoB;AAAA,IACjE,gBAAgB,eAAe,UAAU,gBAAgB;AAAA,EAC3D;AAEA,QAAM,QAAQ,IAAIC,OAAM;AAAA,IACtB,MAAM,CAACC,OAAM,KAAK,KAAK,GAAGA,OAAM,KAAK,OAAO,GAAGA,OAAM,KAAK,SAAS,CAAC;AAAA,IACpE,WAAW,CAAC,IAAI,IAAI,EAAE;AAAA,IACtB,UAAU;AAAA,IACV,OAAO;AAAA,MACL,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC,MAAM;AAAA,IACjB;AAAA,EACF,CAAC;AAED,QAAM,KAAK;AAAA,IACTA,OAAM,MAAM,mBAAmB;AAAA,IAC/BA,OAAM,OAAO,OAAOF,QAAO,iBAAiB,CAAC;AAAA,IAC7CE,OAAM,IAAI,OAAO,eAAe,iBAAiB,CAAC;AAAA,EACpD,CAAC;AAED,QAAM,KAAK;AAAA,IACTA,OAAM,MAAM,kBAAkB;AAAA,IAC9BA,OAAM,OAAO,OAAOF,QAAO,gBAAgB,CAAC;AAAA,IAC5CE,OAAM,IAAI,OAAO,eAAe,gBAAgB,CAAC;AAAA,EACnD,CAAC;AAED,QAAM,KAAK;AAAA,IACTA,OAAM,MAAM,eAAe;AAAA,IAC3BA,OAAM,OAAOF,QAAO,iBAAiB,SAAS;AAAA,IAC9CE,OAAM,IAAI,SAAS;AAAA,EACrB,CAAC;AAED,QAAM,KAAK;AAAA,IACTA,OAAM,MAAM,gBAAgB;AAAA,IAC5BA,OAAM,OAAOF,QAAO,iBAAiBA,QAAO,eAAe,KAAK,IAAI,IAAI,SAAS;AAAA,IACjFE,OAAM,IAAI,SAAS;AAAA,EACrB,CAAC;AAED,QAAM,KAAK;AAAA,IACTA,OAAM,MAAM,cAAc;AAAA,IAC1BA,OAAM,OAAOF,QAAO,gBAAgB,SAAS;AAAA,IAC7CE,OAAM,IAAI,SAAS;AAAA,EACrB,CAAC;AAED,QAAM,KAAK;AAAA,IACTA,OAAM,MAAM,oBAAoB;AAAA,IAChCA,OAAM,OAAOF,QAAO,sBAAsB,SAAS;AAAA,IACnDE,OAAM,IAAI,SAAS;AAAA,EACrB,CAAC;AAED,QAAM,KAAK;AAAA,IACTA,OAAM,MAAM,gBAAgB;AAAA,IAC5BA,OAAM,OAAOF,QAAO,kBAAkB,SAAS;AAAA,IAC/CE,OAAM,IAAI,SAAS;AAAA,EACrB,CAAC;AAED,SAAO,KAAK,wBAAwB;AACpC,SAAO,IAAI,EAAE;AACb,SAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,SAAO,IAAI,EAAE;AACb,SAAO,KAAKA,OAAM,IAAI,qBAAqB,IAAIA,OAAM,KAAK,mCAAmC,CAAC;AAC9F,SAAO,IAAI,EAAE;AACf;AAKA,eAAe,gBAAgB,KAA4B;AACzD,oBAAkB,GAAG;AAErB,QAAM,QAAQ,eAAe,UAAU,GAA2B;AAClE,QAAM,eAAe,eAAe,GAAkC;AAEtE,SAAO,KAAK,qBAAqBA,OAAM,KAAK,GAAG,CAAC,GAAG;AACnD,SAAO,IAAI,EAAE;AACb,SAAO,IAAI,KAAKA,OAAM,MAAM,UAAU,CAAC,IAAIA,OAAM,OAAO,OAAO,KAAK,CAAC,CAAC,EAAE;AACxE,SAAO,IAAI,KAAKA,OAAM,MAAM,UAAU,CAAC,IAAIA,OAAM,IAAI,OAAO,YAAY,CAAC,CAAC,EAAE;AAC5E,SAAO,IAAI,EAAE;AAEb,MAAI,UAAU,cAAc;AAC1B,WAAO,KAAKA,OAAM,IAAI,qBAAqB,CAAC;AAAA,EAC9C,OAAO;AACL,WAAO;AAAA,MACLA,OAAM,IAAI,gCAAgC,IACxCA,OAAM,KAAK,uBAAuB,GAAG,IAAI,YAAY,EAAE;AAAA,IAC3D;AAAA,EACF;AACA,SAAO,IAAI,EAAE;AACf;AAKA,eAAe,gBAAgB,KAAa,OAA8B;AACxE,oBAAkB,GAAG;AAGrB,QAAM,aAAa,wBAAwB,KAAK,KAAK;AAGrD,iBAAe,UAAU,KAA6B,UAAU;AAEhE,SAAO;AAAA,IACLH;AAAA,MACE,GAAGG,OAAM,MAAM,KAAK,8BAAyB,CAAC;AAAA;AAAA,EACzCA,OAAM,MAAM,GAAG,CAAC,KAAKA,OAAM,OAAO,OAAO,UAAU,CAAC,CAAC;AAAA,MAC1D;AAAA,QACE,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,kBAAkB,KAAmB;AAC5C,MAAI,CAAC,kBAAkB,SAAS,GAAU,GAAG;AAC3C,UAAM,IAAI;AAAA,MACR,wBAAwB,GAAG;AAAA;AAAA;AAAA,EAAqB,kBAAkB,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IACrG;AAAA,EACF;AACF;AAKA,SAAS,wBACP,KACA,OAC0C;AAC1C,UAAQ,KAAK;AAAA,IACX,KAAK,YAAY,qBAAqB;AAEpC,YAAM,OAAO,SAAS,OAAO,EAAE;AAC/B,UAAI,MAAM,IAAI,KAAK,OAAO,KAAK,OAAO,KAAK;AACzC,cAAM,IAAI;AAAA,UACR,yCAAyC,KAAK;AAAA;AAAA;AAAA,QAChD;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,YAAY,oBAAoB;AAEnC,YAAM,aAAa,MAAM,YAAY;AACrC,UAAI,eAAe,UAAU,eAAe,OAAO,eAAe,OAAO;AACvE,eAAO;AAAA,MACT,WAAW,eAAe,WAAW,eAAe,OAAO,eAAe,MAAM;AAC9E,eAAO;AAAA,MACT;AACA,YAAM,IAAI;AAAA,QACR,wCAAwC,KAAK;AAAA;AAAA;AAAA,MAC/C;AAAA,IACF;AAAA,IAEA,KAAK,YAAY,gBAAgB;AAC/B,YAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,UAAI,CAAC,aAAa,SAAS,KAAmB,GAAG;AAC/C,cAAM,IAAI;AAAA,UACR,oBAAoB,KAAK;AAAA;AAAA,iBAAuB,aAAa,KAAK,IAAI,CAAC;AAAA,QACzE;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,YAAY,iBAAiB;AAChC,YAAM,UAAU,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACpD,YAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,iBAAW,UAAU,SAAS;AAC5B,YAAI,CAAC,aAAa,SAAS,MAAoB,GAAG;AAChD,gBAAM,IAAI;AAAA,YACR,qCAAqC,MAAM;AAAA;AAAA,iBAAuB,aAAa,KAAK,IAAI,CAAC;AAAA,UAC3F;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,YAAY;AAAA,IACjB,KAAK,YAAY;AAAA,IACjB,KAAK,YAAY,iBAAiB;AAEhC,UAAI,CAAC,MAAM,MAAM,mCAAmC,GAAG;AACrD,cAAM,IAAI;AAAA,UACR,0BAA0B,KAAK;AAAA;AAAA;AAAA,QACjC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA;AAEE,YAAM,IAAI,gBAAgB,wBAAwB,GAAG,GAAG;AAAA,EAC5D;AACF;AAKA,SAAS,cAAc,OAAoB;AACzC,MAAI,MAAM,SAAS,mBAAmB;AACpC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;A1B7RA;AACA;AAEA,IAAMC,cAAaC,eAAc,YAAY,GAAG;AAChD,IAAMC,aAAYC,SAAQH,WAAU;AAGpC,IAAM,kBAAkBI,MAAKF,YAAW,oBAAoB;AAC5D,IAAM,cAAc,KAAK,MAAMG,cAAa,iBAAiB,OAAO,CAAC;AAErE,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,UAAU,EACf,YAAY,iFAAiF,EAC7F,QAAQ,YAAY,SAAS,iBAAiB,wBAAwB,EACtE,WAAW,cAAc,0BAA0B,EACnD,OAAO,wBAAwB,yCAAyC,EACxE,OAAO,WAAW,yCAAyC;AAG9D,QACG,QAAQ,mBAAmB,EAC3B,YAAY,uEAAuE,EACnF,OAAO,OAAO,eAAe;AAC5B,MAAI;AACF,UAAM,YAAY,UAAU;AAAA,EAC9B,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,MAAM,EACd,YAAY,kCAAkC,EAC9C,OAAO,uBAAuB,0BAA0B,CAAC,QAAQ,SAAS,KAAK,EAAE,CAAC,EAClF,OAAO,aAAa,2CAA2C,EAC/D,OAAO,uBAAuB,+BAA+B,EAC7D,OAAO,OAAO,YAAY;AACzB,MAAI;AACF,UAAM,YAAY,OAAO;AAAA,EAC3B,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,YAAY;AAAA,EACpB,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,MAAM,EACd,YAAY,0DAA0D,EACtE,OAAO,uBAAuB,0BAA0B,CAAC,QAAQ,SAAS,KAAK,EAAE,CAAC,EAClF,OAAO,aAAa,6CAA6C,EACjE,OAAO,OAAO,YAAY;AACzB,MAAI;AACF,UAAM,YAAY,OAAO;AAAA,EAC3B,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,MAAM,EACd,YAAY,0BAA0B,EACtC,OAAO,wBAAwB,8BAA8B,CAAC,QAAQ,SAAS,KAAK,EAAE,GAAG,EAAE,EAC3F,OAAO,yBAAyB,2BAA2B,CAAC,QAAQ,SAAS,KAAK,EAAE,GAAG,CAAC,EACxF,OAAO,qBAAqB,kCAAkC,EAC9D,OAAO,wBAAwB,yBAAyB,EACxD,OAAO,aAAa,wCAAwC,EAC5D,OAAO,OAAO,YAAY;AACzB,MAAI;AACF,UAAM,YAAY,OAAO;AAAA,EAC3B,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,QAAQ,EAChB,YAAY,0BAA0B,EACtC,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,cAAc;AAAA,EACtB,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,mCAAmC,EAC3C,YAAY,wDAAwD,EACpE,OAAO,OAAO,YAAY,KAAK,UAAU;AACxC,MAAI;AACF,UAAM,cAAc,YAAY,KAAK,KAAK;AAAA,EAC5C,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QAAQ,KAAK,aAAa,YAAY;AACpC,QAAM,UAAU,QAAQ,KAAK;AAG7B,MAAI,QAAQ,OAAO;AACjB,YAAQ,IAAI,QAAQ;AACpB,WAAO,MAAM,oBAAoB;AAAA,EACnC;AAGA,QAAM,kBACJ,QAAQ,KAAK,SAAS,WAAW,KACjC,QAAQ,KAAK,SAAS,IAAI,KAC1B,QAAQ,KAAK,SAAS,QAAQ,KAC9B,QAAQ,KAAK,SAAS,IAAI;AAE5B,MAAI,CAAC,QAAQ,oBAAoB,CAAC,iBAAiB;AACjD,QAAI;AACF,YAAM,gBAAgB,EAAE,QAAQ,MAAM,CAAC;AAAA,IACzC,QAAQ;AAEN,aAAO,MAAM,qCAAqC;AAAA,IACpD;AAAA,EACF;AACF,CAAC;AAGD,QAAQ,MAAM,QAAQ,IAAI;AAG1B,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,EAAE,QAAQ;AACjC,UAAQ,WAAW;AACrB;","names":["fileURLToPath","path","config","join","randomBytes","readFileSync","fileURLToPath","dirname","join","packageJsonPath","__dirname","packageJson","version","__filename","readFileSync","fileURLToPath","dirname","join","chalk","boxen","packageJsonPath","__dirname","packageJson","__filename","ofetch","readFileSync","fileURLToPath","URLSearchParams","dirname","join","packageJsonPath","__dirname","packageJson","__filename","version","readFileSync","fileURLToPath","dirname","join","chalk","exec","promisify","existsSync","join","path","execAsync","promisify","exec","chalk","chalk","select","boxen","exec","promisify","execAsync","promisify","exec","exec","promisify","URLSearchParams","execAsync","promisify","exec","URLSearchParams","boxen","boxen","chalk","input","boxen","input","boxen","boxen","ora","ora","select","createSpinner","boxen","getErrorHint","confirm","boxen","chalk","ora","boxen","chalk","boxen","chalk","createSpinner","getErrorHint","boxen","Table","boxen","getErrorHint","Table","boxen","chalk","Table","boxen","config","Table","chalk","__filename","fileURLToPath","__dirname","dirname","join","readFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/constants.ts","../../src/utils/env-loader.ts","../../src/utils/errors.ts","../../src/utils/config-loader.ts","../../src/services/storage.service.ts","../../src/utils/logger.ts","../../src/utils/oauth-server.ts","../../src/utils/browser.ts","../../src/services/auth.service.ts","../../src/utils/version.ts","../../src/services/api.service.ts","../../src/cli.ts","../../src/commands/auth.ts","../../src/services/github.service.ts","../../src/services/git.service.ts","../../src/utils/validators.ts","../../src/ui/theme.ts","../../src/commands/sync.ts","../../node_modules/@inquirer/core/dist/esm/lib/errors.mjs","../../src/sync/adapter-factory.ts","../../src/sync/github-adapter.ts","../../src/sync/bitbucket-adapter.ts","../../src/services/bitbucket.service.ts","../../src/sync/gitlab-adapter.ts","../../src/services/gitlab.service.ts","../../src/sync/jira-adapter.ts","../../src/services/jira.service.ts","../../src/sync/confluence-adapter.ts","../../src/services/confluence.service.ts","../../src/utils/auth-helper.ts","../../src/commands/init.ts","../../src/ui/prompts.ts","../../src/ui/formatters.ts","../../src/ui/spinners.ts","../../src/commands/logout.ts","../../src/commands/scan.ts","../../src/commands/list.ts","../../src/commands/config.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","// Load environment variables\nimport { config } from 'dotenv';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\n\n// Get the directory of this file\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Load .env from the project root (silently)\n// In production, this file is bundled into dist/bin/bragduck.js, so we need to go up 2 levels\n// In development (src/), we'd need to go up 1 level, but the build is what matters\nconfig({ path: join(__dirname, '..', '..', '.env'), debug: false, quiet: true } as any);\n\n// App-wide constants for Bragduck CLI\n\n/**\n * Application name used for storage and configuration\n */\nexport const APP_NAME = 'bragduck';\n\n/**\n * Storage keys for credentials and configuration\n */\nexport const STORAGE_KEYS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n USER_INFO: 'user_info',\n OAUTH_STATE: 'oauth_state',\n} as const;\n\n/**\n * Configuration keys\n */\nexport const CONFIG_KEYS = {\n DEFAULT_COMMIT_DAYS: 'defaultCommitDays',\n AUTO_VERSION_CHECK: 'autoVersionCheck',\n DEFAULT_SOURCE: 'defaultSource',\n SOURCE_PRIORITY: 'sourcePriority',\n JIRA_INSTANCE: 'jiraInstance',\n CONFLUENCE_INSTANCE: 'confluenceInstance',\n GITLAB_INSTANCE: 'gitlabInstance',\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n defaultCommitDays: 30,\n autoVersionCheck: true,\n defaultSource: undefined,\n sourcePriority: undefined,\n jiraInstance: undefined,\n confluenceInstance: undefined,\n gitlabInstance: undefined,\n} as const;\n\n/**\n * OAuth configuration\n */\nexport const OAUTH_CONFIG = {\n CLIENT_ID: 'bragduck-cli',\n CALLBACK_PATH: '/callback',\n TIMEOUT_MS: 120000, // 2 minutes\n MIN_PORT: 8000,\n MAX_PORT: 9000,\n} as const;\n\n/**\n * API endpoints\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n INITIATE: '/v1/auth/cli/initiate',\n TOKEN: '/v1/auth/cli/token',\n },\n BRAGS: {\n CREATE: '/v1/brags',\n LIST: '/v1/brags',\n REFINE: '/v1/brags/refine',\n },\n SUBSCRIPTION: {\n STATUS: '/v1/subscriptions/status',\n },\n ORGANISATIONS: {\n LIST: '/v1/users/{userId}/organisations',\n },\n VERSION: '/v1/cli/version',\n /**\n * @deprecated Use BRAGS.REFINE instead\n */\n COMMITS: {\n REFINE: '/v1/commits/refine',\n },\n} as const;\n\n/**\n * Encryption configuration for file-based credential storage\n */\nexport const ENCRYPTION_CONFIG = {\n ALGORITHM: 'aes-256-gcm',\n KEY_LENGTH: 32,\n IV_LENGTH: 16,\n AUTH_TAG_LENGTH: 16,\n SALT_LENGTH: 32,\n} as const;\n\n/**\n * File paths for credential storage fallback\n */\nexport const STORAGE_PATHS = {\n CREDENTIALS_DIR: '.bragduck',\n CREDENTIALS_FILE: 'credentials.enc',\n CONFIG_FILE: 'config.json',\n} as const;\n\n/**\n * Error codes\n */\nexport const ERROR_CODES = {\n AUTH_FAILED: 'AUTH_FAILED',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n NETWORK_ERROR: 'NETWORK_ERROR',\n GIT_ERROR: 'GIT_ERROR',\n API_ERROR: 'API_ERROR',\n STORAGE_ERROR: 'STORAGE_ERROR',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n} as const;\n\n/**\n * HTTP status codes\n */\nexport const HTTP_STATUS = {\n OK: 200,\n CREATED: 201,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n INTERNAL_SERVER_ERROR: 500,\n} as const;\n\n/**\n * GitHub configuration\n */\nexport const GITHUB_CONFIG = {\n MIN_GH_VERSION: '2.0.0',\n PR_SEARCH_FIELDS: 'number,title,body,author,mergedAt,additions,deletions,changedFiles,url,labels',\n MAX_BODY_LENGTH: 5000,\n} as const;\n\n/**\n * Environment variable names for configuration\n */\nexport const ENV_VARS = {\n SOURCE: 'BRAGDUCK_SOURCE',\n JIRA_INSTANCE: 'BRAGDUCK_JIRA_INSTANCE',\n CONFLUENCE_INSTANCE: 'BRAGDUCK_CONFLUENCE_INSTANCE',\n GITLAB_INSTANCE: 'BRAGDUCK_GITLAB_INSTANCE',\n DEFAULT_COMMIT_DAYS: 'BRAGDUCK_DEFAULT_COMMIT_DAYS',\n AUTO_VERSION_CHECK: 'BRAGDUCK_AUTO_VERSION_CHECK',\n SOURCE_PRIORITY: 'BRAGDUCK_SOURCE_PRIORITY',\n\n // Credentials (for CI/CD)\n JIRA_TOKEN: 'BRAGDUCK_JIRA_TOKEN',\n CONFLUENCE_TOKEN: 'BRAGDUCK_CONFLUENCE_TOKEN',\n GITLAB_TOKEN: 'BRAGDUCK_GITLAB_TOKEN',\n} as const;\n\n/**\n * Project config file names to search for (in order of priority)\n */\nexport const CONFIG_FILES = ['.bragduckrc', '.bragduck/config.json', '.bragduckrc.json'] as const;\n","import type { SourceType } from '../types/source.types.js';\nimport type { EnvironmentConfig } from '../types/config.types.js';\n\n/**\n * Parse a number from environment variable\n */\nfunction parseEnvNumber(key: string): number | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Parse a boolean from environment variable\n * Accepts: true/false, yes/no, 1/0 (case-insensitive)\n */\nfunction parseEnvBoolean(key: string): boolean | undefined {\n const value = process.env[key]?.toLowerCase();\n if (!value) return undefined;\n\n if (['true', 'yes', '1'].includes(value)) return true;\n if (['false', 'no', '0'].includes(value)) return false;\n return undefined;\n}\n\n/**\n * Parse an array from environment variable (comma-separated)\n */\nfunction parseEnvArray(key: string): SourceType[] | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const items = value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n return items.length > 0 ? (items as SourceType[]) : undefined;\n}\n\n/**\n * Validate source type from environment variable\n */\nfunction parseEnvSource(key: string): SourceType | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n return validSources.includes(value as SourceType) ? (value as SourceType) : undefined;\n}\n\n/**\n * Load configuration from environment variables\n * Environment variables follow the pattern: BRAGDUCK_*\n */\nexport function loadEnvConfig(): EnvironmentConfig {\n return {\n // Source configuration\n source: parseEnvSource('BRAGDUCK_SOURCE'),\n jiraInstance: process.env.BRAGDUCK_JIRA_INSTANCE,\n confluenceInstance: process.env.BRAGDUCK_CONFLUENCE_INSTANCE,\n gitlabInstance: process.env.BRAGDUCK_GITLAB_INSTANCE,\n\n // Behavior configuration\n defaultCommitDays: parseEnvNumber('BRAGDUCK_DEFAULT_COMMIT_DAYS'),\n autoVersionCheck: parseEnvBoolean('BRAGDUCK_AUTO_VERSION_CHECK'),\n sourcePriority: parseEnvArray('BRAGDUCK_SOURCE_PRIORITY'),\n\n // Credential overrides (for CI/CD)\n jiraToken: process.env.BRAGDUCK_JIRA_TOKEN,\n confluenceToken: process.env.BRAGDUCK_CONFLUENCE_TOKEN,\n gitlabToken: process.env.BRAGDUCK_GITLAB_TOKEN,\n };\n}\n\n/**\n * Get a specific environment config value\n */\nexport function getEnvConfigValue<K extends keyof EnvironmentConfig>(key: K): EnvironmentConfig[K] {\n const config = loadEnvConfig();\n return config[key];\n}\n\n/**\n * Check if any environment configuration is set\n */\nexport function hasEnvConfig(): boolean {\n const config = loadEnvConfig();\n return Object.values(config).some((value) => value !== undefined);\n}\n","// Custom error classes for Bragduck CLI\n\n/**\n * Base error class for all Bragduck errors\n */\nexport class BragduckError extends Error {\n public code: string;\n public details?: Record<string, any>;\n\n constructor(message: string, code: string, details?: Record<string, any>) {\n super(message);\n this.name = 'BragduckError';\n this.code = code;\n this.details = details;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Authentication-related errors\n */\nexport class AuthenticationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'AUTH_ERROR', details);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Git operation errors\n */\nexport class GitError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GIT_ERROR', details);\n this.name = 'GitError';\n }\n}\n\n/**\n * API communication errors\n */\nexport class ApiError extends BragduckError {\n public statusCode?: number;\n\n constructor(message: string, statusCode?: number, details?: Record<string, any>) {\n super(message, 'API_ERROR', details);\n this.name = 'ApiError';\n this.statusCode = statusCode;\n }\n}\n\n/**\n * Network-related errors\n */\nexport class NetworkError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'NETWORK_ERROR', details);\n this.name = 'NetworkError';\n }\n}\n\n/**\n * Storage-related errors\n */\nexport class StorageError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'STORAGE_ERROR', details);\n this.name = 'StorageError';\n }\n}\n\n/**\n * Validation errors\n */\nexport class ValidationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * OAuth-specific errors\n */\nexport class OAuthError extends AuthenticationError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, details);\n this.name = 'OAuthError';\n }\n}\n\n/**\n * Token expiration error\n */\nexport class TokenExpiredError extends AuthenticationError {\n constructor(message = 'Authentication token has expired') {\n super(message);\n this.name = 'TokenExpiredError';\n this.code = 'TOKEN_EXPIRED';\n }\n}\n\n/**\n * GitHub-related errors\n */\nexport class GitHubError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITHUB_ERROR', details);\n this.name = 'GitHubError';\n }\n}\n\n/**\n * Bitbucket-related errors\n */\nexport class BitbucketError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'BITBUCKET_ERROR', details);\n this.name = 'BitbucketError';\n }\n}\n\n/**\n * GitLab-related errors\n */\nexport class GitLabError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITLAB_ERROR', details);\n this.name = 'GitLabError';\n }\n}\n\n/**\n * Jira-related errors\n */\nexport class JiraError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'JIRA_ERROR', details);\n this.name = 'JiraError';\n }\n}\n\n/**\n * Confluence-related errors\n */\nexport class ConfluenceError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'CONFLUENCE_ERROR', details);\n this.name = 'ConfluenceError';\n }\n}\n\n/**\n * Atlassian-related errors (for shared Atlassian services)\n */\nexport class AtlassianError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'ATLASSIAN_ERROR', details);\n this.name = 'AtlassianError';\n }\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { CONFIG_FILES } from '../constants.js';\nimport { ValidationError } from './errors.js';\nimport type { SourceType } from '../types/source.types.js';\nimport type { ProjectConfig } from '../types/config.types.js';\n\n/**\n * Cache for project config to avoid repeated file system reads\n */\nlet configCache: Map<string, ProjectConfig | null> = new Map();\n\n/**\n * Find and load project config file in the current directory\n */\nexport async function findProjectConfig(): Promise<ProjectConfig | null> {\n const cwd = process.cwd();\n\n // Check cache first\n if (configCache.has(cwd)) {\n return configCache.get(cwd) || null;\n }\n\n // Search for config files in order of priority\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(cwd, filename);\n\n try {\n await fs.access(configPath);\n const config = await loadAndValidateConfig(configPath);\n configCache.set(cwd, config);\n return config;\n } catch {\n // File doesn't exist or is not readable, continue to next\n continue;\n }\n }\n\n // No config file found\n configCache.set(cwd, null);\n return null;\n}\n\n/**\n * Load and validate a project config file\n */\nexport async function loadAndValidateConfig(configPath: string): Promise<ProjectConfig> {\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const config = JSON.parse(content);\n\n // Validate the config structure\n validateProjectConfig(config);\n\n return config as ProjectConfig;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ValidationError(`Invalid JSON in config file: ${configPath}`, {\n originalError: error.message,\n });\n }\n throw error;\n }\n}\n\n/**\n * Validate project config structure\n */\nfunction validateProjectConfig(config: unknown): void {\n if (typeof config !== 'object' || config === null) {\n throw new ValidationError('Config must be a JSON object');\n }\n\n const cfg = config as Record<string, unknown>;\n\n // Validate defaultCommitDays\n if (cfg.defaultCommitDays !== undefined) {\n if (typeof cfg.defaultCommitDays !== 'number') {\n throw new ValidationError('defaultCommitDays must be a number');\n }\n if (cfg.defaultCommitDays < 1 || cfg.defaultCommitDays > 365) {\n throw new ValidationError('defaultCommitDays must be between 1 and 365');\n }\n }\n\n // Validate autoVersionCheck\n if (cfg.autoVersionCheck !== undefined) {\n if (typeof cfg.autoVersionCheck !== 'boolean') {\n throw new ValidationError('autoVersionCheck must be a boolean');\n }\n }\n\n // Validate defaultSource\n if (cfg.defaultSource !== undefined) {\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n if (!validSources.includes(cfg.defaultSource as SourceType)) {\n throw new ValidationError(\n `Invalid defaultSource: ${cfg.defaultSource}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n\n // Validate sourcePriority\n if (cfg.sourcePriority !== undefined) {\n if (!Array.isArray(cfg.sourcePriority)) {\n throw new ValidationError('sourcePriority must be an array');\n }\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n for (const source of cfg.sourcePriority) {\n if (!validSources.includes(source)) {\n throw new ValidationError(\n `Invalid source in sourcePriority: ${source}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n }\n\n // Validate instance URLs\n const instanceFields = ['jiraInstance', 'confluenceInstance', 'gitlabInstance'];\n for (const field of instanceFields) {\n if (cfg[field] !== undefined) {\n if (typeof cfg[field] !== 'string') {\n throw new ValidationError(`${field} must be a string`);\n }\n // Basic hostname/URL validation\n const value = cfg[field] as string;\n if (!value.match(/^[a-zA-Z0-9.-]+(:[0-9]+)?(\\/.*)?$/)) {\n throw new ValidationError(`Invalid ${field}: ${value}`);\n }\n }\n }\n\n // Validate boolean flags\n const booleanFields = ['requireAuthentication', 'skipSourceDetection'];\n for (const field of booleanFields) {\n if (cfg[field] !== undefined && typeof cfg[field] !== 'boolean') {\n throw new ValidationError(`${field} must be a boolean`);\n }\n }\n}\n\n/**\n * Clear the config cache (useful for testing)\n */\nexport function clearConfigCache(): void {\n configCache.clear();\n}\n\n/**\n * Get config value from project config\n */\nexport async function getProjectConfigValue<K extends keyof ProjectConfig>(\n key: K\n): Promise<ProjectConfig[K] | undefined> {\n const config = await findProjectConfig();\n return config?.[key];\n}\n\n/**\n * Check if a project config file exists\n */\nexport async function hasProjectConfig(): Promise<boolean> {\n const config = await findProjectConfig();\n return config !== null;\n}\n","import Conf from 'conf';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { APP_NAME, ENCRYPTION_CONFIG, STORAGE_PATHS, DEFAULT_CONFIG } from '../constants.js';\nimport { loadEnvConfig } from '../utils/env-loader.js';\nimport { findProjectConfig } from '../utils/config-loader.js';\nimport type {\n StoredCredentials,\n ServiceCredentials,\n ServiceType,\n UserInfo,\n OAuthState,\n StorageBackend,\n EncryptedData,\n BragduckConfig,\n} from '../types/config.types.js';\n\n/**\n * Storage service for managing credentials and configuration\n * Uses encrypted file storage for credentials\n *\n * NOTE: OS keychain support (via cross-keychain or similar) can be added in the future.\n * For now, we use secure encrypted file storage with machine-specific keys.\n */\nexport class StorageService {\n private config: Conf<BragduckConfig>;\n private storageBackend: StorageBackend;\n private credentialsDir: string;\n private credentialsFilePath: string;\n\n constructor() {\n // Initialize config management\n this.config = new Conf<BragduckConfig>({\n projectName: APP_NAME,\n defaults: DEFAULT_CONFIG,\n });\n\n // Set up credentials directory and file path\n this.credentialsDir = join(homedir(), STORAGE_PATHS.CREDENTIALS_DIR);\n this.credentialsFilePath = join(this.credentialsDir, STORAGE_PATHS.CREDENTIALS_FILE);\n\n // Use file storage for now (keychain support can be added later)\n this.storageBackend = 'file';\n this.ensureCredentialsDir();\n }\n\n /**\n * Ensure credentials directory exists\n */\n private ensureCredentialsDir(): void {\n if (!existsSync(this.credentialsDir)) {\n mkdirSync(this.credentialsDir, { recursive: true, mode: 0o700 });\n }\n }\n\n /**\n * Encrypt data for file storage\n */\n private encrypt(data: string, key: Buffer): EncryptedData {\n const iv = randomBytes(ENCRYPTION_CONFIG.IV_LENGTH);\n const cipher = createCipheriv(ENCRYPTION_CONFIG.ALGORITHM, key, iv, {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n });\n\n let encrypted = cipher.update(data, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n\n const authTag = cipher.getAuthTag();\n\n return {\n encrypted,\n iv: iv.toString('hex'),\n authTag: authTag.toString('hex'),\n salt: '', // Salt is stored separately\n };\n }\n\n /**\n * Decrypt data from file storage\n */\n private decrypt(encryptedData: EncryptedData, key: Buffer): string {\n const decipher = createDecipheriv(\n ENCRYPTION_CONFIG.ALGORITHM,\n key,\n Buffer.from(encryptedData.iv, 'hex'),\n {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n }\n );\n\n decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));\n\n let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n return decrypted;\n }\n\n /**\n * Derive encryption key from machine-specific data\n */\n private deriveEncryptionKey(salt: Buffer): Buffer {\n // Use machine ID and app name as password\n const password = `${APP_NAME}-${homedir()}-${process.platform}`;\n return scryptSync(password, salt, ENCRYPTION_CONFIG.KEY_LENGTH);\n }\n\n /**\n * Store credentials using encrypted file storage\n */\n async setCredentials(credentials: StoredCredentials): Promise<void> {\n const data = JSON.stringify(credentials);\n\n // Encrypt and store credentials\n const salt = randomBytes(ENCRYPTION_CONFIG.SALT_LENGTH);\n const key = this.deriveEncryptionKey(salt);\n const encrypted = this.encrypt(data, key);\n encrypted.salt = salt.toString('hex');\n\n writeFileSync(this.credentialsFilePath, JSON.stringify(encrypted), {\n mode: 0o600,\n encoding: 'utf8',\n });\n }\n\n /**\n * Retrieve credentials from encrypted file storage\n */\n async getCredentials(): Promise<StoredCredentials | null> {\n if (!existsSync(this.credentialsFilePath)) {\n return null;\n }\n\n try {\n const encryptedData: EncryptedData = JSON.parse(\n readFileSync(this.credentialsFilePath, 'utf8')\n );\n const salt = Buffer.from(encryptedData.salt, 'hex');\n const key = this.deriveEncryptionKey(salt);\n const decrypted = this.decrypt(encryptedData, key);\n return JSON.parse(decrypted);\n } catch (error) {\n console.error('Failed to decrypt credentials:', error);\n return null;\n }\n }\n\n /**\n * Delete credentials from file storage\n */\n async deleteCredentials(): Promise<void> {\n // Delete file if it exists\n if (existsSync(this.credentialsFilePath)) {\n try {\n unlinkSync(this.credentialsFilePath);\n } catch (error) {\n console.error('Failed to delete credentials file:', error);\n }\n }\n }\n\n /**\n * Check if user is authenticated (checks bragduck service)\n */\n async isAuthenticated(): Promise<boolean> {\n // Use the service-aware authentication check to support both legacy and multi-service formats\n return this.isServiceAuthenticated('bragduck');\n }\n\n /**\n * Get credentials for a specific service\n */\n async getServiceCredentials(service: ServiceType): Promise<ServiceCredentials | null> {\n const credentials = await this.getCredentials();\n if (!credentials) return null;\n\n // Handle legacy format for bragduck service\n if (service === 'bragduck' && credentials.accessToken && !credentials.services) {\n return {\n accessToken: credentials.accessToken,\n refreshToken: credentials.refreshToken,\n expiresAt: credentials.expiresAt,\n };\n }\n\n return credentials.services?.[service] || null;\n }\n\n /**\n * Set credentials for a specific service\n */\n async setServiceCredentials(service: ServiceType, creds: ServiceCredentials): Promise<void> {\n let existing = await this.getCredentials();\n\n // Migrate legacy format on first new service addition\n if (existing && existing.accessToken && !existing.services) {\n existing = {\n services: {\n bragduck: {\n accessToken: existing.accessToken,\n refreshToken: existing.refreshToken,\n expiresAt: existing.expiresAt,\n },\n },\n };\n }\n\n const updated: StoredCredentials = {\n ...existing,\n services: {\n ...existing?.services,\n [service]: creds,\n },\n };\n\n await this.setCredentials(updated);\n }\n\n /**\n * Delete credentials for a specific service\n */\n async deleteServiceCredentials(service: ServiceType): Promise<void> {\n const existing = await this.getCredentials();\n if (!existing?.services?.[service]) return;\n\n delete existing.services[service];\n await this.setCredentials(existing);\n }\n\n /**\n * Check if a specific service is authenticated\n */\n async isServiceAuthenticated(service: ServiceType): Promise<boolean> {\n const creds = await this.getServiceCredentials(service);\n if (!creds?.accessToken) return false;\n\n // Check expiration\n if (creds.expiresAt && creds.expiresAt < Date.now()) return false;\n\n return true;\n }\n\n /**\n * List all authenticated services\n */\n async getAuthenticatedServices(): Promise<ServiceType[]> {\n const credentials = await this.getCredentials();\n if (!credentials) return [];\n\n // Handle legacy format\n if (credentials.accessToken && !credentials.services) {\n return ['bragduck'];\n }\n\n if (!credentials.services) return [];\n\n const services: ServiceType[] = [];\n for (const [service, creds] of Object.entries(credentials.services)) {\n if (creds?.accessToken) {\n services.push(service as ServiceType);\n }\n }\n\n return services;\n }\n\n /**\n * Store user information\n */\n setUserInfo(userInfo: UserInfo): void {\n this.config.set('userInfo' as keyof BragduckConfig, userInfo as any);\n }\n\n /**\n * Get user information\n */\n getUserInfo(): UserInfo | null {\n return (this.config.get('userInfo' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete user information\n */\n deleteUserInfo(): void {\n this.config.delete('userInfo' as keyof BragduckConfig);\n }\n\n /**\n * Store OAuth state for CSRF protection\n */\n setOAuthState(state: OAuthState): void {\n this.config.set('oauthState' as keyof BragduckConfig, state as any);\n }\n\n /**\n * Get OAuth state\n */\n getOAuthState(): OAuthState | null {\n return (this.config.get('oauthState' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete OAuth state\n */\n deleteOAuthState(): void {\n this.config.delete('oauthState' as keyof BragduckConfig);\n }\n\n /**\n * Get configuration value with hierarchy resolution\n * Priority: env vars > project config > user config > defaults\n */\n async getConfigWithHierarchy<K extends keyof BragduckConfig>(key: K): Promise<BragduckConfig[K]> {\n // 1. Check environment variable\n const envConfig = loadEnvConfig();\n const envKey = key === 'defaultSource' ? 'source' : key;\n if (envConfig[envKey as keyof typeof envConfig] !== undefined) {\n return envConfig[envKey as keyof typeof envConfig] as BragduckConfig[K];\n }\n\n // 2. Check project config\n const projectConfig = await findProjectConfig();\n if (projectConfig && projectConfig[key] !== undefined) {\n return projectConfig[key] as BragduckConfig[K];\n }\n\n // 3. Check user config\n const userValue = this.config.get(key);\n if (userValue !== undefined) {\n return userValue;\n }\n\n // 4. Return default\n return DEFAULT_CONFIG[key] as BragduckConfig[K];\n }\n\n /**\n * Get configuration value (uses hierarchy resolution)\n */\n getConfig<K extends keyof BragduckConfig>(key: K): BragduckConfig[K] {\n return this.config.get(key);\n }\n\n /**\n * Set configuration value\n */\n setConfig<K extends keyof BragduckConfig>(key: K, value: BragduckConfig[K]): void {\n this.config.set(key, value);\n }\n\n /**\n * Get all configuration (merges all layers)\n * Priority: env vars > project config > user config > defaults\n */\n async getAllConfigWithHierarchy(): Promise<BragduckConfig> {\n const envConfig = loadEnvConfig();\n const projectConfig = await findProjectConfig();\n const userConfig = this.config.store;\n\n // Merge all layers with proper priority\n return {\n ...DEFAULT_CONFIG,\n ...userConfig,\n ...projectConfig,\n ...(envConfig.source && { defaultSource: envConfig.source }),\n ...(envConfig.jiraInstance && { jiraInstance: envConfig.jiraInstance }),\n ...(envConfig.confluenceInstance && { confluenceInstance: envConfig.confluenceInstance }),\n ...(envConfig.gitlabInstance && { gitlabInstance: envConfig.gitlabInstance }),\n ...(envConfig.defaultCommitDays !== undefined && {\n defaultCommitDays: envConfig.defaultCommitDays,\n }),\n ...(envConfig.autoVersionCheck !== undefined && {\n autoVersionCheck: envConfig.autoVersionCheck,\n }),\n ...(envConfig.sourcePriority && { sourcePriority: envConfig.sourcePriority }),\n };\n }\n\n /**\n * Get all configuration (user config only)\n */\n getAllConfig(): BragduckConfig {\n return this.config.store;\n }\n\n /**\n * Reset configuration to defaults\n */\n resetConfig(): void {\n this.config.clear();\n // Re-apply defaults (skip undefined values)\n Object.entries(DEFAULT_CONFIG).forEach(([key, value]) => {\n if (value !== undefined) {\n this.config.set(key as keyof BragduckConfig, value as any);\n }\n });\n }\n\n /**\n * Get current storage backend\n */\n getStorageBackend(): StorageBackend {\n return this.storageBackend;\n }\n\n /**\n * Clear all stored data (credentials + config)\n */\n async clearAll(): Promise<void> {\n await this.deleteCredentials();\n this.deleteUserInfo();\n this.deleteOAuthState();\n this.resetConfig();\n }\n}\n\n// Export singleton instance\nexport const storageService = new StorageService();\n","import chalk from 'chalk';\n\n/**\n * Logger utility for consistent console output\n */\nexport const logger = {\n /**\n * Debug message (only shown when DEBUG env var is set)\n */\n debug: (message: string, ...args: any[]): void => {\n if (process.env.DEBUG) {\n console.log(chalk.gray(`[DEBUG] ${message}`), ...args);\n }\n },\n\n /**\n * Info message\n */\n info: (message: string): void => {\n console.log(chalk.blue(`ℹ ${message}`));\n },\n\n /**\n * Success message\n */\n success: (message: string): void => {\n console.log(chalk.green(`✓ ${message}`));\n },\n\n /**\n * Warning message\n */\n warning: (message: string): void => {\n console.warn(chalk.yellow(`⚠ ${message}`));\n },\n\n /**\n * Error message\n */\n error: (message: string): void => {\n console.error(chalk.red(`✗ ${message}`));\n },\n\n /**\n * Plain log without formatting\n */\n log: (message: string): void => {\n console.log(message);\n },\n};\n","import { createServer, type Server, type IncomingMessage, type ServerResponse } from 'http';\nimport { parse } from 'url';\nimport { OAUTH_CONFIG } from '../constants.js';\nimport { OAuthError } from './errors.js';\nimport { logger } from './logger.js';\n\n/**\n * OAuth callback result\n */\nexport interface OAuthCallbackResult {\n code: string;\n state: string;\n port: number;\n}\n\n/**\n * Find an available port in the configured range\n */\nasync function findAvailablePort(): Promise<number> {\n const { MIN_PORT, MAX_PORT } = OAUTH_CONFIG;\n\n for (let port = MIN_PORT; port <= MAX_PORT; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n const testServer = createServer();\n testServer.once('error', reject);\n testServer.once('listening', () => {\n testServer.close(() => resolve());\n });\n testServer.listen(port, '127.0.0.1');\n });\n return port;\n } catch {\n // Port is in use, try next one\n continue;\n }\n }\n\n throw new OAuthError(`No available ports found in range ${MIN_PORT}-${MAX_PORT}`);\n}\n\n/**\n * Success HTML page to show after authentication\n */\nconst SUCCESS_HTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Successful</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .checkmark {\n font-size: 4rem;\n animation: scale-in 0.3s ease-out;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n @keyframes scale-in {\n from { transform: scale(0); }\n to { transform: scale(1); }\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"checkmark\">✓</div>\n <h1>Authentication Successful!</h1>\n <p>You can now close this window and return to your terminal.</p>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Error HTML page to show on authentication failure\n */\nconst ERROR_HTML = (error: string) => `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Failed</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .error-icon {\n font-size: 4rem;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n .error-details {\n background: rgba(0, 0, 0, 0.2);\n padding: 1rem;\n border-radius: 0.5rem;\n font-family: monospace;\n font-size: 0.9rem;\n margin-top: 1rem;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"error-icon\">✗</div>\n <h1>Authentication Failed</h1>\n <p>Please return to your terminal and try again.</p>\n <div class=\"error-details\">${error}</div>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Start OAuth callback server and wait for callback\n */\nexport async function startOAuthCallbackServer(\n expectedState: string\n): Promise<OAuthCallbackResult> {\n const port = await findAvailablePort();\n const timeout = OAUTH_CONFIG.TIMEOUT_MS;\n\n return new Promise<OAuthCallbackResult>((resolve, reject) => {\n let server: Server | null = null;\n let timeoutId: ReturnType<typeof globalThis.setTimeout> | null = null;\n\n const cleanup = () => {\n if (timeoutId) {\n globalThis.clearTimeout(timeoutId);\n }\n if (server) {\n // Close all connections immediately (Node.js 18+)\n if (typeof (server as any).closeAllConnections === 'function') {\n (server as any).closeAllConnections();\n }\n server.close(() => {\n logger.debug('OAuth server closed');\n });\n server.unref(); // Allow process to exit even if server is still running\n }\n };\n\n const handleRequest = (req: IncomingMessage, res: ServerResponse) => {\n const parsedUrl = parse(req.url || '', true);\n\n logger.debug(`OAuth callback received: ${req.url}`);\n\n // Handle callback request\n if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {\n const { code, state, error, error_description } = parsedUrl.query;\n\n // Check for OAuth errors\n if (error) {\n const errorMsg = error_description || error;\n logger.debug(`OAuth error: ${errorMsg}`);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(String(errorMsg)));\n\n cleanup();\n reject(new OAuthError(`OAuth error: ${errorMsg}`));\n return;\n }\n\n // Validate required parameters\n if (!code || !state) {\n const errorMsg = 'Missing code or state parameter';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Verify state matches (CSRF protection)\n if (state !== expectedState) {\n const errorMsg = 'Invalid state parameter (possible CSRF attack)';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Success!\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(SUCCESS_HTML);\n\n // Give the response time to be sent before closing\n globalThis.setTimeout(() => {\n cleanup();\n resolve({\n code: String(code),\n state: String(state),\n port,\n });\n }, 100);\n return;\n }\n\n // Handle other requests (404)\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n };\n\n // Create server\n server = createServer(handleRequest);\n\n // Handle server errors\n server.on('error', (error) => {\n logger.debug(`OAuth server error: ${error.message}`);\n cleanup();\n reject(new OAuthError(`OAuth server error: ${error.message}`));\n });\n\n // Start server\n server.listen(port, '127.0.0.1', () => {\n logger.debug(\n `OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`\n );\n });\n\n // Set timeout\n timeoutId = globalThis.setTimeout(() => {\n logger.debug('OAuth callback timeout');\n cleanup();\n reject(new OAuthError('Authentication timeout - no callback received within 2 minutes'));\n }, timeout);\n });\n}\n\n/**\n * Get the callback URL for the OAuth flow\n */\nexport async function getCallbackUrl(): Promise<string> {\n const port = await findAvailablePort();\n return `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { logger } from './logger.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Open a URL in the default browser\n */\nexport async function openBrowser(url: string): Promise<void> {\n const platform = process.platform;\n let command: string;\n\n // Determine the command based on the platform\n switch (platform) {\n case 'darwin': // macOS\n command = `open \"${url}\"`;\n break;\n case 'win32': // Windows\n command = `start \"\" \"${url}\"`;\n break;\n default: // Linux and others\n command = `xdg-open \"${url}\"`;\n break;\n }\n\n try {\n logger.debug(`Opening browser with command: ${command}`);\n await execAsync(command);\n logger.debug('Browser opened successfully');\n } catch (error) {\n logger.debug(`Failed to open browser: ${error}`);\n throw new Error(`Failed to open browser automatically. Please open this URL manually:\\n${url}`);\n }\n}\n","import { randomBytes } from 'crypto';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath, URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { ofetch } from 'ofetch';\nimport { OAUTH_CONFIG, API_ENDPOINTS } from '../constants.js';\nimport { storageService } from './storage.service.js';\nimport { startOAuthCallbackServer, getCallbackUrl } from '../utils/oauth-server.js';\nimport { openBrowser } from '../utils/browser.js';\nimport { AuthenticationError, NetworkError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type { ServiceCredentials, UserInfo } from '../types/config.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version and User-Agent string\n */\nfunction getUserAgent(): string {\n try {\n // In production (dist/services/auth.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const version = packageJson.version;\n const platform = process.platform;\n const arch = process.arch;\n return `BragDuck-CLI/${version} (${platform}-${arch})`;\n } catch {\n logger.debug('Failed to read package.json version');\n return 'BragDuck-CLI/2.0.0';\n }\n}\n\n/**\n * Token exchange response from the backend\n */\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type: string;\n user?: UserInfo;\n}\n\n/**\n * Authentication service for managing OAuth flow and tokens\n */\nexport class AuthService {\n private apiBaseUrl: string;\n\n constructor() {\n // Use environment variable or default API URL\n this.apiBaseUrl = process.env.API_BASE_URL || 'https://api.bragduck.com';\n }\n\n /**\n * Generate a random state string for CSRF protection\n */\n private generateState(): string {\n return randomBytes(32).toString('hex');\n }\n\n /**\n * Build the OAuth authorization URL\n */\n private async buildAuthUrl(state: string, callbackUrl: string): Promise<string> {\n const params = new URLSearchParams({\n client_id: OAUTH_CONFIG.CLIENT_ID,\n redirect_uri: callbackUrl,\n state,\n });\n\n return `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.INITIATE}?${params.toString()}`;\n }\n\n /**\n * Exchange authorization code for access token\n */\n private async exchangeCodeForToken(code: string, callbackUrl: string): Promise<TokenResponse> {\n try {\n logger.debug('Exchanging authorization code for token');\n\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n code,\n redirect_uri: callbackUrl,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'authorization_code',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n logger.debug('Token exchange successful');\n return response;\n } catch (error: any) {\n logger.debug(`Token exchange failed: ${error.message}`);\n\n if (error.response) {\n throw new AuthenticationError(\n `Token exchange failed: ${error.response.statusText || 'Unknown error'}`,\n {\n statusCode: error.response.status,\n body: error.response._data,\n }\n );\n }\n\n throw new NetworkError('Failed to connect to authentication server', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Complete OAuth flow: start server, open browser, wait for callback, exchange token\n */\n async login(): Promise<UserInfo> {\n logger.debug('Starting OAuth login flow');\n\n // Generate state for CSRF protection\n const state = this.generateState();\n const callbackUrl = await getCallbackUrl();\n\n // Store state temporarily\n storageService.setOAuthState({\n state,\n createdAt: Date.now(),\n });\n\n logger.debug(`OAuth state: ${state}`);\n logger.debug(`Callback URL: ${callbackUrl}`);\n\n // Build authorization URL\n const authUrl = await this.buildAuthUrl(state, callbackUrl);\n logger.debug(`Authorization URL: ${authUrl}`);\n\n // Start callback server (this will wait for the callback)\n const serverPromise = startOAuthCallbackServer(state);\n\n // Open browser\n try {\n await openBrowser(authUrl);\n } catch {\n // If browser opening fails, show the URL for manual opening\n logger.warning('Could not open browser automatically');\n logger.info(`Please open this URL in your browser:`);\n logger.log(authUrl);\n }\n\n // Wait for callback\n let callbackResult;\n try {\n callbackResult = await serverPromise;\n } catch (error: any) {\n storageService.deleteOAuthState();\n throw error;\n }\n\n // Clear OAuth state\n storageService.deleteOAuthState();\n\n // Exchange code for token\n const tokenResponse = await this.exchangeCodeForToken(callbackResult.code, callbackUrl);\n\n // Calculate expiration time\n const expiresAt = tokenResponse.expires_in\n ? Date.now() + tokenResponse.expires_in * 1000\n : undefined;\n\n // Store credentials for bragduck service\n const credentials: ServiceCredentials = {\n accessToken: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresAt,\n };\n await storageService.setServiceCredentials('bragduck', credentials);\n\n // Store user info if provided\n if (tokenResponse.user) {\n storageService.setUserInfo(tokenResponse.user);\n }\n\n logger.debug('Login successful');\n\n return tokenResponse.user || { id: 'unknown', email: 'unknown', name: 'Unknown User' };\n }\n\n /**\n * Logout: clear all stored credentials and user info\n */\n async logout(): Promise<void> {\n logger.debug('Logging out');\n\n await storageService.deleteCredentials();\n storageService.deleteUserInfo();\n storageService.deleteOAuthState();\n\n logger.debug('Logout complete');\n }\n\n /**\n * Check if user is authenticated\n */\n async isAuthenticated(): Promise<boolean> {\n return storageService.isAuthenticated();\n }\n\n /**\n * Get current access token\n */\n async getAccessToken(): Promise<string | null> {\n const credentials = await storageService.getServiceCredentials('bragduck');\n return credentials?.accessToken || null;\n }\n\n /**\n * Get current user info\n */\n getUserInfo(): UserInfo | null {\n return storageService.getUserInfo();\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refreshToken(): Promise<void> {\n logger.debug('Refreshing access token');\n\n const credentials = await storageService.getServiceCredentials('bragduck');\n if (!credentials?.refreshToken) {\n throw new AuthenticationError('No refresh token available');\n }\n\n try {\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n refresh_token: credentials.refreshToken,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'refresh_token',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n // Calculate expiration time\n const expiresAt = response.expires_in ? Date.now() + response.expires_in * 1000 : undefined;\n\n // Update stored credentials for bragduck service\n const newCredentials: ServiceCredentials = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token || credentials.refreshToken,\n expiresAt,\n };\n await storageService.setServiceCredentials('bragduck', newCredentials);\n\n logger.debug('Token refresh successful');\n } catch (error: any) {\n logger.debug(`Token refresh failed: ${error.message}`);\n\n // If refresh fails, user needs to re-authenticate\n await this.logout();\n throw new AuthenticationError(\n 'Bragduck platform token refresh failed. Please run \"bragduck auth login\" to re-authenticate.'\n );\n }\n }\n}\n\n// Export singleton instance\nexport const authService = new AuthService();\n","import { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport chalk from 'chalk';\nimport boxen from 'boxen';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from './logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get current CLI version from package.json\n */\nexport function getCurrentVersion(): string {\n try {\n // In production (dist/utils/version.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '1.0.0'; // Fallback version\n }\n}\n\n/**\n * Export current version\n */\nexport const version = getCurrentVersion();\n\n/**\n * Compare two semantic versions\n * Returns:\n * 1 if v1 > v2\n * 0 if v1 === v2\n * -1 if v1 < v2\n */\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map((p) => parseInt(p, 10));\n const parts2 = v2.split('.').map((p) => parseInt(p, 10));\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 > part2) return 1;\n if (part1 < part2) return -1;\n }\n\n return 0;\n}\n\n/**\n * Check if a newer version is available\n */\nexport async function checkForUpdates(\n options: {\n silent?: boolean;\n force?: boolean;\n } = {}\n): Promise<{ updateAvailable: boolean; latestVersion: string; currentVersion: string }> {\n const { silent = false, force = false } = options;\n\n try {\n // Skip version check if disabled in config (unless forced)\n if (!force) {\n const autoVersionCheck = storageService.getConfig('autoVersionCheck');\n if (!autoVersionCheck) {\n logger.debug('Version check disabled in config');\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n }\n\n logger.debug('Checking for CLI updates...');\n\n // Check via API service\n const response = await apiService.checkVersion();\n const latestVersion = response.latest_version;\n const currentVersion = version;\n\n logger.debug(`Current version: ${currentVersion}, Latest version: ${latestVersion}`);\n\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;\n\n // Display update notification if not silent and update is available\n if (!silent && updateAvailable) {\n displayUpdateNotification(currentVersion, latestVersion, response.critical_update);\n }\n\n return {\n updateAvailable,\n latestVersion,\n currentVersion,\n };\n } catch (error: any) {\n logger.debug(`Version check failed: ${error.message}`);\n // Don't throw error - version check is non-critical\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n}\n\n/**\n * Display update notification\n */\nfunction displayUpdateNotification(\n currentVersion: string,\n latestVersion: string,\n critical: boolean = false\n): void {\n const urgency = critical\n ? chalk.red.bold('CRITICAL UPDATE')\n : chalk.yellow.bold('Update Available');\n const message =\n `${urgency}\\n\\n` +\n `Current version: ${chalk.dim(currentVersion)}\\n` +\n `Latest version: ${chalk.green(latestVersion)}\\n\\n` +\n `Update with: ${chalk.cyan('npm install -g @bragduck/cli@latest')}`;\n\n console.log('');\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 0, right: 1, bottom: 0, left: 1 },\n borderStyle: 'round',\n borderColor: critical ? 'red' : 'yellow',\n })\n );\n console.log('');\n\n if (critical) {\n logger.warning('This is a critical update. Please update as soon as possible.');\n console.log('');\n }\n}\n\n/**\n * Format version for display\n */\nexport function formatVersion(includePrefix: boolean = true): string {\n const prefix = includePrefix ? 'v' : '';\n return `${prefix}${version}`;\n}\n","import { ofetch, type FetchOptions } from 'ofetch';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { authService } from './auth.service.js';\nimport { API_ENDPOINTS, HTTP_STATUS } from '../constants.js';\nimport { ApiError, NetworkError, TokenExpiredError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type {\n RefineCommitsRequest,\n RefineCommitsResponse,\n RefineBragsRequest,\n RefineBragsResponse,\n CreateBragsRequest,\n CreateBragsResponse,\n ListBragsParams,\n ListBragsResponse,\n GetSubscriptionStatusResponse,\n VersionCheckResponse,\n ApiErrorResponse,\n ListOrganisationsResponse,\n} from '../types/api.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version from package.json\n */\nfunction getCliVersion(): string {\n try {\n // In production (dist/services/api.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '2.0.0'; // Fallback version\n }\n}\n\n/**\n * Get platform information for User-Agent\n */\nfunction getPlatformInfo(): string {\n const platform = process.platform; // darwin, linux, win32, etc.\n const arch = process.arch; // arm64, x64, etc.\n return `${platform}-${arch}`;\n}\n\n/**\n * API service for communicating with the Bragduck backend\n */\nexport class ApiService {\n private baseURL: string;\n private client: typeof ofetch;\n\n constructor() {\n // Use environment variable or default API URL\n this.baseURL = process.env.API_BASE_URL || 'https://api.bragduck.com';\n\n // Create ofetch client with interceptors\n this.client = ofetch.create({\n baseURL: this.baseURL,\n\n // Request interceptor\n onRequest: async ({ request, options }) => {\n logger.debug(`API Request: ${options.method || 'GET'} ${request}`);\n\n // Add User-Agent header for CLI identification\n const cliVersion = getCliVersion();\n const platform = getPlatformInfo();\n const userAgent = `BragDuck-CLI/${cliVersion} (${platform})`;\n\n // Add authentication header\n const token = await authService.getAccessToken();\n\n // Create new headers object\n const newHeaders: Record<string, string> = {\n 'User-Agent': userAgent,\n };\n\n // Copy existing headers if any\n if (options.headers) {\n if (typeof options.headers === 'object' && !Array.isArray(options.headers)) {\n Object.entries(options.headers).forEach(([key, value]) => {\n if (typeof value === 'string') {\n newHeaders[key] = value;\n }\n });\n }\n }\n\n if (token) {\n newHeaders.Authorization = `Bearer ${token}`;\n }\n\n // Ensure Content-Type is set for POST/PUT requests\n if (options.method && ['POST', 'PUT', 'PATCH'].includes(options.method)) {\n newHeaders['Content-Type'] = 'application/json';\n }\n\n options.headers = newHeaders as any;\n },\n\n // Response interceptor for success\n onResponse: ({ response }) => {\n logger.debug(`API Response: ${response.status} ${response.statusText}`);\n },\n\n // Response interceptor for errors\n onResponseError: async ({ request, response }) => {\n const status = response.status;\n\n logger.debug(`API Error: ${status} ${response.statusText} - ${request}`);\n\n // Handle 401 Unauthorized - token expired\n if (status === HTTP_STATUS.UNAUTHORIZED) {\n logger.debug('Token expired, attempting refresh');\n\n try {\n // Try to refresh the token\n await authService.refreshToken();\n\n // Retry the request once with the new token\n logger.debug('Token refreshed, retrying request');\n throw new Error('RETRY_WITH_NEW_TOKEN');\n } catch (error: any) {\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n throw error;\n }\n // If refresh fails, throw TokenExpiredError\n throw new TokenExpiredError(\n 'Your Bragduck platform session has expired. Please run \"bragduck auth login\" to re-authenticate.'\n );\n }\n }\n\n // Parse error response\n let errorMessage = 'An unexpected error occurred';\n let errorDetails: Record<string, any> | undefined;\n\n try {\n const errorData = response._data as ApiErrorResponse;\n if (errorData && errorData.message) {\n errorMessage = errorData.message;\n errorDetails = errorData.details;\n }\n } catch {\n // If we can't parse error, use status text\n errorMessage = response.statusText || errorMessage;\n }\n\n throw new ApiError(errorMessage, status, errorDetails);\n },\n\n // Retry configuration\n retry: 2,\n retryDelay: 1000,\n retryStatusCodes: [408, 409, 425, 429, 500, 502, 503, 504],\n\n // Timeout\n timeout: 30000, // 30 seconds\n });\n }\n\n /**\n * Make API request with retry for token refresh\n */\n private async makeRequest<T>(url: string, options: FetchOptions = {}): Promise<T> {\n try {\n return (await this.client(url, options)) as Promise<T>;\n } catch (error: any) {\n // If we got the special retry signal, retry the request once\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n logger.debug('Retrying request with refreshed token');\n return (await this.client(url, options)) as Promise<T>;\n }\n\n // Handle network errors\n if (error.name === 'FetchError' || error.code === 'ECONNREFUSED') {\n throw new NetworkError('Failed to connect to Bragduck API', {\n originalError: error.message,\n baseURL: this.baseURL,\n });\n }\n\n throw error;\n }\n }\n\n /**\n * Refine brags using AI\n */\n async refineBrags(request: RefineBragsRequest): Promise<RefineBragsResponse> {\n const MAX_TEXT_LENGTH = 10000;\n\n const trimmedRequest = {\n ...request,\n brags: request.brags.map((brag: RefineBragsRequest['brags'][number]) => ({\n ...brag,\n text:\n brag.text && brag.text.length > MAX_TEXT_LENGTH\n ? brag.text.substring(0, MAX_TEXT_LENGTH)\n : brag.text,\n })),\n };\n\n logger.debug(`Refining ${trimmedRequest.brags.length} brags`);\n\n try {\n const response = await this.makeRequest<RefineBragsResponse>(API_ENDPOINTS.BRAGS.REFINE, {\n method: 'POST',\n body: trimmedRequest,\n });\n\n logger.debug(`Successfully refined ${response.refined_brags.length} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine brags');\n throw _error;\n }\n }\n\n /**\n * @deprecated Use refineBrags() instead. Will be removed in v3.0.0\n * Refine commits using AI (legacy endpoint)\n */\n async refineCommits(request: RefineCommitsRequest): Promise<RefineCommitsResponse> {\n logger.debug(`[DEPRECATED] Using legacy refineCommits - migrate to refineBrags`);\n logger.debug(`Refining ${request.commits.length} commits`);\n\n try {\n const response = await this.makeRequest<RefineCommitsResponse>(API_ENDPOINTS.COMMITS.REFINE, {\n method: 'POST',\n body: request,\n });\n\n logger.debug(`Successfully refined ${response.refined_commits.length} commits`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine commits');\n throw _error;\n }\n }\n\n /**\n * Create brags from refined commits\n */\n async createBrags(request: CreateBragsRequest): Promise<CreateBragsResponse> {\n logger.debug(`Creating ${request.brags.length} brags`);\n logger.debug(`Request body: ${JSON.stringify(request, null, 2)}`);\n\n try {\n const response = await this.makeRequest<CreateBragsResponse>(API_ENDPOINTS.BRAGS.CREATE, {\n method: 'POST',\n body: request,\n });\n logger.debug(`Response: ${JSON.stringify(response, null, 2)}`);\n\n logger.debug(`Successfully created ${response.created} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to create brags');\n throw _error;\n }\n }\n\n /**\n * List existing brags\n */\n async listBrags(params: ListBragsParams = {}): Promise<ListBragsResponse> {\n const { limit = 50, offset = 0, tags, search } = params;\n\n logger.debug(`Listing brags: limit=${limit}, offset=${offset}`);\n\n try {\n // Build query parameters\n const queryParams = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (search) {\n queryParams.append('search', search);\n }\n\n if (tags && tags.length > 0) {\n tags.forEach((tag) => queryParams.append('tags[]', tag));\n }\n\n const url = `${API_ENDPOINTS.BRAGS.LIST}?${queryParams.toString()}`;\n\n const response = await this.makeRequest<ListBragsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(\n `Successfully fetched ${response.brags.length} brags (total: ${response.total})`\n );\n return response;\n } catch (_error) {\n logger.debug('Failed to list brags');\n throw _error;\n }\n }\n\n /**\n * List user's organisations\n */\n async listUserOrganisations(userId: string): Promise<ListOrganisationsResponse> {\n logger.debug(`Listing organisations for user: ${userId}`);\n\n try {\n const url = API_ENDPOINTS.ORGANISATIONS.LIST.replace('{userId}', userId);\n\n const response = await this.makeRequest<ListOrganisationsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(`Successfully fetched ${response.items.length} organisations`);\n return response;\n } catch (_error) {\n logger.debug('Failed to list organisations');\n throw _error;\n }\n }\n\n /**\n * Get user's subscription status\n */\n async getSubscriptionStatus(): Promise<GetSubscriptionStatusResponse> {\n logger.debug(`Fetching subscription status from ${API_ENDPOINTS.SUBSCRIPTION.STATUS}`);\n\n try {\n const response = await this.makeRequest<{\n status: string;\n data: GetSubscriptionStatusResponse;\n }>(API_ENDPOINTS.SUBSCRIPTION.STATUS, {\n method: 'GET',\n });\n\n logger.debug(`Subscription API response: ${JSON.stringify(response)}`);\n\n // Unwrap the response - API returns { status: \"success\", data: {...} }\n const subscriptionData = response.data;\n\n logger.debug(\n `Subscription tier: ${subscriptionData.tier}, status: ${subscriptionData.status}`\n );\n return subscriptionData;\n } catch (error) {\n logger.debug(`Failed to fetch subscription status: ${error}`);\n logger.debug(`Error details: ${JSON.stringify(error, null, 2)}`);\n throw error;\n }\n }\n\n /**\n * Check for CLI updates\n */\n async checkVersion(): Promise<VersionCheckResponse> {\n logger.debug('Checking for CLI updates');\n\n try {\n const response = await this.makeRequest<VersionCheckResponse>(API_ENDPOINTS.VERSION, {\n method: 'GET',\n });\n\n logger.debug(`Latest version: ${response.latest_version}`);\n return response;\n } catch {\n logger.debug('Failed to check version');\n // Don't throw error for version check failures\n // Return current version as fallback\n const { version } = await import('../utils/version.js');\n return {\n latest_version: version,\n critical_update: false,\n };\n }\n }\n\n /**\n * Test API connectivity\n */\n async testConnection(): Promise<boolean> {\n try {\n await this.checkVersion();\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Update base URL\n */\n setBaseURL(url: string): void {\n this.baseURL = url;\n // Recreate client with new base URL\n this.client = ofetch.create({\n baseURL: url,\n });\n }\n\n /**\n * Get current base URL\n */\n getBaseURL(): string {\n return this.baseURL;\n }\n}\n\n// Export singleton instance\nexport const apiService = new ApiService();\n","import { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { authCommand } from './commands/auth.js';\nimport { syncCommand } from './commands/sync.js';\nimport { initCommand } from './commands/init.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { scanCommand } from './commands/scan.js';\nimport { listCommand } from './commands/list.js';\nimport { configCommand } from './commands/config.js';\nimport { checkForUpdates } from './utils/version.js';\nimport { logger } from './utils/logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read package.json for version (go up two levels from dist/bin/)\nconst packageJsonPath = join(__dirname, '../../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('bragduck')\n .description('CLI tool for managing developer achievements and brags\\nAliases: bd, duck, brag')\n .version(packageJson.version, '-v, --version', 'Display version number')\n .helpOption('-h, --help', 'Display help information')\n .option('--skip-version-check', 'Skip automatic version check on startup')\n .option('--debug', 'Enable debug mode (shows detailed logs)');\n\n// Auth command - Unified authentication (NEW)\nprogram\n .command('auth [subcommand]')\n .description('Manage authentication (subcommands: login, status, bitbucket, gitlab)')\n .action(async (subcommand) => {\n try {\n await authCommand(subcommand);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Sync command - Unified work item sync (NEW)\nprogram\n .command('sync')\n .description('Sync work items and create brags')\n .option('-d, --days <number>', 'Number of days to scan', (val) => parseInt(val, 10))\n .option('-a, --all', 'Include all items (not just current user)')\n .option('-s, --source <type>', 'Explicit source type (github)')\n .action(async (options) => {\n try {\n await syncCommand(options);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Init command - OAuth authentication (DEPRECATED)\nprogram\n .command('init')\n .description('Authenticate with Bragduck')\n .action(async () => {\n try {\n await initCommand();\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Scan command - Interactive commit selection and brag creation (DEPRECATED)\nprogram\n .command('scan')\n .description('Scan git commits and create brags (deprecated, use sync)')\n .option('-d, --days <number>', 'Number of days to scan', (val) => parseInt(val, 10))\n .option('-a, --all', 'Include all commits (not just current user)')\n .action(async (options) => {\n try {\n await scanCommand(options);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// List command - Display existing brags\nprogram\n .command('list')\n .description('List your existing brags')\n .option('-l, --limit <number>', 'Number of brags to display', (val) => parseInt(val, 10), 50)\n .option('-o, --offset <number>', 'Number of brags to skip', (val) => parseInt(val, 10), 0)\n .option('-t, --tags <tags>', 'Filter by tags (comma-separated)')\n .option('-s, --search <query>', 'Search brags by keyword')\n .option('--oneline', 'Show only date and title for each brag')\n .action(async (options) => {\n try {\n await listCommand(options);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Logout command - Clear credentials\nprogram\n .command('logout')\n .description('Clear stored credentials')\n .action(async () => {\n try {\n await logoutCommand();\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Config command - Manage CLI configuration\nprogram\n .command('config [subcommand] [key] [value]')\n .description('Manage CLI configuration (subcommands: list, get, set)')\n .action(async (subcommand, key, value) => {\n try {\n await configCommand(subcommand, key, value);\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n });\n\n// Hook to run before any command execution\nprogram.hook('preAction', async () => {\n const options = program.opts();\n\n // Enable debug mode if --debug flag is set\n if (options.debug) {\n process.env.DEBUG = 'true';\n logger.debug('Debug mode enabled');\n }\n\n // Check for updates (unless --skip-version-check is set or --version/--help is used)\n const isVersionOrHelp =\n process.argv.includes('--version') ||\n process.argv.includes('-v') ||\n process.argv.includes('--help') ||\n process.argv.includes('-h');\n\n if (!options.skipVersionCheck && !isVersionOrHelp) {\n try {\n await checkForUpdates({ silent: false });\n } catch {\n // Non-critical, continue execution\n logger.debug('Version check failed, continuing...');\n }\n }\n});\n\n// Parse command line arguments\nprogram.parse(process.argv);\n\n// Show help if no command is provided\nif (!process.argv.slice(2).length) {\n program.outputHelp();\n}\n","import boxen from 'boxen';\nimport chalk from 'chalk';\nimport { input } from '@inquirer/prompts';\nimport { authService } from '../services/auth.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { githubService } from '../services/github.service.js';\nimport { logger } from '../utils/logger.js';\nimport { theme, colors, boxStyles } from '../ui/theme.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport type { ServiceCredentials } from '../types/config.types.js';\nimport type { BitbucketUser } from '../types/bitbucket.types.js';\nimport type { GitLabUser } from '../types/gitlab.types.js';\n\n/**\n * Auth command: Unified authentication management\n */\nexport async function authCommand(subcommand?: string): Promise<void> {\n // Default to login if no subcommand\n if (!subcommand || subcommand === 'login') {\n await authLogin();\n } else if (subcommand === 'status') {\n await authStatus();\n } else if (subcommand === 'bitbucket') {\n await authBitbucket();\n } else if (subcommand === 'gitlab') {\n await authGitLab();\n } else if (subcommand === 'atlassian') {\n await authAtlassian();\n } else {\n logger.error(`Unknown auth subcommand: ${subcommand}`);\n logger.info('Available subcommands: login, status, bitbucket, gitlab, atlassian');\n process.exit(1);\n }\n}\n\n/**\n * Auth login: Authenticate with Bragduck\n */\nasync function authLogin(): Promise<void> {\n logger.log('');\n logger.info('Authenticating with Bragduck...');\n logger.log('');\n\n // Check if already authenticated\n const isAuthenticated = await storageService.isServiceAuthenticated('bragduck');\n if (isAuthenticated) {\n const userInfo = authService.getUserInfo();\n if (userInfo) {\n logger.log(\n boxen(\n `${chalk.yellow('Already authenticated!')}\\n\\n` +\n `${chalk.gray('User:')} ${userInfo.name}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('Run')} ${chalk.cyan('bragduck logout')} ${chalk.dim('to sign out')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n }\n )\n );\n logger.log('');\n return;\n }\n }\n\n // Perform OAuth login\n try {\n const userInfo = await authService.login();\n\n logger.log('');\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Successfully authenticated!')}\\n\\n` +\n `${chalk.gray('Welcome,')} ${chalk.cyan(userInfo.name)}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('Use')} ${chalk.cyan('bragduck sync')} ${chalk.dim('to create brags')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(`${chalk.red.bold('✗ Authentication Failed')}\\n\\n` + `${err.message}`, {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'red',\n })\n );\n process.exit(1);\n }\n}\n\n/**\n * Auth status: Show authentication status for all services\n */\nasync function authStatus(): Promise<void> {\n logger.log('');\n logger.info('Authentication Status:');\n logger.log('');\n\n const services = await storageService.getAuthenticatedServices();\n\n // Show Bragduck status\n const bragduckAuth = await storageService.isServiceAuthenticated('bragduck');\n if (bragduckAuth) {\n const userInfo = authService.getUserInfo();\n logger.info(`${colors.success('✓')} Bragduck: ${userInfo?.name || 'Authenticated'}`);\n } else {\n logger.info(`${colors.error('✗')} Bragduck: Not authenticated`);\n }\n\n // Show GitHub CLI status (external tool)\n const ghStatus = await githubService.getAuthStatus();\n if (ghStatus.installed) {\n if (ghStatus.authenticated) {\n logger.info(`${colors.success('✓')} GitHub CLI (gh): Authenticated`);\n } else {\n logger.info(`${colors.error('✗')} GitHub CLI (gh): Not authenticated`);\n logger.info(theme.secondary(' Run: gh auth login'));\n }\n } else {\n logger.info(`${colors.error('✗')} GitHub CLI (gh): Not installed`);\n logger.info(theme.secondary(' Install from: https://cli.github.com'));\n }\n\n // Show other services (GitHub, etc.)\n for (const service of services) {\n if (service !== 'bragduck') {\n logger.info(`${colors.success('✓')} ${service}: Authenticated`);\n }\n }\n\n logger.log('');\n\n // Show help message if no services authenticated\n if (services.length === 0) {\n logger.info(`Run ${theme.command('bragduck auth login')} to authenticate with Bragduck`);\n logger.log('');\n }\n}\n\n/**\n * Auth Bitbucket: Authenticate with Bitbucket using API Token\n */\nasync function authBitbucket(): Promise<void> {\n logger.log('');\n logger.log(\n boxen(\n theme.info('Bitbucket API Token Authentication') +\n '\\n\\n' +\n 'Create an API Token at:\\n' +\n colors.highlight('https://bitbucket.org/account/settings/api-token/new') +\n '\\n\\n' +\n 'Required scopes:\\n' +\n ' • pullrequest:read\\n' +\n ' • repository:read\\n' +\n ' • account:read\\n\\n' +\n theme.warning('Note: API tokens expire (max 1 year)'),\n boxStyles.info\n )\n );\n logger.log('');\n\n try {\n const email = await input({\n message: 'Atlassian account email:',\n validate: (value) => (value.includes('@') ? true : 'Please enter a valid email address'),\n });\n\n const apiToken = await input({\n message: 'API Token:',\n validate: (value) => (value.length > 0 ? true : 'API token cannot be empty'),\n });\n\n const tokenExpiry = await input({\n message: 'Token expiry date (YYYY-MM-DD, optional):',\n default: '',\n validate: (value) => {\n if (!value) return true; // Optional\n const date = new Date(value);\n return !isNaN(date.getTime()) ? true : 'Please enter a valid date (YYYY-MM-DD)';\n },\n });\n\n // Test credentials by fetching user info\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n const response = await fetch('https://api.bitbucket.org/2.0/user', {\n headers: { Authorization: `Basic ${auth}` },\n });\n\n if (!response.ok) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + 'Invalid email or API token',\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n\n const user = (await response.json()) as BitbucketUser;\n\n // Store credentials\n const credentials: ServiceCredentials = {\n accessToken: apiToken,\n username: email, // Store email in username field\n };\n\n // Add expiry if provided\n if (tokenExpiry) {\n const expiryDate = new Date(tokenExpiry);\n credentials.expiresAt = expiryDate.getTime();\n }\n\n await storageService.setServiceCredentials('bitbucket', credentials);\n\n logger.log('');\n logger.log(\n boxen(\n theme.success('✓ Successfully authenticated with Bitbucket') +\n '\\n\\n' +\n `Email: ${email}\\n` +\n `User: ${user.display_name}\\n` +\n (tokenExpiry ? `Expires: ${tokenExpiry}` : ''),\n boxStyles.success\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + (err.message || 'Unknown error'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n\n/**\n * Auth GitLab: Authenticate with GitLab using Personal Access Token\n */\nasync function authGitLab(): Promise<void> {\n logger.log('');\n logger.log(\n boxen(\n theme.info('GitLab Personal Access Token Authentication') +\n '\\n\\n' +\n 'Create a Personal Access Token at:\\n' +\n colors.highlight('https://gitlab.com/-/profile/personal_access_tokens') +\n '\\n\\n' +\n 'Required scopes:\\n' +\n ' • api (full API access)\\n' +\n ' • read_api (read API)\\n' +\n ' • read_user (read user info)\\n\\n' +\n theme.warning('For self-hosted GitLab, check your instance docs'),\n boxStyles.info\n )\n );\n logger.log('');\n\n try {\n const instanceUrl = await input({\n message: 'GitLab instance URL (press Enter for gitlab.com):',\n default: 'https://gitlab.com',\n });\n\n const accessToken = await input({\n message: 'Personal Access Token:',\n validate: (value) => (value.length > 0 ? true : 'Token cannot be empty'),\n });\n\n // Test credentials by fetching user info\n const testUrl = `${instanceUrl.replace(/\\/$/, '')}/api/v4/user`;\n const response = await fetch(testUrl, {\n headers: { 'PRIVATE-TOKEN': accessToken },\n });\n\n if (!response.ok) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + 'Invalid instance URL or access token',\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n\n const user = (await response.json()) as GitLabUser;\n\n // Store credentials\n const credentials: ServiceCredentials = {\n accessToken,\n instanceUrl: instanceUrl === 'https://gitlab.com' ? undefined : instanceUrl,\n };\n\n await storageService.setServiceCredentials('gitlab', credentials);\n\n logger.log('');\n logger.log(\n boxen(\n theme.success('✓ Successfully authenticated with GitLab') +\n '\\n\\n' +\n `Instance: ${instanceUrl}\\n` +\n `User: ${user.name} (@${user.username})`,\n boxStyles.success\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + (err.message || 'Unknown error'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n\n/**\n * Auth Atlassian: Authenticate with Atlassian services (Jira, Confluence, Bitbucket)\n */\nasync function authAtlassian(): Promise<void> {\n logger.log('');\n logger.log(\n boxen(\n theme.info('Atlassian API Token Authentication') +\n '\\n\\n' +\n 'This token works for Jira, Confluence, and Bitbucket\\n\\n' +\n 'Create an API Token at:\\n' +\n colors.highlight('https://id.atlassian.com/manage-profile/security/api-tokens') +\n '\\n\\n' +\n 'Required access:\\n' +\n ' • Jira: Read issues\\n' +\n ' • Confluence: Read pages\\n' +\n ' • Bitbucket: Read repositories',\n boxStyles.info\n )\n );\n logger.log('');\n\n try {\n const instanceUrl = await input({\n message: 'Atlassian instance URL (e.g., company.atlassian.net):',\n validate: (value) => (value.length > 0 ? true : 'Instance URL cannot be empty'),\n });\n\n const email = await input({\n message: 'Atlassian account email:',\n validate: (value) => (value.includes('@') ? true : 'Please enter a valid email address'),\n });\n\n const apiToken = await input({\n message: 'API Token:',\n validate: (value) => (value.length > 0 ? true : 'API token cannot be empty'),\n });\n\n // Test credentials with Jira API\n const testInstanceUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n const response = await fetch(`${testInstanceUrl}/rest/api/2/myself`, {\n headers: { Authorization: `Basic ${auth}` },\n });\n\n if (!response.ok) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') +\n '\\n\\n' +\n 'Invalid instance URL, email, or API token\\n' +\n 'Make sure the instance URL is correct (e.g., company.atlassian.net)',\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n\n const user = (await response.json()) as { displayName: string; emailAddress: string };\n\n // Store credentials for all Atlassian services\n const credentials: ServiceCredentials = {\n accessToken: apiToken,\n username: email,\n instanceUrl: instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`,\n };\n\n await storageService.setServiceCredentials('jira', credentials);\n await storageService.setServiceCredentials('confluence', credentials);\n // Also update bitbucket credentials if needed (for consistency)\n await storageService.setServiceCredentials('bitbucket', {\n ...credentials,\n instanceUrl: 'https://api.bitbucket.org', // Bitbucket uses different API base\n });\n\n logger.log('');\n logger.log(\n boxen(\n theme.success('✓ Successfully authenticated with Atlassian') +\n '\\n\\n' +\n `Instance: ${instanceUrl}\\n` +\n `User: ${user.displayName}\\n` +\n `Email: ${user.emailAddress}\\n\\n` +\n 'Services configured:\\n' +\n ' • Jira\\n' +\n ' • Confluence\\n' +\n ' • Bitbucket',\n boxStyles.success\n )\n );\n logger.log('');\n } catch (error) {\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(\n theme.error('✗ Authentication Failed') + '\\n\\n' + (err.message || 'Unknown error'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { GitHubError, GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type { GitHubPR, FetchPRsOptions, GitHubRepositoryInfo } from '../types/github.types.js';\nimport type { GitCommit } from '../types/git.types.js';\nimport { gitService } from './git.service.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * GitHub service for interacting with GitHub via gh CLI\n */\nexport class GitHubService {\n private readonly MAX_BODY_LENGTH = 5000;\n private readonly PR_SEARCH_FIELDS =\n 'number,title,body,author,mergedAt,additions,deletions,changedFiles,url,labels';\n\n /**\n * Check if GitHub CLI is installed and available\n */\n private async checkGitHubCLI(): Promise<boolean> {\n try {\n await execAsync('command gh --version');\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Validate that GitHub CLI is installed\n */\n private async ensureGitHubCLI(): Promise<void> {\n const isInstalled = await this.checkGitHubCLI();\n if (!isInstalled) {\n throw new GitHubError('GitHub CLI (gh) is not installed', {\n hint: 'Install from https://cli.github.com/',\n });\n }\n }\n\n /**\n * Check if user is authenticated with GitHub CLI\n */\n private async checkAuthentication(): Promise<boolean> {\n try {\n await execAsync('command gh auth status');\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Ensure user is authenticated with GitHub CLI\n */\n private async ensureAuthentication(): Promise<void> {\n const isAuthenticated = await this.checkAuthentication();\n if (!isAuthenticated) {\n throw new GitHubError('Not authenticated with GitHub', {\n hint: 'Run \"gh auth login\" to authenticate',\n });\n }\n }\n\n /**\n * Check GitHub CLI authentication status\n * Returns object with installation and authentication status\n */\n async getAuthStatus(): Promise<{ installed: boolean; authenticated: boolean }> {\n const installed = await this.checkGitHubCLI();\n if (!installed) {\n return { installed: false, authenticated: false };\n }\n\n const authenticated = await this.checkAuthentication();\n return { installed, authenticated };\n }\n\n /**\n * Validate that the current repository is hosted on GitHub\n */\n async validateGitHubRepository(): Promise<void> {\n try {\n await this.ensureGitHubCLI();\n await this.ensureAuthentication();\n\n // Check if current directory is a git repo\n await gitService.validateRepository();\n\n // Try to get GitHub repo info using gh CLI\n const { stdout } = await execAsync('command gh repo view --json url');\n const data = JSON.parse(stdout);\n\n if (!data.url) {\n throw new GitHubError('This repository is not hosted on GitHub', {\n hint: 'Only GitHub repositories are currently supported for PR scanning',\n });\n }\n } catch (error: any) {\n if (error instanceof GitHubError || error instanceof GitError) {\n throw error;\n }\n\n // Handle gh CLI errors\n if (error.message?.includes('not a git repository')) {\n throw new GitHubError('Not a git repository', {\n hint: 'Navigate to a git repository directory',\n });\n }\n\n if (error.message?.includes('Could not resolve to a Repository')) {\n throw new GitHubError('This repository is not hosted on GitHub', {\n hint: 'Only GitHub repositories are currently supported for PR scanning',\n });\n }\n\n throw new GitHubError('Failed to validate GitHub repository', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Get GitHub repository information\n */\n async getRepositoryInfo(): Promise<GitHubRepositoryInfo> {\n try {\n await this.ensureGitHubCLI();\n\n // Get repo info from gh CLI\n const { stdout } = await execAsync(\n 'command gh repo view --json owner,name,url,nameWithOwner'\n );\n const data = JSON.parse(stdout);\n\n return {\n owner: data.owner.login,\n name: data.name,\n fullName: data.nameWithOwner,\n url: data.url,\n isGitHub: true,\n };\n } catch (error: any) {\n if (error instanceof GitHubError || error instanceof GitError) {\n throw error;\n }\n throw new GitHubError('Failed to get GitHub repository information', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Get the current authenticated GitHub user\n */\n async getCurrentGitHubUser(): Promise<string | null> {\n try {\n const { stdout } = await execAsync('command gh api user --jq .login');\n return stdout.trim() || null;\n } catch {\n logger.debug('Failed to get GitHub user');\n return null;\n }\n }\n\n /**\n * Fetch merged PRs from GitHub\n */\n async getMergedPRs(options: FetchPRsOptions = {}): Promise<GitHubPR[]> {\n const { days = 30, limit, author } = options;\n\n try {\n await this.ensureGitHubCLI();\n await this.ensureAuthentication();\n\n logger.debug(`Fetching merged PRs from the last ${days} days`);\n\n // Calculate date for filtering\n const since = new Date();\n since.setDate(since.getDate() - days);\n const sinceDate = since.toISOString().split('T')[0]; // YYYY-MM-DD\n\n // Build search query with date and optional author filter\n let searchQuery = `merged:>=${sinceDate}`;\n if (author) {\n searchQuery += ` author:${author}`;\n }\n\n // Build gh pr list command\n const limitArg = limit ? `--limit ${limit}` : '';\n const command = `command gh pr list --state merged --json ${this.PR_SEARCH_FIELDS} --search \"${searchQuery}\" ${limitArg}`;\n\n logger.debug(`Running: ${command}`);\n\n const { stdout } = await execAsync(command);\n const prs: GitHubPR[] = JSON.parse(stdout);\n\n logger.debug(`Found ${prs.length} merged PRs`);\n\n return prs;\n } catch (error: any) {\n if (error instanceof GitHubError || error instanceof GitError) {\n throw error;\n }\n throw new GitHubError('Failed to fetch PRs from GitHub', {\n originalError: error.message,\n days,\n });\n }\n }\n\n /**\n * Get merged PRs by current user (PRs authored by the current user)\n */\n async getPRsByCurrentUser(options: FetchPRsOptions = {}): Promise<GitHubPR[]> {\n const currentUser = await this.getCurrentGitHubUser();\n\n if (!currentUser) {\n logger.warning('Could not determine GitHub user, returning all PRs');\n return this.getMergedPRs(options);\n }\n\n logger.debug(`Filtering PRs by author: ${currentUser}`);\n\n // Pass author to getMergedPRs to filter server-side\n return this.getMergedPRs({\n ...options,\n author: currentUser,\n });\n }\n\n /**\n * Transform a GitHub PR into a GitCommit structure\n * This allows PR data to work with existing commit-based UI and API\n */\n transformPRToCommit(pr: GitHubPR): GitCommit {\n // Construct message from PR title and body\n const title = pr.title;\n const body = pr.body || '';\n\n // Truncate body if too long\n const truncatedBody =\n body.length > this.MAX_BODY_LENGTH\n ? body.substring(0, this.MAX_BODY_LENGTH) + '...[truncated]'\n : body;\n\n const message = truncatedBody ? `${title}\\n\\n${truncatedBody}` : title;\n\n return {\n sha: `pr-${pr.number}`,\n message,\n author: pr.author.login,\n authorEmail: '', // Not available from gh PR API\n date: pr.mergedAt,\n url: pr.url,\n diffStats: {\n filesChanged: pr.changedFiles,\n insertions: pr.additions,\n deletions: pr.deletions,\n },\n };\n }\n}\n\n// Export singleton instance\nexport const githubService = new GitHubService();\n","import simpleGit, { SimpleGit, LogResult, DefaultLogFields } from 'simple-git';\nimport { validateGitRepository } from '../utils/validators.js';\nimport { GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type {\n GitCommit,\n DiffStats,\n FetchCommitsOptions,\n GitRepositoryInfo,\n} from '../types/git.types.js';\n\n/**\n * Git service for interacting with git repositories\n */\nexport class GitService {\n private git: SimpleGit;\n private repoPath: string;\n\n constructor(repoPath: string = process.cwd()) {\n this.repoPath = repoPath;\n this.git = simpleGit(repoPath);\n }\n\n /**\n * Validate that the current directory is a git repository\n */\n async validateRepository(): Promise<void> {\n try {\n validateGitRepository(this.repoPath);\n const isRepo = await this.git.checkIsRepo();\n\n if (!isRepo) {\n throw new GitError('Not a valid git repository', {\n path: this.repoPath,\n });\n }\n } catch (error: any) {\n if (error instanceof GitError) {\n throw error;\n }\n throw new GitError('Failed to validate git repository', {\n originalError: error.message,\n path: this.repoPath,\n });\n }\n }\n\n /**\n * Get repository information\n */\n async getRepositoryInfo(): Promise<GitRepositoryInfo> {\n try {\n await this.validateRepository();\n\n const status = await this.git.status();\n const remotes = await this.git.getRemotes(true);\n const primaryRemote = remotes.find((r) => r.name === 'origin');\n\n return {\n path: this.repoPath,\n currentBranch: status.current || 'unknown',\n remoteUrl: primaryRemote?.refs?.fetch || primaryRemote?.refs?.push,\n isClean: status.isClean(),\n };\n } catch (error: any) {\n if (error instanceof GitError) {\n throw error;\n }\n throw new GitError('Failed to get repository information', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Fetch recent commits\n */\n async getRecentCommits(options: FetchCommitsOptions = {}): Promise<GitCommit[]> {\n const { days = 30, limit, author } = options;\n\n try {\n await this.validateRepository();\n\n logger.debug(`Fetching commits from last ${days} days`);\n\n // Calculate date for filtering\n const since = new Date();\n since.setDate(since.getDate() - days);\n\n // Build log options\n const logOptions: any = {\n '--since': since.toISOString(),\n '--no-merges': null,\n };\n\n if (limit) {\n logOptions.maxCount = limit;\n }\n\n if (author) {\n logOptions['--author'] = author;\n }\n\n // Fetch commits\n const log: LogResult<DefaultLogFields> = await this.git.log(logOptions);\n\n logger.debug(`Found ${log.all.length} commits`);\n\n // Convert to our GitCommit format\n const commits: GitCommit[] = log.all.map((commit) => ({\n sha: commit.hash,\n message: commit.message,\n author: commit.author_name,\n authorEmail: commit.author_email,\n date: commit.date,\n }));\n\n return commits;\n } catch (error: any) {\n if (error instanceof GitError) {\n throw error;\n }\n throw new GitError('Failed to fetch commits', {\n originalError: error.message,\n days,\n });\n }\n }\n\n /**\n * Get diff statistics for a specific commit\n */\n async getCommitStats(sha: string): Promise<DiffStats> {\n try {\n logger.debug(`Getting stats for commit ${sha}`);\n\n // Get diff summary for the commit\n const diffSummary = await this.git.diffSummary([`${sha}^`, sha]);\n\n const stats: DiffStats = {\n filesChanged: diffSummary.files.length,\n insertions: diffSummary.insertions,\n deletions: diffSummary.deletions,\n };\n\n logger.debug(\n `Commit ${sha}: ${stats.filesChanged} files, +${stats.insertions} -${stats.deletions}`\n );\n\n return stats;\n } catch (error: any) {\n // If this is the first commit, there's no parent to diff against\n if (error.message && error.message.includes('unknown revision')) {\n logger.debug(`Commit ${sha} has no parent (first commit)`);\n // Try to get stats for first commit\n try {\n const diffSummary = await this.git.diffSummary([sha]);\n return {\n filesChanged: diffSummary.files.length,\n insertions: diffSummary.insertions,\n deletions: diffSummary.deletions,\n };\n } catch {\n // Return zeros if we can't get stats\n return {\n filesChanged: 0,\n insertions: 0,\n deletions: 0,\n };\n }\n }\n\n throw new GitError('Failed to get commit statistics', {\n originalError: error.message,\n sha,\n });\n }\n }\n\n /**\n * Get commits with their diff statistics\n */\n async getCommitsWithStats(options: FetchCommitsOptions = {}): Promise<GitCommit[]> {\n const commits = await this.getRecentCommits(options);\n\n logger.debug(`Fetching diff stats for ${commits.length} commits`);\n\n // Fetch stats for each commit in parallel\n const commitsWithStats = await Promise.all(\n commits.map(async (commit) => {\n try {\n const stats = await this.getCommitStats(commit.sha);\n return {\n ...commit,\n diffStats: stats,\n };\n } catch {\n logger.debug(`Failed to get stats for commit ${commit.sha}, continuing without stats`);\n return commit;\n }\n })\n );\n\n return commitsWithStats;\n }\n\n /**\n * Get the current git user email\n */\n async getCurrentUserEmail(): Promise<string | null> {\n try {\n const email = await this.git.raw(['config', 'user.email']);\n return email.trim() || null;\n } catch {\n logger.debug('Failed to get git user email');\n return null;\n }\n }\n\n /**\n * Get the current git user name\n */\n async getCurrentUserName(): Promise<string | null> {\n try {\n const name = await this.git.raw(['config', 'user.name']);\n return name.trim() || null;\n } catch {\n logger.debug('Failed to get git user name');\n return null;\n }\n }\n\n /**\n * Filter commits by current user\n */\n async getCommitsByCurrentUser(options: FetchCommitsOptions = {}): Promise<GitCommit[]> {\n const userEmail = await this.getCurrentUserEmail();\n\n if (!userEmail) {\n logger.warning('Could not determine git user email, returning all commits');\n return this.getCommitsWithStats(options);\n }\n\n logger.debug(`Filtering commits by user: ${userEmail}`);\n\n return this.getCommitsWithStats({\n ...options,\n author: userEmail,\n });\n }\n}\n\n// Export singleton instance for the current working directory\nexport const gitService = new GitService();\n","import { existsSync } from 'fs';\nimport { join } from 'path';\nimport { GitError, ValidationError } from './errors.js';\n\n/**\n * Validate that a directory is a git repository\n */\nexport function validateGitRepository(path: string): void {\n const gitDir = join(path, '.git');\n\n if (!existsSync(gitDir)) {\n throw new GitError(\n 'Not a git repository. Please run this command from within a git repository.',\n {\n path,\n hint: 'Run \"git init\" to initialize a git repository, or navigate to an existing one',\n }\n );\n }\n}\n\n/**\n * Validate email format\n */\nexport function validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n\n/**\n * Validate that a value is not empty\n */\nexport function validateNotEmpty(value: string, fieldName: string): void {\n if (!value || value.trim().length === 0) {\n throw new ValidationError(`${fieldName} cannot be empty`);\n }\n}\n\n/**\n * Validate date is in valid format\n */\nexport function validateDate(dateString: string): boolean {\n const date = new Date(dateString);\n return !isNaN(date.getTime());\n}\n\n/**\n * Validate number is positive\n */\nexport function validatePositiveNumber(value: number, fieldName: string): void {\n if (value <= 0) {\n throw new ValidationError(`${fieldName} must be a positive number`);\n }\n}\n\n/**\n * Validate commit SHA format (40 character hex string or pr-{number} format)\n */\nexport function validateCommitSha(sha: string): boolean {\n const sha40Regex = /^[a-f0-9]{40}$/i;\n const prFormatRegex = /^pr-\\d+$/i;\n return sha40Regex.test(sha) || prFormatRegex.test(sha);\n}\n","import chalk from 'chalk';\n\n/**\n * Color scheme for consistent UI theming across the CLI\n */\nexport const colors = {\n // Primary colors for main actions and interactive elements\n primary: chalk.cyan,\n\n // Success states\n success: chalk.green,\n successBold: chalk.green.bold,\n\n // Warning states\n warning: chalk.yellow,\n warningBold: chalk.yellow.bold,\n\n // Error states\n error: chalk.red,\n errorBold: chalk.red.bold,\n\n // Info and metadata\n info: chalk.gray,\n infoDim: chalk.dim,\n\n // Highlighted/important data\n highlight: chalk.yellow.bold,\n highlightCyan: chalk.cyan.bold,\n\n // Text emphasis\n bold: chalk.bold,\n dim: chalk.dim,\n\n // Special purpose\n white: chalk.white,\n gray: chalk.gray,\n\n // Links and URLs\n link: chalk.blue.underline,\n} as const;\n\n/**\n * Themed formatting functions for consistent UI elements\n */\nexport const theme = {\n /**\n * Format command names and CLI actions\n */\n command: (text: string) => colors.primary(text),\n\n /**\n * Format success messages\n */\n success: (text: string) => colors.success(`✓ ${text}`),\n successBold: (text: string) => colors.successBold(`✓ ${text}`),\n\n /**\n * Format error messages\n */\n error: (text: string) => colors.error(`✗ ${text}`),\n errorBold: (text: string) => colors.errorBold(`✗ ${text}`),\n\n /**\n * Format warning messages\n */\n warning: (text: string) => colors.warning(`⚠ ${text}`),\n\n /**\n * Format info messages\n */\n info: (text: string) => colors.info(text),\n\n /**\n * Format labels (e.g., \"User:\", \"Email:\")\n */\n label: (text: string) => colors.gray(`${text}:`),\n\n /**\n * Format values\n */\n value: (text: string) => colors.highlight(text),\n\n /**\n * Format highlighted text\n */\n highlight: (text: string) => colors.highlight(text),\n\n /**\n * Format counts and numbers\n */\n count: (num: number) => colors.highlightCyan(num.toString()),\n\n /**\n * Format file paths\n */\n path: (text: string) => colors.info(text),\n\n /**\n * Format step indicators (e.g., \"Step 1/5:\")\n */\n step: (current: number, total: number) => colors.primary(`[${current}/${total}]`),\n\n /**\n * Format progress text\n */\n progress: (text: string) => colors.infoDim(text),\n\n /**\n * Format emphasized text\n */\n emphasis: (text: string) => colors.bold(text),\n\n /**\n * Format de-emphasized/secondary text\n */\n secondary: (text: string) => colors.dim(text),\n\n /**\n * Format interactive elements (prompts, selections)\n */\n interactive: (text: string) => colors.primary(text),\n\n /**\n * Format keys in key-value pairs\n */\n key: (text: string) => colors.white(text),\n} as const;\n\n/**\n * Box styles for different message types\n */\nexport const boxStyles = {\n success: {\n borderColor: 'green',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n error: {\n borderColor: 'red',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n warning: {\n borderColor: 'yellow',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n info: {\n borderColor: 'cyan',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n\n plain: {\n borderColor: 'gray',\n borderStyle: 'round',\n padding: 1,\n margin: 1,\n } as const,\n} as const;\n\n/**\n * Table styles for consistent table formatting\n */\nexport const tableStyles = {\n default: {\n style: {\n head: [] as string[],\n border: ['gray'] as string[],\n },\n },\n\n compact: {\n style: {\n head: [] as string[],\n border: ['dim'] as string[],\n compact: true,\n },\n },\n} as const;\n\n/**\n * Size indicators for visual representation\n */\nexport const sizeIndicators = {\n small: colors.success('●'),\n medium: colors.warning('●'),\n large: colors.error('●'),\n} as const;\n\n/**\n * Helper to format size indicator based on lines changed\n */\nexport function getSizeIndicator(insertions: number, deletions: number): string {\n const total = insertions + deletions;\n\n if (total < 50) {\n return `${sizeIndicators.small} Small`;\n } else if (total < 200) {\n return `${sizeIndicators.medium} Medium`;\n } else {\n return `${sizeIndicators.large} Large`;\n }\n}\n\n/**\n * Helper to format diff stats with colors\n */\nexport function formatDiffStats(insertions: number, deletions: number): string {\n return `${colors.success(`+${insertions}`)} ${colors.error(`-${deletions}`)}`;\n}\n","import { CancelPromptError } from '@inquirer/core';\nimport { select } from '@inquirer/prompts';\nimport boxen from 'boxen';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { authService } from '../services/auth.service.js';\nimport { loadEnvConfig } from '../utils/env-loader.js';\nimport { findProjectConfig } from '../utils/config-loader.js';\nimport { AdapterFactory } from '../sync/adapter-factory.js';\nimport { logger } from '../utils/logger.js';\nimport { ensureAuthenticated } from '../utils/auth-helper.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport {\n promptSelectCommits,\n promptDaysToScan,\n promptSortOption,\n promptReviewBrags,\n promptSelectOrganisation,\n} from '../ui/prompts.js';\nimport { createStepSpinner, succeedStepSpinner, failStepSpinner } from '../ui/spinners.js';\nimport {\n formatRefinedCommitsTable,\n formatSuccessMessage,\n formatErrorMessage,\n formatCommitStats,\n formatSelectionSummary,\n} from '../ui/formatters.js';\nimport { theme, colors, boxStyles } from '../ui/theme.js';\nimport type { CreateBragItem, RefinedBrag } from '../types/api.types.js';\nimport type { SourceType } from '../types/source.types.js';\n\n/**\n * Sync command options\n */\nexport interface SyncCommandOptions {\n days?: number;\n all?: boolean;\n source?: string; // Explicit source override\n}\n\n/**\n * Sync results for a single service\n */\ninterface SyncResult {\n created: number;\n skipped: number;\n}\n\n/**\n * Prompt user to select a service to sync\n */\nasync function promptSelectService(): Promise<SourceType | 'all'> {\n // Define all supported services in order\n const allServices: SourceType[] = [\n 'github',\n 'gitlab',\n 'bitbucket',\n 'atlassian',\n 'jira',\n 'confluence',\n ];\n\n // Get authenticated services\n const authenticatedServices = await storageService.getAuthenticatedServices();\n\n // Filter to only include sync-supported services (exclude 'bragduck')\n const authenticatedSyncServices = authenticatedServices.filter(\n (service): service is SourceType =>\n service !== 'bragduck' && allServices.includes(service as SourceType)\n );\n\n // Create choices for each service with auth status\n const serviceChoices = await Promise.all(\n allServices.map(async (service) => {\n const isAuth = await storageService.isServiceAuthenticated(service);\n const indicator = isAuth ? '✓' : '✗';\n const serviceLabel = service.charAt(0).toUpperCase() + service.slice(1);\n\n return {\n name: `${indicator} ${serviceLabel}`,\n value: service,\n description: isAuth ? 'Authenticated' : 'Not authenticated',\n };\n })\n );\n\n // Add \"All authenticated services\" option if there are any\n if (authenticatedSyncServices.length > 0) {\n const serviceNames = authenticatedSyncServices\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join(', ');\n\n serviceChoices.push({\n name: `✓ All authenticated services (${serviceNames})`,\n value: 'all' as SourceType | 'all',\n description: `Sync all ${authenticatedSyncServices.length} authenticated service${authenticatedSyncServices.length > 1 ? 's' : ''}`,\n });\n }\n\n const selected = await select({\n message: 'Select a service to sync:',\n choices: serviceChoices,\n });\n\n return selected;\n}\n\n/**\n * Sync a single service\n */\nasync function syncSingleService(\n sourceType: SourceType,\n options: SyncCommandOptions,\n TOTAL_STEPS: number\n): Promise<SyncResult> {\n // Step 3: Get adapter and validate\n const adapter = AdapterFactory.getAdapter(sourceType);\n const repoSpinner = createStepSpinner(2, TOTAL_STEPS, 'Validating repository');\n repoSpinner.start();\n\n await adapter.validate();\n const repoInfo = await adapter.getRepositoryInfo();\n\n succeedStepSpinner(repoSpinner, 2, TOTAL_STEPS, `Repository: ${theme.value(repoInfo.fullName)}`);\n logger.log('');\n\n // Step 4: Prompt for days\n let days = options.days;\n if (!days) {\n const defaultDays = storageService.getConfig('defaultCommitDays');\n days = await promptDaysToScan(defaultDays);\n logger.log('');\n }\n\n // Step 5: Fetch work items\n const fetchSpinner = createStepSpinner(\n 3,\n TOTAL_STEPS,\n `Fetching work items from the last ${days} days`\n );\n fetchSpinner.start();\n\n const workItems = await adapter.fetchWorkItems({\n days,\n author: options.all ? undefined : (await adapter.getCurrentUser()) || undefined,\n });\n\n if (workItems.length === 0) {\n failStepSpinner(fetchSpinner, 3, TOTAL_STEPS, `No work items found in the last ${days} days`);\n logger.log('');\n logger.info('Try increasing the number of days or check your activity');\n return { created: 0, skipped: 0 };\n }\n\n succeedStepSpinner(\n fetchSpinner,\n 3,\n TOTAL_STEPS,\n `Found ${theme.count(workItems.length)} work item${workItems.length > 1 ? 's' : ''}`\n );\n logger.log('');\n\n // Show commit statistics\n logger.log(formatCommitStats(workItems));\n logger.log('');\n\n // Step 6: Sort and select work items\n let sortedCommits = [...workItems];\n if (workItems.length > 1) {\n const sortOption = await promptSortOption();\n logger.log('');\n\n // Sort commits based on user preference\n if (sortOption === 'date') {\n sortedCommits.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());\n } else if (sortOption === 'size') {\n sortedCommits.sort((a, b) => {\n const sizeA = (a.diffStats?.insertions || 0) + (a.diffStats?.deletions || 0);\n const sizeB = (b.diffStats?.insertions || 0) + (b.diffStats?.deletions || 0);\n return sizeB - sizeA;\n });\n } else if (sortOption === 'files') {\n sortedCommits.sort((a, b) => {\n const filesA = a.diffStats?.filesChanged || 0;\n const filesB = b.diffStats?.filesChanged || 0;\n return filesB - filesA;\n });\n }\n }\n\n const selectedShas = await promptSelectCommits(sortedCommits);\n\n if (selectedShas.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No work items selected. Sync cancelled.'));\n logger.log('');\n return { created: 0, skipped: 0 };\n }\n\n const selectedCommits = sortedCommits.filter((c) => selectedShas.includes(c.sha));\n\n // Show selection summary\n logger.log(formatSelectionSummary(selectedCommits.length, selectedCommits));\n logger.log('');\n\n // Check for duplicates\n const existingBrags = await apiService.listBrags({ limit: 100 });\n logger.debug(`Fetched ${existingBrags.brags.length} existing brags`);\n\n const existingUrls = new Set(existingBrags.brags.flatMap((b) => b.attachments || []));\n logger.debug(`Existing URLs in attachments: ${existingUrls.size}`);\n\n const duplicates = selectedCommits.filter((c) => c.url && existingUrls.has(c.url));\n const newCommits = selectedCommits.filter((c) => !c.url || !existingUrls.has(c.url));\n\n logger.debug(`Duplicates: ${duplicates.length}, New: ${newCommits.length}`);\n\n if (duplicates.length > 0) {\n logger.log('');\n logger.info(\n colors.warning(\n `${duplicates.length} work item${duplicates.length > 1 ? 's' : ''} already added to Bragduck - skipping`\n )\n );\n logger.log('');\n }\n\n if (newCommits.length === 0) {\n logger.log('');\n logger.info(\n theme.secondary('All selected work items already exist in Bragduck. Nothing to refine.')\n );\n logger.log('');\n return { created: 0, skipped: duplicates.length };\n }\n\n // Step 7: Refine with AI\n const refineSpinner = createStepSpinner(\n 4,\n TOTAL_STEPS,\n `Refining ${theme.count(newCommits.length)} work item${newCommits.length > 1 ? 's' : ''} with AI`\n );\n refineSpinner.start();\n\n const refineRequest = {\n brags: newCommits.map((c) => ({\n text: c.message,\n date: c.date,\n title: c.message.split('\\n')[0],\n })),\n };\n\n const refineResponse = await apiService.refineBrags(refineRequest);\n let refinedBrags = refineResponse.refined_brags;\n\n succeedStepSpinner(refineSpinner, 4, TOTAL_STEPS, 'Work items refined successfully');\n logger.log('');\n\n // Step 8: Review and edit brags\n logger.info('Preview of refined brags:');\n logger.log('');\n logger.log(formatRefinedCommitsTable(refinedBrags, newCommits));\n logger.log('');\n\n const acceptedBrags = await promptReviewBrags(refinedBrags, newCommits);\n\n if (acceptedBrags.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No brags selected for creation. Sync cancelled.'));\n logger.log('');\n return { created: 0, skipped: duplicates.length };\n }\n\n logger.log('');\n\n // Step 9: Select organisation (if user has any)\n let selectedOrgId: string | null = null;\n const userInfo = authService.getUserInfo();\n if (userInfo?.id) {\n try {\n const orgsResponse = await apiService.listUserOrganisations(userInfo.id);\n if (orgsResponse.items.length > 0) {\n selectedOrgId = await promptSelectOrganisation(orgsResponse.items);\n logger.log('');\n }\n } catch {\n logger.debug('Failed to fetch organisations, skipping org selection');\n }\n }\n\n // Step 10: Create brags\n const createSpinner = createStepSpinner(\n 5,\n TOTAL_STEPS,\n `Creating ${theme.count(acceptedBrags.length)} brag${acceptedBrags.length > 1 ? 's' : ''}`\n );\n createSpinner.start();\n\n const createRequest = {\n brags: acceptedBrags.map((refined: RefinedBrag, index: number): CreateBragItem => {\n const originalCommit = newCommits[index];\n return {\n commit_sha: originalCommit?.sha || `brag-${index}`,\n title: refined.refined_title,\n description: refined.refined_description,\n tags: refined.suggested_tags,\n repository: repoInfo.url,\n date: originalCommit?.date || '',\n commit_url: originalCommit?.url || '',\n impact_score: refined.suggested_impactLevel,\n impact_description: refined.impact_description,\n attachments: originalCommit?.url ? [originalCommit.url] : [],\n orgId: selectedOrgId || undefined,\n // External fields for non-git sources (Jira, Confluence, etc.)\n externalId: originalCommit?.externalId,\n externalType: originalCommit?.externalType,\n externalSource: originalCommit?.externalSource,\n externalUrl: originalCommit?.externalUrl,\n };\n }),\n };\n\n const createResponse = await apiService.createBrags(createRequest);\n\n succeedStepSpinner(\n createSpinner,\n 5,\n TOTAL_STEPS,\n `Created ${theme.count(createResponse.created)} brag${createResponse.created > 1 ? 's' : ''}`\n );\n logger.log('');\n\n return { created: createResponse.created, skipped: duplicates.length };\n}\n\n/**\n * Sync all authenticated services\n */\nasync function syncAllAuthenticatedServices(options: SyncCommandOptions): Promise<void> {\n const TOTAL_STEPS = 5;\n const allServices: SourceType[] = [\n 'github',\n 'gitlab',\n 'bitbucket',\n 'atlassian',\n 'jira',\n 'confluence',\n ];\n\n // Get authenticated services\n const authenticatedServices = await storageService.getAuthenticatedServices();\n\n // Filter to only include sync-supported services (exclude 'bragduck')\n const servicesToSync = authenticatedServices.filter(\n (service): service is SourceType =>\n service !== 'bragduck' && allServices.includes(service as SourceType)\n );\n\n if (servicesToSync.length === 0) {\n logger.log('');\n logger.error('No authenticated services found.');\n logger.log('');\n logger.info('Authenticate a service first:');\n logger.info(` ${theme.command('bragduck auth github')}`);\n logger.info(` ${theme.command('bragduck auth atlassian')}`);\n return;\n }\n\n logger.info(\n theme.highlight(\n `Syncing ${servicesToSync.length} authenticated service${servicesToSync.length > 1 ? 's' : ''}...`\n )\n );\n logger.log('');\n\n const results: Array<{ service: SourceType; created: number; skipped: number; error?: string }> =\n [];\n\n // Sync each service\n for (let i = 0; i < servicesToSync.length; i++) {\n const service = servicesToSync[i];\n const serviceLabel = service.charAt(0).toUpperCase() + service.slice(1);\n\n logger.log(\n colors.highlight(`━━━ Syncing ${i + 1}/${servicesToSync.length}: ${serviceLabel} ━━━`)\n );\n logger.log('');\n\n try {\n const result = await syncSingleService(service, options, TOTAL_STEPS);\n results.push({ service, created: result.created, skipped: result.skipped });\n logger.log('');\n } catch (error) {\n const err = error as Error;\n logger.log('');\n logger.warn(`Failed to sync ${serviceLabel}: ${err.message}`);\n logger.log('');\n results.push({ service, created: 0, skipped: 0, error: err.message });\n }\n }\n\n // Show final summary\n logger.log('');\n logger.log(colors.highlight('━━━ Sync Summary ━━━'));\n logger.log('');\n\n const successful = results.filter((r) => !r.error);\n const failed = results.filter((r) => r.error);\n const totalCreated = successful.reduce((sum, r) => sum + r.created, 0);\n\n if (successful.length > 0) {\n logger.log(\n theme.success(\n `✓ Successfully synced ${successful.length}/${servicesToSync.length} service${servicesToSync.length > 1 ? 's' : ''}:`\n )\n );\n for (const result of successful) {\n const serviceLabel = result.service.charAt(0).toUpperCase() + result.service.slice(1);\n logger.info(\n ` • ${serviceLabel}: ${result.created} brag${result.created !== 1 ? 's' : ''} created${result.skipped > 0 ? `, ${result.skipped} skipped` : ''}`\n );\n }\n logger.log('');\n }\n\n if (failed.length > 0) {\n logger.log(\n colors.warning(`✗ Failed to sync ${failed.length} service${failed.length > 1 ? 's' : ''}:`)\n );\n for (const result of failed) {\n const serviceLabel = result.service.charAt(0).toUpperCase() + result.service.slice(1);\n logger.info(` • ${serviceLabel}: ${result.error}`);\n }\n logger.log('');\n }\n\n if (totalCreated > 0) {\n logger.log(boxen(formatSuccessMessage(totalCreated), boxStyles.success));\n } else if (successful.length > 0) {\n logger.log(\n boxen(\n theme.secondary('No new brags created (all items already exist or were skipped)'),\n boxStyles.info\n )\n );\n }\n}\n\n/**\n * Sync command: Unified work item sync across all sources\n */\nexport async function syncCommand(options: SyncCommandOptions = {}): Promise<void> {\n logger.log('');\n\n const TOTAL_STEPS = 5;\n let sourceType: SourceType | undefined;\n\n try {\n // Step 1: Check authentication\n const isAuthenticated = await ensureAuthenticated();\n if (!isAuthenticated) {\n process.exit(1);\n }\n\n // Step 1.5: Check subscription plan\n logger.debug('Fetching subscription status...');\n const subscriptionStatus = await apiService.getSubscriptionStatus();\n\n logger.debug('Subscription status response:', JSON.stringify(subscriptionStatus, null, 2));\n\n if (subscriptionStatus.tier === 'FREE') {\n logger.debug('FREE tier detected - blocking sync command');\n logger.log('');\n logger.log(\n boxen(\n theme.warning('CLI Access Requires Subscription') +\n '\\n\\n' +\n 'The Bragduck CLI is available for Plus and Pro subscribers.\\n' +\n 'Upgrade now to unlock:\\n\\n' +\n ' • Automatic work item scanning\\n' +\n ' • AI-powered brag generation\\n' +\n ' • Unlimited brags\\n\\n' +\n colors.highlight('Start your free trial today'),\n {\n ...boxStyles.warning,\n padding: 1,\n margin: 1,\n }\n )\n );\n logger.log('');\n return;\n }\n\n logger.debug(`Subscription tier \"${subscriptionStatus.tier}\" - proceeding with sync`);\n\n // Step 2: Select or detect source\n let selectedSource: SourceType | 'all';\n\n if (options.source) {\n // Use explicit --source flag (skip menu)\n sourceType = options.source as SourceType;\n\n // Validate source is supported\n if (!AdapterFactory.isSupported(sourceType)) {\n logger.log('');\n logger.error(`Unsupported source: ${options.source}`);\n logger.log('');\n logger.info('Supported sources: github, gitlab, bitbucket, atlassian, jira, confluence');\n return;\n }\n\n selectedSource = sourceType;\n } else {\n // Show interactive service selection menu\n logger.log('');\n selectedSource = await promptSelectService();\n logger.log('');\n }\n\n // Handle selection\n if (selectedSource === 'all') {\n // Multi-service sync\n await syncAllAuthenticatedServices(options);\n } else {\n // Single service sync\n const detectionSpinner = createStepSpinner(1, TOTAL_STEPS, 'Preparing sync');\n detectionSpinner.start();\n\n sourceType = selectedSource;\n\n // Early validation for Jira/Confluence credentials\n if (sourceType === 'jira' || sourceType === 'confluence') {\n const creds = await storageService.getServiceCredentials(sourceType);\n\n // Try environment variable or project config as fallback\n const envInstance =\n loadEnvConfig()[`${sourceType}Instance` as keyof ReturnType<typeof loadEnvConfig>];\n const projectConfig = await findProjectConfig();\n const configInstance =\n projectConfig?.[`${sourceType}Instance` as keyof typeof projectConfig];\n\n if (!creds?.instanceUrl && !envInstance && !configInstance) {\n failStepSpinner(detectionSpinner, 1, TOTAL_STEPS, `No ${sourceType} instance configured`);\n logger.log('');\n logger.info('Configure instance via:');\n logger.info(` ${theme.command('bragduck auth atlassian')} (interactive)`);\n logger.info(\n ` ${theme.command(`bragduck config set ${sourceType}Instance company.atlassian.net`)}`\n );\n logger.info(\n ` ${theme.command(`export BRAGDUCK_${sourceType.toUpperCase()}_INSTANCE=company.atlassian.net`)}`\n );\n return;\n }\n }\n\n succeedStepSpinner(detectionSpinner, 1, TOTAL_STEPS, `Source: ${theme.value(sourceType)}`);\n logger.log('');\n\n // Sync the selected service\n const result = await syncSingleService(sourceType, options, TOTAL_STEPS);\n\n // Show success message\n if (result.created > 0) {\n logger.log(boxen(formatSuccessMessage(result.created), boxStyles.success));\n }\n }\n } catch (error) {\n if (error instanceof CancelPromptError) {\n logger.log('');\n logger.info(theme.secondary('Sync cancelled.'));\n logger.log('');\n return;\n }\n\n const err = error as BragduckError;\n logger.log('');\n logger.log(\n boxen(formatErrorMessage(err.message, getErrorHint(err, sourceType)), boxStyles.error)\n );\n\n process.exit(1);\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError, sourceType?: SourceType): string {\n if (error.name === 'GitHubError') {\n return 'Make sure you are in a GitHub repository and have authenticated with \"gh auth login\"';\n }\n\n if (error.name === 'GitError') {\n return 'Make sure you are in a git repository';\n }\n\n if (error.name === 'TokenExpiredError' || error.name === 'AuthenticationError') {\n // Provide context-aware hint for non-git sources\n if (sourceType === 'jira' || sourceType === 'confluence') {\n return 'This is your Bragduck platform session. Run \"bragduck auth login\" (not \"bragduck auth atlassian\")';\n }\n return 'Run \"bragduck auth login\" to login again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'ApiError') {\n return 'The server might be experiencing issues. Try again later';\n }\n\n return 'Try running with DEBUG=* for more information';\n}\n","export class AbortPromptError extends Error {\n name = 'AbortPromptError';\n message = 'Prompt was aborted';\n constructor(options) {\n super();\n this.cause = options?.cause;\n }\n}\nexport class CancelPromptError extends Error {\n name = 'CancelPromptError';\n message = 'Prompt was canceled';\n}\nexport class ExitPromptError extends Error {\n name = 'ExitPromptError';\n}\nexport class HookError extends Error {\n name = 'HookError';\n}\nexport class ValidationError extends Error {\n name = 'ValidationError';\n}\n","import type { SourceType } from '../types/source.types.js';\nimport type { SyncAdapter } from './base-adapter.js';\nimport { githubSyncAdapter } from './github-adapter.js';\nimport { bitbucketSyncAdapter } from './bitbucket-adapter.js';\nimport { gitlabSyncAdapter } from './gitlab-adapter.js';\nimport { jiraSyncAdapter } from './jira-adapter.js';\nimport { confluenceSyncAdapter } from './confluence-adapter.js';\n\n/**\n * Factory for creating source adapters\n */\nexport class AdapterFactory {\n /**\n * Get adapter for a specific source type\n */\n static getAdapter(source: SourceType): SyncAdapter {\n switch (source) {\n case 'github':\n return githubSyncAdapter;\n case 'bitbucket':\n case 'atlassian':\n return bitbucketSyncAdapter; // Bitbucket Cloud and Server use same adapter\n case 'gitlab':\n return gitlabSyncAdapter;\n case 'jira':\n return jiraSyncAdapter;\n case 'confluence':\n return confluenceSyncAdapter;\n default:\n throw new Error(`Unknown source type: ${source}`);\n }\n }\n\n /**\n * Check if adapter is available for source\n */\n static isSupported(source: SourceType): boolean {\n return (\n source === 'github' ||\n source === 'bitbucket' ||\n source === 'atlassian' ||\n source === 'gitlab' ||\n source === 'jira' ||\n source === 'confluence'\n );\n }\n}\n","import { githubService } from '../services/github.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * GitHub adapter for syncing PRs and commits\n */\nexport class GitHubSyncAdapter implements SyncAdapter {\n readonly name = 'github';\n\n async validate(): Promise<void> {\n await githubService.validateGitHubRepository();\n }\n\n async getRepositoryInfo() {\n const info = await githubService.getRepositoryInfo();\n return {\n owner: info.owner,\n name: info.name,\n fullName: info.fullName,\n url: info.url,\n };\n }\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n // Reuse existing GitHub PR fetching logic\n let prs;\n if (options.author) {\n prs = await githubService.getMergedPRs({\n days: options.days,\n limit: options.limit,\n author: options.author,\n });\n } else {\n prs = await githubService.getPRsByCurrentUser({\n days: options.days,\n limit: options.limit,\n });\n }\n\n // Transform to GitCommit format\n return prs.map((pr) => githubService.transformPRToCommit(pr));\n }\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await githubService.validateGitHubRepository();\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentUser(): Promise<string | null> {\n return githubService.getCurrentGitHubUser();\n }\n}\n\nexport const githubSyncAdapter = new GitHubSyncAdapter();\n","import { bitbucketService } from '../services/bitbucket.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Bitbucket adapter for syncing PRs and commits\n */\nexport class BitbucketSyncAdapter implements SyncAdapter {\n readonly name = 'bitbucket';\n\n async validate(): Promise<void> {\n await bitbucketService.validateBitbucketRepository();\n }\n\n async getRepositoryInfo() {\n const info = await bitbucketService.getRepositoryInfo();\n return {\n owner: info.owner,\n name: info.name,\n fullName: info.fullName,\n url: info.url,\n };\n }\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n let prs;\n if (options.author) {\n prs = await bitbucketService.getMergedPRs({\n days: options.days,\n limit: options.limit,\n author: options.author,\n });\n } else {\n prs = await bitbucketService.getPRsByCurrentUser({\n days: options.days,\n limit: options.limit,\n });\n }\n\n return prs.map((pr) => bitbucketService.transformPRToCommit(pr));\n }\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await bitbucketService.validateBitbucketRepository();\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentUser(): Promise<string | null> {\n return bitbucketService.getCurrentGitHubUser();\n }\n}\n\nexport const bitbucketSyncAdapter = new BitbucketSyncAdapter();\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { BitbucketError, GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport { gitService } from './git.service.js';\nimport type {\n BitbucketPullRequest,\n BitbucketUser,\n FetchBitbucketPRsOptions,\n BitbucketPaginatedResponse,\n BitbucketRepository,\n} from '../types/bitbucket.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Bitbucket service for interacting with Bitbucket Cloud REST API\n */\nexport class BitbucketService {\n private readonly BITBUCKET_API_BASE = 'https://api.bitbucket.org/2.0';\n private readonly MAX_DESCRIPTION_LENGTH = 5000;\n\n /**\n * Get stored Bitbucket credentials\n */\n private async getCredentials(): Promise<{ email: string; apiToken: string }> {\n const creds = await storageService.getServiceCredentials('bitbucket');\n if (!creds || !creds.username || !creds.accessToken) {\n throw new BitbucketError('Not authenticated with Bitbucket', {\n hint: 'Run: bragduck auth bitbucket',\n });\n }\n\n // Check token expiry\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new BitbucketError('API token has expired', {\n hint: 'Run: bragduck auth bitbucket',\n });\n }\n\n return {\n email: creds.username, // username field stores email\n apiToken: creds.accessToken,\n };\n }\n\n /**\n * Make authenticated request to Bitbucket API\n */\n private async request<T>(endpoint: string): Promise<T> {\n const { email, apiToken } = await this.getCredentials();\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n\n logger.debug(`Bitbucket API: GET ${endpoint}`);\n\n const response = await fetch(`${this.BITBUCKET_API_BASE}${endpoint}`, {\n headers: {\n Authorization: `Basic ${auth}`,\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new BitbucketError('Invalid or expired API token', {\n hint: 'Run: bragduck auth bitbucket',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new BitbucketError('Forbidden - check token permissions', {\n hint: 'Token needs: pullrequest:read, repository:read, account:read',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new BitbucketError('Repository or resource not found', {\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new BitbucketError('Rate limit exceeded', {\n hint: 'Wait a few minutes before trying again',\n originalError: statusText,\n });\n }\n\n throw new BitbucketError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Extract workspace and repo from git remote URL\n */\n private parseRemoteUrl(url: string): { workspace: string; repo: string } | null {\n // Match: bitbucket.org/{workspace}/{repo}\n const match = url.match(/bitbucket\\.org[:/]([^/]+)\\/([^/.]+)/);\n if (match && match[1] && match[2]) {\n return {\n workspace: match[1],\n repo: match[2].replace(/\\.git$/, ''),\n };\n }\n return null;\n }\n\n /**\n * Get repository info from git remote\n */\n private async getRepoFromGit(): Promise<{ workspace: string; repo: string }> {\n try {\n const { stdout } = await execAsync('command git remote get-url origin');\n const remoteUrl = stdout.trim();\n\n const parsed = this.parseRemoteUrl(remoteUrl);\n if (!parsed) {\n throw new BitbucketError('Could not parse Bitbucket repository from git remote', {\n hint: 'Ensure this is a Bitbucket repository',\n });\n }\n\n return parsed;\n } catch (error: unknown) {\n if (error instanceof BitbucketError) {\n throw error;\n }\n throw new GitError('Could not get git remote URL');\n }\n }\n\n /**\n * Validate that this is a Bitbucket repository and credentials work\n */\n async validateBitbucketRepository(): Promise<void> {\n // Check if in git repo\n await gitService.validateRepository();\n\n // Get repo info from git\n const { workspace, repo } = await this.getRepoFromGit();\n\n // Test API access by fetching repository info\n try {\n await this.request<BitbucketRepository>(`/repositories/${workspace}/${repo}`);\n } catch (error: unknown) {\n if (error instanceof BitbucketError) {\n throw error;\n }\n throw new BitbucketError('Could not access Bitbucket repository via API', {\n hint: 'Check that this is a Bitbucket repository and your credentials are valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get repository information\n */\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const { workspace, repo } = await this.getRepoFromGit();\n\n const bitbucketRepo = await this.request<BitbucketRepository>(\n `/repositories/${workspace}/${repo}`\n );\n\n return {\n owner: workspace,\n name: bitbucketRepo.name,\n fullName: bitbucketRepo.full_name,\n url: bitbucketRepo.links.html.href,\n };\n }\n\n /**\n * Get current user's account ID\n */\n private async getCurrentUserAccountId(): Promise<string> {\n const user = await this.request<BitbucketUser>('/user');\n return user.account_id;\n }\n\n /**\n * Get current user's username (nickname)\n */\n async getCurrentGitHubUser(): Promise<string | null> {\n try {\n const user = await this.request<BitbucketUser>('/user');\n return user.nickname;\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch merged pull requests with optional filtering\n */\n async getMergedPRs(options: FetchBitbucketPRsOptions = {}): Promise<BitbucketPullRequest[]> {\n const { workspace, repo } = await this.getRepoFromGit();\n\n // Build query\n const queries = ['state=\"MERGED\"'];\n\n // Date filtering\n if (options.days) {\n const since = new Date();\n since.setDate(since.getDate() - options.days);\n queries.push(`updated_on>=${since.toISOString()}`);\n }\n\n // Author filtering by account_id\n if (options.author) {\n queries.push(`author.account_id=\"${options.author}\"`);\n }\n\n const queryString = queries.join(' AND ');\n\n // Fetch with cursor-based pagination\n const allPRs: BitbucketPullRequest[] = [];\n let endpoint = `/repositories/${workspace}/${repo}/pullrequests?q=${encodeURIComponent(queryString)}&pagelen=100`;\n\n while (endpoint) {\n const response =\n await this.request<BitbucketPaginatedResponse<BitbucketPullRequest>>(endpoint);\n\n allPRs.push(...response.values);\n\n logger.debug(\n `Fetched ${response.values.length} PRs (total: ${allPRs.length})${response.next ? ', fetching next page...' : ''}`\n );\n\n // Check limit\n if (options.limit && allPRs.length >= options.limit) {\n return allPRs.slice(0, options.limit);\n }\n\n // Get next page (convert absolute URL to relative endpoint)\n if (response.next) {\n const url = new URL(response.next);\n endpoint = url.pathname + url.search;\n } else {\n endpoint = '';\n }\n }\n\n return allPRs;\n }\n\n /**\n * Fetch PRs for the current authenticated user\n */\n async getPRsByCurrentUser(\n options: Omit<FetchBitbucketPRsOptions, 'author'> = {}\n ): Promise<BitbucketPullRequest[]> {\n const accountId = await this.getCurrentUserAccountId();\n return this.getMergedPRs({\n ...options,\n author: accountId,\n });\n }\n\n /**\n * Transform Bitbucket PR to GitCommit format\n */\n transformPRToCommit(pr: BitbucketPullRequest): GitCommit {\n // Format message: title + description\n let message = pr.title;\n if (pr.description) {\n const truncatedDesc = pr.description.substring(0, this.MAX_DESCRIPTION_LENGTH);\n message = `${pr.title}\\n\\n${truncatedDesc}`;\n }\n\n return {\n sha: `pr-${pr.id}`,\n message,\n author: pr.author.nickname,\n authorEmail: '', // Not available in Bitbucket API\n date: pr.created_on,\n url: pr.links.html.href,\n diffStats: {\n filesChanged: 0, // Would require separate API call to diffstat endpoint\n insertions: 0,\n deletions: 0,\n },\n };\n }\n}\n\nexport const bitbucketService = new BitbucketService();\n","import { gitlabService } from '../services/gitlab.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * GitLab sync adapter for fetching merge requests\n */\nexport class GitLabSyncAdapter implements SyncAdapter {\n readonly name = 'gitlab';\n\n async validate(): Promise<void> {\n await gitlabService.validateGitLabRepository();\n }\n\n async getRepositoryInfo() {\n const info = await gitlabService.getRepositoryInfo();\n return {\n owner: info.owner,\n name: info.name,\n fullName: info.fullName,\n url: info.url,\n };\n }\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n let mrs;\n if (options.author) {\n mrs = await gitlabService.getMergedMRs({\n days: options.days,\n limit: options.limit,\n author: options.author,\n });\n } else {\n mrs = await gitlabService.getMRsByCurrentUser({\n days: options.days,\n limit: options.limit,\n });\n }\n return mrs.map((mr) => gitlabService.transformMRToCommit(mr));\n }\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await gitlabService.validateGitLabRepository();\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentUser(): Promise<string | null> {\n return gitlabService.getCurrentGitLabUser();\n }\n}\n\nexport const gitlabSyncAdapter = new GitLabSyncAdapter();\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { URLSearchParams } from 'url';\nimport { GitLabError, GitError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport { gitService } from './git.service.js';\nimport type {\n GitLabMergeRequest,\n GitLabUser,\n FetchGitLabMRsOptions,\n GitLabProject,\n} from '../types/gitlab.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * GitLab service for interacting with GitLab REST API v4\n */\nexport class GitLabService {\n private readonly DEFAULT_INSTANCE = 'https://gitlab.com';\n private readonly MAX_DESCRIPTION_LENGTH = 5000;\n\n /**\n * Get stored GitLab credentials\n */\n private async getCredentials(): Promise<{ accessToken: string; instanceUrl: string }> {\n const creds = await storageService.getServiceCredentials('gitlab');\n if (!creds || !creds.accessToken) {\n throw new GitLabError('Not authenticated with GitLab', {\n hint: 'Run: bragduck auth gitlab',\n });\n }\n\n // Check token expiry (future feature)\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new GitLabError('Access token has expired', {\n hint: 'Run: bragduck auth gitlab',\n });\n }\n\n return {\n accessToken: creds.accessToken,\n instanceUrl: creds.instanceUrl || this.DEFAULT_INSTANCE,\n };\n }\n\n /**\n * Make authenticated request to GitLab API\n */\n private async request<T>(endpoint: string): Promise<T> {\n const { accessToken, instanceUrl } = await this.getCredentials();\n const baseUrl = `${instanceUrl}/api/v4`;\n const url = `${baseUrl}${endpoint}`;\n\n logger.debug(`GitLab API: GET ${endpoint}`);\n\n const response = await fetch(url, {\n headers: {\n 'PRIVATE-TOKEN': accessToken,\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new GitLabError('Invalid or expired access token', {\n hint: 'Run: bragduck auth gitlab',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new GitLabError('Insufficient token permissions', {\n hint: 'Token requires scopes: api, read_api, read_user',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new GitLabError('Resource not found', {\n hint: 'Check repository URL and token permissions',\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new GitLabError('Rate limit exceeded', {\n hint: 'Wait a moment and try again',\n originalError: statusText,\n });\n }\n\n throw new GitLabError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Extract namespace and project from git remote URL\n */\n private parseRemoteUrl(url: string): { namespace: string; project: string } | null {\n // Patterns:\n // https://gitlab.com/owner/repo.git\n // git@gitlab.com:owner/repo.git\n // https://custom-gitlab.com/owner/repo.git\n const match = url.match(/[:/]([\\w-]+)\\/([\\w-]+?)(?:\\.git)?$/);\n if (match && match[1] && match[2]) {\n return {\n namespace: match[1],\n project: match[2],\n };\n }\n return null;\n }\n\n /**\n * Get project path from git remote\n */\n private async getProjectFromGit(): Promise<{\n namespace: string;\n project: string;\n projectPath: string;\n }> {\n try {\n const { stdout } = await execAsync('git remote get-url origin');\n const remoteUrl = stdout.trim();\n\n const parsed = this.parseRemoteUrl(remoteUrl);\n if (!parsed) {\n throw new GitLabError('Could not parse GitLab project from remote URL', {\n url: remoteUrl,\n });\n }\n\n return {\n ...parsed,\n projectPath: `${parsed.namespace}/${parsed.project}`,\n };\n } catch (error: unknown) {\n if (error instanceof GitLabError) {\n throw error;\n }\n throw new GitError('Could not get git remote URL');\n }\n }\n\n /**\n * Validate that this is a GitLab repository and credentials work\n */\n async validateGitLabRepository(): Promise<void> {\n // Check if in git repo\n await gitService.validateRepository();\n\n // Get project info from git\n const { projectPath } = await this.getProjectFromGit();\n\n // Test API access by fetching project\n const encodedPath = encodeURIComponent(projectPath);\n try {\n await this.request<GitLabProject>(`/projects/${encodedPath}`);\n } catch (error: unknown) {\n if (error instanceof GitLabError) {\n throw error;\n }\n throw new GitLabError('Could not access GitLab project via API', {\n hint: 'Check that this is a GitLab repository and your token is valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get repository information\n */\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const { projectPath } = await this.getProjectFromGit();\n const encodedPath = encodeURIComponent(projectPath);\n const project = await this.request<GitLabProject>(`/projects/${encodedPath}`);\n\n const [owner, name] = projectPath.split('/');\n\n return {\n owner: owner || '',\n name: name || '',\n fullName: project.path_with_namespace,\n url: project.web_url,\n };\n }\n\n /**\n * Fetch merged MRs with pagination\n */\n async getMergedMRs(options: FetchGitLabMRsOptions = {}): Promise<GitLabMergeRequest[]> {\n const { projectPath } = await this.getProjectFromGit();\n const encodedPath = encodeURIComponent(projectPath);\n\n // Build query params\n const params = new URLSearchParams({\n state: 'merged',\n order_by: 'updated_at',\n sort: 'desc',\n per_page: '100',\n });\n\n // Date filtering\n if (options.days) {\n const since = new Date();\n since.setDate(since.getDate() - options.days);\n params.append('updated_after', since.toISOString());\n }\n\n // Author filtering\n if (options.author) {\n params.append('author_username', options.author);\n }\n\n // Pagination (page-based)\n const allMRs: GitLabMergeRequest[] = [];\n let page = 1;\n\n while (true) {\n params.set('page', page.toString());\n const endpoint = `/projects/${encodedPath}/merge_requests?${params}`;\n\n const mrs = await this.request<GitLabMergeRequest[]>(endpoint);\n allMRs.push(...mrs);\n\n logger.debug(\n `Fetched ${mrs.length} MRs (total: ${allMRs.length})${mrs.length === 100 ? ', fetching next page...' : ''}`\n );\n\n // Check limit\n if (options.limit && allMRs.length >= options.limit) {\n return allMRs.slice(0, options.limit);\n }\n\n // Check if more pages (last page has < per_page results)\n if (mrs.length < 100) {\n break;\n }\n\n page++;\n }\n\n return allMRs;\n }\n\n /**\n * Get MRs by current user\n */\n async getMRsByCurrentUser(options: FetchGitLabMRsOptions = {}): Promise<GitLabMergeRequest[]> {\n const username = await this.getCurrentGitLabUser();\n if (!username) {\n throw new GitLabError('Could not get current user username');\n }\n return this.getMergedMRs({\n ...options,\n author: username,\n });\n }\n\n /**\n * Get current authenticated user\n */\n async getCurrentGitLabUser(): Promise<string | null> {\n try {\n const user = await this.request<GitLabUser>('/user');\n return user.username;\n } catch {\n return null;\n }\n }\n\n /**\n * Transform GitLab MR to GitCommit format\n */\n transformMRToCommit(mr: GitLabMergeRequest): GitCommit {\n const message = this.formatMessage(mr.title, mr.description);\n\n return {\n sha: `mr-${mr.iid}`, // Use iid (project-scoped)\n message,\n author: mr.author.username,\n authorEmail: '', // Not available in MR response\n date: mr.created_at,\n url: mr.web_url,\n diffStats: {\n filesChanged: mr.diff_stats?.file_count || 0,\n insertions: mr.diff_stats?.additions || 0,\n deletions: mr.diff_stats?.deletions || 0,\n },\n };\n }\n\n /**\n * Format MR message with title and description\n */\n private formatMessage(title: string, description: string | null): string {\n if (!description) return title;\n const truncated = description.substring(0, this.MAX_DESCRIPTION_LENGTH);\n return `${title}\\n\\n${truncated}`;\n }\n}\n\nexport const gitlabService = new GitLabService();\n","import { jiraService } from '../services/jira.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Jira adapter for syncing issues\n */\nexport const jiraSyncAdapter: SyncAdapter = {\n name: 'jira',\n\n async validate(): Promise<void> {\n await jiraService.validateJiraInstance();\n },\n\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const user = await jiraService.getCurrentUser();\n // Access private method via bracket notation to avoid exposing it publicly\n const creds = await (\n jiraService as unknown as { getCredentials: () => Promise<{ instanceUrl: string }> }\n ).getCredentials();\n\n const userName = user || 'Unknown User';\n const baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n\n return {\n owner: userName,\n name: 'Jira Issues',\n fullName: `${userName}'s Jira Issues`,\n url: baseUrl,\n };\n },\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n // Handle 'current' author\n const author = options.author === 'current' ? await this.getCurrentUser() : options.author;\n\n return jiraService.getIssues({\n days: options.days,\n limit: options.limit,\n author: author || undefined,\n });\n },\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await this.validate();\n return true;\n } catch {\n return false;\n }\n },\n\n async getCurrentUser(): Promise<string | null> {\n return jiraService.getCurrentUser();\n },\n};\n","import { JiraError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport type {\n JiraIssue,\n JiraSearchResponse,\n JiraUser,\n FetchJiraIssuesOptions,\n} from '../types/atlassian.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Jira service for interacting with Jira Cloud and Server REST API\n */\nexport class JiraService {\n private readonly MAX_DESCRIPTION_LENGTH = 5000;\n\n /**\n * Get stored Jira credentials\n */\n private async getCredentials(): Promise<{\n email: string;\n apiToken: string;\n instanceUrl: string;\n }> {\n const creds = await storageService.getServiceCredentials('jira');\n if (!creds || !creds.username || !creds.accessToken || !creds.instanceUrl) {\n throw new JiraError('Not authenticated with Jira', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n // Check token expiry\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new JiraError('API token has expired', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n return {\n email: creds.username,\n apiToken: creds.accessToken,\n instanceUrl: creds.instanceUrl,\n };\n }\n\n /**\n * Make authenticated request to Jira API\n */\n private async request<T>(endpoint: string, method = 'GET', body?: unknown): Promise<T> {\n const { email, apiToken, instanceUrl } = await this.getCredentials();\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n\n // Ensure instanceUrl has protocol\n const baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n\n logger.debug(`Jira API: ${method} ${endpoint}`);\n\n const options: Parameters<typeof fetch>[1] = {\n method,\n headers: {\n Authorization: `Basic ${auth}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n };\n\n if (body) {\n options.body = JSON.stringify(body);\n }\n\n const response = await fetch(`${baseUrl}${endpoint}`, options);\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new JiraError('Invalid or expired API token', {\n hint: 'Run: bragduck auth atlassian',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new JiraError('Forbidden - check token permissions', {\n hint: 'Token needs: read access to issues',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new JiraError('Resource not found', {\n originalError: statusText,\n });\n } else if (status === 410) {\n throw new JiraError('Resource no longer available (deleted, archived, or moved)', {\n hint: 'The Jira issue, project, or instance may have been deleted/archived. Verify your instance URL and that the resource still exists.',\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new JiraError('Rate limit exceeded', {\n hint: 'Wait a few minutes before trying again',\n originalError: statusText,\n });\n }\n\n throw new JiraError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Validate Jira instance and credentials\n */\n async validateJiraInstance(): Promise<void> {\n try {\n await this.request<JiraUser>('/rest/api/2/myself');\n } catch (error: unknown) {\n if (error instanceof JiraError) {\n throw error;\n }\n throw new JiraError('Could not access Jira instance via API', {\n hint: 'Check that the instance URL is correct and your credentials are valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get current user's email\n */\n async getCurrentUser(): Promise<string | null> {\n try {\n const user = await this.request<JiraUser>('/rest/api/2/myself');\n return user.emailAddress;\n } catch {\n return null;\n }\n }\n\n /**\n * Build JQL query from options\n */\n private buildJQL(options: FetchJiraIssuesOptions): string {\n const queries: string[] = [];\n\n // Status filter (completed issues only)\n queries.push('status IN (Done, Resolved, Closed)');\n\n // Date filtering\n if (options.days) {\n queries.push(`updated >= -${options.days}d`);\n }\n\n // Author filtering\n if (options.author) {\n queries.push(`creator = \"${options.author}\"`);\n }\n\n // Custom JQL\n if (options.jql) {\n queries.push(`(${options.jql})`);\n }\n\n return queries.join(' AND ');\n }\n\n /**\n * Estimate issue complexity for impact scoring\n */\n private estimateComplexity(issue: JiraIssue): number {\n const typeScores: Record<string, number> = {\n Epic: 500,\n Story: 200,\n Task: 100,\n Bug: 100,\n 'Sub-task': 50,\n };\n\n return typeScores[issue.fields.issuetype.name] || 100;\n }\n\n /**\n * Fetch issues with optional filtering\n */\n async getIssues(options: FetchJiraIssuesOptions = {}): Promise<GitCommit[]> {\n const jql = this.buildJQL(options);\n const fields = [\n 'summary',\n 'description',\n 'created',\n 'updated',\n 'resolutiondate',\n 'creator',\n 'status',\n 'issuetype',\n ];\n\n const allIssues: JiraIssue[] = [];\n let startAt = 0;\n const maxResults = 100;\n\n // Pagination: loop until all results fetched\n while (true) {\n const endpoint = `/rest/api/2/search?jql=${encodeURIComponent(jql)}&startAt=${startAt}&maxResults=${maxResults}&fields=${fields.join(',')}`;\n\n const response = await this.request<JiraSearchResponse>(endpoint);\n\n allIssues.push(...response.issues);\n\n logger.debug(\n `Fetched ${response.issues.length} issues (total: ${allIssues.length} of ${response.total})${startAt + maxResults < response.total ? ', fetching next page...' : ''}`\n );\n\n // Check if we've fetched all issues\n if (startAt + maxResults >= response.total) {\n break;\n }\n\n // Check limit\n if (options.limit && allIssues.length >= options.limit) {\n return allIssues.slice(0, options.limit).map((issue) => this.transformIssueToCommit(issue));\n }\n\n startAt += maxResults;\n }\n\n return allIssues.map((issue) => this.transformIssueToCommit(issue));\n }\n\n /**\n * Fetch issues for the current authenticated user\n */\n async getIssuesByCurrentUser(\n options: Omit<FetchJiraIssuesOptions, 'author'> = {}\n ): Promise<GitCommit[]> {\n const email = await this.getCurrentUser();\n if (!email) {\n throw new JiraError('Could not get current user');\n }\n\n return this.getIssues({\n ...options,\n author: email,\n });\n }\n\n /**\n * Transform Jira issue to GitCommit format with external fields\n */\n transformIssueToCommit(issue: JiraIssue, instanceUrl?: string): GitCommit {\n // Format message: title + description\n let message = issue.fields.summary;\n if (issue.fields.description) {\n const truncatedDesc = issue.fields.description.substring(0, this.MAX_DESCRIPTION_LENGTH);\n message = `${issue.fields.summary}\\n\\n${truncatedDesc}`;\n }\n\n // Use resolution date if available, otherwise updated date\n const date = issue.fields.resolutiondate || issue.fields.updated;\n\n // Build URL (use provided instanceUrl or try to get from storage)\n let baseUrl = 'https://jira.atlassian.net';\n if (instanceUrl) {\n baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n } else {\n try {\n const creds = storageService.getServiceCredentials('jira') as {\n instanceUrl?: string;\n } | null;\n if (creds?.instanceUrl) {\n baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n }\n } catch {\n // Use default if credentials not available\n }\n }\n const url = `${baseUrl}/browse/${issue.key}`;\n\n return {\n sha: issue.key,\n message,\n author: issue.fields.creator.displayName,\n authorEmail: issue.fields.creator.emailAddress,\n date,\n url,\n diffStats: {\n filesChanged: 0,\n insertions: this.estimateComplexity(issue),\n deletions: 0,\n },\n externalId: issue.key,\n externalType: 'issue',\n externalSource: 'jira',\n externalUrl: url,\n };\n }\n}\n\nexport const jiraService = new JiraService();\n","import { confluenceService } from '../services/confluence.service.js';\nimport type { SyncAdapter, FetchWorkItemsOptions } from './base-adapter.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Confluence adapter for syncing pages\n */\nexport const confluenceSyncAdapter: SyncAdapter = {\n name: 'confluence',\n\n async validate(): Promise<void> {\n await confluenceService.validateConfluenceInstance();\n },\n\n async getRepositoryInfo(): Promise<{\n owner: string;\n name: string;\n fullName: string;\n url: string;\n }> {\n const user = await confluenceService.getCurrentUser();\n // Access private method via bracket notation to avoid exposing it publicly\n const creds = await (\n confluenceService as unknown as { getCredentials: () => Promise<{ instanceUrl: string }> }\n ).getCredentials();\n\n const userName = user || 'Unknown User';\n const baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n\n return {\n owner: userName,\n name: 'Confluence Pages',\n fullName: `${userName}'s Confluence Pages`,\n url: `${baseUrl}/wiki`,\n };\n },\n\n async fetchWorkItems(options: FetchWorkItemsOptions): Promise<GitCommit[]> {\n // Handle 'current' author\n const author = options.author === 'current' ? await this.getCurrentUser() : options.author;\n\n return confluenceService.getPages({\n days: options.days,\n limit: options.limit,\n author: author || undefined,\n });\n },\n\n async isAuthenticated(): Promise<boolean> {\n try {\n await this.validate();\n return true;\n } catch {\n return false;\n }\n },\n\n async getCurrentUser(): Promise<string | null> {\n return confluenceService.getCurrentUser();\n },\n};\n","import { ConfluenceError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport { storageService } from './storage.service.js';\nimport type {\n ConfluencePage,\n ConfluenceSearchResponse,\n FetchConfluencePagesOptions,\n} from '../types/atlassian.types.js';\nimport type { GitCommit } from '../types/git.types.js';\n\n/**\n * Confluence service for interacting with Confluence Cloud and Server REST API\n */\nexport class ConfluenceService {\n /**\n * Get stored Confluence credentials\n */\n private async getCredentials(): Promise<{\n email: string;\n apiToken: string;\n instanceUrl: string;\n }> {\n const creds = await storageService.getServiceCredentials('confluence');\n if (!creds || !creds.username || !creds.accessToken || !creds.instanceUrl) {\n throw new ConfluenceError('Not authenticated with Confluence', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n // Check token expiry\n if (creds.expiresAt && creds.expiresAt < Date.now()) {\n throw new ConfluenceError('API token has expired', {\n hint: 'Run: bragduck auth atlassian',\n });\n }\n\n return {\n email: creds.username,\n apiToken: creds.accessToken,\n instanceUrl: creds.instanceUrl,\n };\n }\n\n /**\n * Make authenticated request to Confluence API\n */\n private async request<T>(endpoint: string, method = 'GET', body?: unknown): Promise<T> {\n const { email, apiToken, instanceUrl } = await this.getCredentials();\n const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');\n\n // Ensure instanceUrl has protocol\n const baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n\n logger.debug(`Confluence API: ${method} ${endpoint}`);\n\n const options: Parameters<typeof fetch>[1] = {\n method,\n headers: {\n Authorization: `Basic ${auth}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n };\n\n if (body) {\n options.body = JSON.stringify(body);\n }\n\n const response = await fetch(`${baseUrl}${endpoint}`, options);\n\n if (!response.ok) {\n const statusText = response.statusText;\n const status = response.status;\n\n if (status === 401) {\n throw new ConfluenceError('Invalid or expired API token', {\n hint: 'Run: bragduck auth atlassian',\n originalError: statusText,\n });\n } else if (status === 403) {\n throw new ConfluenceError('Forbidden - check token permissions', {\n hint: 'Token needs: read access to pages',\n originalError: statusText,\n });\n } else if (status === 404) {\n throw new ConfluenceError('Resource not found', {\n originalError: statusText,\n });\n } else if (status === 410) {\n throw new ConfluenceError('Resource no longer available (deleted, archived, or moved)', {\n hint: 'The Confluence page, space, or instance may have been deleted/archived. Verify your instance URL and that the resource still exists.',\n originalError: statusText,\n });\n } else if (status === 429) {\n throw new ConfluenceError('Rate limit exceeded', {\n hint: 'Wait a few minutes before trying again',\n originalError: statusText,\n });\n }\n\n throw new ConfluenceError(`API request failed: ${statusText}`, {\n originalError: statusText,\n });\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Validate Confluence instance and credentials\n */\n async validateConfluenceInstance(): Promise<void> {\n try {\n // Test with a simple content search\n await this.request<ConfluenceSearchResponse>('/wiki/rest/api/content?type=page&limit=1');\n } catch (error: unknown) {\n if (error instanceof ConfluenceError) {\n throw error;\n }\n throw new ConfluenceError('Could not access Confluence instance via API', {\n hint: 'Check that the instance URL is correct and your credentials are valid',\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get current user's email\n */\n async getCurrentUser(): Promise<string | null> {\n try {\n const creds = await this.getCredentials();\n return creds.email;\n } catch {\n return null;\n }\n }\n\n /**\n * Build CQL query from options\n */\n private buildCQL(options: FetchConfluencePagesOptions): string {\n const queries: string[] = [];\n\n // Type filter\n queries.push('type=page');\n\n // Date filtering\n if (options.days) {\n queries.push(`lastModified >= now(\"-${options.days}d\")`);\n }\n\n // Author filtering\n if (options.author) {\n queries.push(`creator = \"${options.author}\"`);\n }\n\n // Custom CQL\n if (options.cql) {\n queries.push(`(${options.cql})`);\n }\n\n return queries.join(' AND ');\n }\n\n /**\n * Estimate page size for impact scoring\n */\n private estimatePageSize(page: ConfluencePage): number {\n const content = page.body?.storage?.value || '';\n // Rough heuristic: 1 line per 80 characters\n return Math.ceil(content.length / 80);\n }\n\n /**\n * Fetch pages with optional filtering\n */\n async getPages(options: FetchConfluencePagesOptions = {}): Promise<GitCommit[]> {\n const cql = this.buildCQL(options);\n\n const allPages: ConfluencePage[] = [];\n let start = 0;\n const limit = 100;\n\n // Pagination: loop until all results fetched\n while (true) {\n const params: Record<string, string> = {\n type: 'page',\n status: 'current',\n start: start.toString(),\n limit: limit.toString(),\n expand: 'version,body.storage',\n };\n\n if (cql) {\n params.cql = cql;\n }\n\n const queryString = Object.entries(params)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&');\n\n const endpoint = `/wiki/rest/api/content?${queryString}`;\n\n const response = await this.request<ConfluenceSearchResponse>(endpoint);\n\n allPages.push(...response.results);\n\n logger.debug(\n `Fetched ${response.results.length} pages (total: ${allPages.length})${response.results.length === limit ? ', fetching next page...' : ''}`\n );\n\n // Check if we've fetched all pages\n if (response.results.length < limit) {\n break;\n }\n\n // Check limit\n if (options.limit && allPages.length >= options.limit) {\n return allPages.slice(0, options.limit).map((page) => this.transformPageToCommit(page));\n }\n\n start += limit;\n }\n\n return allPages.map((page) => this.transformPageToCommit(page));\n }\n\n /**\n * Fetch pages for the current authenticated user\n */\n async getPagesByCurrentUser(\n options: Omit<FetchConfluencePagesOptions, 'author'> = {}\n ): Promise<GitCommit[]> {\n const email = await this.getCurrentUser();\n if (!email) {\n throw new ConfluenceError('Could not get current user');\n }\n\n return this.getPages({\n ...options,\n author: email,\n });\n }\n\n /**\n * Transform Confluence page to GitCommit format with external fields\n */\n transformPageToCommit(page: ConfluencePage, instanceUrl?: string): GitCommit {\n // Format message: title + version info\n const message = `${page.title}\\n\\n[Confluence Page v${page.version.number}]`;\n\n // Build URL (use provided instanceUrl or try to get from storage)\n let baseUrl = 'https://confluence.atlassian.net';\n if (instanceUrl) {\n baseUrl = instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`;\n } else {\n try {\n const creds = storageService.getServiceCredentials('confluence') as {\n instanceUrl?: string;\n } | null;\n if (creds?.instanceUrl) {\n baseUrl = creds.instanceUrl.startsWith('http')\n ? creds.instanceUrl\n : `https://${creds.instanceUrl}`;\n }\n } catch {\n // Use default if credentials not available\n }\n }\n const url = `${baseUrl}/wiki${page._links.webui}`;\n\n return {\n sha: page.id,\n message,\n author: page.version.by.displayName,\n authorEmail: page.version.by.email,\n date: page.version.when,\n url,\n diffStats: {\n filesChanged: 1,\n insertions: this.estimatePageSize(page),\n deletions: 0,\n },\n externalId: page.id,\n externalType: 'page',\n externalSource: 'confluence',\n externalUrl: url,\n };\n }\n}\n\nexport const confluenceService = new ConfluenceService();\n","import boxen from 'boxen';\nimport { authService } from '../services/auth.service.js';\nimport { initCommand } from '../commands/init.js';\nimport { logger } from './logger.js';\nimport { promptConfirm } from '../ui/prompts.js';\nimport { theme, boxStyles } from '../ui/theme.js';\n\n/**\n * Ensure user is authenticated, offering to run init if not\n * Returns true if authenticated (or after successful auth), false if user declined\n */\nexport async function ensureAuthenticated(): Promise<boolean> {\n const isAuthenticated = await authService.isAuthenticated();\n\n if (isAuthenticated) {\n return true;\n }\n\n // User is not authenticated - offer to authenticate now\n logger.log('');\n logger.log(\n boxen(\n theme.warning('Not authenticated') +\n '\\n\\n' +\n 'You need to be logged in to use this command.\\n\\n' +\n 'Would you like to authenticate now?',\n boxStyles.warning\n )\n );\n logger.log('');\n\n const shouldAuth = await promptConfirm('Authenticate now?', true);\n\n if (!shouldAuth) {\n logger.log('');\n logger.info(\n theme.secondary('Authentication skipped. Run ') +\n theme.command('bragduck auth login') +\n theme.secondary(\" when you're ready to authenticate.\")\n );\n logger.log('');\n return false;\n }\n\n // Run init command inline\n try {\n await initCommand();\n return true;\n } catch {\n // Init command will handle its own error display\n return false;\n }\n}\n\n/**\n * Simple authentication check without offering init\n * Used for commands that should fail fast if not authenticated\n */\nexport async function requireAuthentication(): Promise<void> {\n const isAuthenticated = await authService.isAuthenticated();\n\n if (!isAuthenticated) {\n logger.log('');\n logger.log(\n boxen(\n theme.error('Not authenticated') +\n '\\n\\n' +\n 'You need to be logged in to use this command.\\n\\n' +\n theme.secondary('Run ') +\n theme.command('bragduck auth login') +\n theme.secondary(' to authenticate.'),\n boxStyles.error\n )\n );\n logger.log('');\n process.exit(1);\n }\n}\n","import ora from 'ora';\nimport boxen from 'boxen';\nimport chalk from 'chalk';\nimport { authService } from '../services/auth.service.js';\nimport { logger } from '../utils/logger.js';\nimport type { BragduckError } from '../utils/errors.js';\n\n/**\n * Init command: Authenticate with Bragduck\n */\nexport async function initCommand(): Promise<void> {\n // Deprecation warning\n logger.log('');\n logger.log(\n boxen(\n chalk.yellow.bold('⚠ Deprecation Notice') +\n '\\n\\n' +\n `The ${chalk.cyan('init')} command is deprecated.\\n` +\n `Please use ${chalk.cyan('bragduck auth login')} instead.\\n\\n` +\n chalk.dim('This command will be removed in v3.0.0'),\n {\n padding: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n dimBorder: true,\n }\n )\n );\n logger.log('');\n\n logger.info('Starting authentication flow...');\n logger.log('');\n\n // Check if already authenticated\n const isAuthenticated = await authService.isAuthenticated();\n if (isAuthenticated) {\n const userInfo = authService.getUserInfo();\n if (userInfo) {\n logger.log(\n boxen(\n `${chalk.yellow('Already authenticated!')}\\n\\n` +\n `${chalk.gray('User:')} ${userInfo.name}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('Run')} ${chalk.cyan('bragduck logout')} ${chalk.dim('to sign out')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n }\n )\n );\n logger.log('');\n globalThis.setTimeout(() => {\n process.exit(0);\n }, 100);\n return;\n }\n }\n\n const spinner = ora('Opening browser for authentication...').start();\n\n try {\n // Start OAuth flow\n spinner.text = 'Waiting for authentication...';\n const userInfo = await authService.login();\n\n spinner.succeed('Authentication successful!');\n logger.log('');\n\n // Show success message\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Successfully authenticated!')}\\n\\n` +\n `${chalk.gray('Welcome,')} ${chalk.cyan(userInfo.name)}\\n` +\n `${chalk.gray('Email:')} ${userInfo.email}\\n\\n` +\n `${chalk.dim('You can now use')} ${chalk.cyan('bragduck scan')} ${chalk.dim('to create brags!')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n logger.log('');\n\n // Exit successfully - force immediate exit\n // Use setTimeout to ensure all logs are flushed\n globalThis.setTimeout(() => {\n process.exit(0);\n }, 100);\n\n // Return to prevent further execution\n return;\n } catch (error) {\n spinner.fail('Authentication failed');\n logger.log('');\n\n const err = error as BragduckError;\n\n // Show error message\n logger.log(\n boxen(\n `${chalk.red.bold('✗ Authentication Failed')}\\n\\n` +\n `${err.message}\\n\\n` +\n `${chalk.dim('Hint:')} ${getErrorHint(err)}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'red',\n }\n )\n );\n\n process.exit(1);\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError): string {\n if (error.name === 'OAuthError') {\n if (error.message.includes('timeout')) {\n return 'Try again and complete the authentication within 2 minutes';\n }\n if (error.message.includes('CSRF')) {\n return 'This might be a security issue. Try running the command again';\n }\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and firewall settings';\n }\n\n if (error.name === 'AuthenticationError') {\n return 'Verify your credentials and try again';\n }\n\n return 'Try running the command again or check the logs with DEBUG=* bragduck init';\n}\n","import { checkbox, confirm, input, select, editor } from '@inquirer/prompts';\nimport boxen from 'boxen';\nimport type { GitCommit } from '../types/git.types.js';\nimport type { RefinedCommit, RefinedBrag, OrganisationItem } from '../types/api.types.js';\nimport { formatCommitChoice } from './formatters.js';\nimport { theme, colors, boxStyles } from './theme.js';\n\n/**\n * Prompt user to select commits\n */\nexport async function promptSelectCommits(commits: GitCommit[]): Promise<string[]> {\n if (commits.length === 0) {\n return [];\n }\n\n const choices = commits.map((commit) => ({\n name: formatCommitChoice(commit),\n value: commit.sha,\n checked: false,\n }));\n\n const selected = await checkbox({\n message: 'Select PRs to brag about (use space to select, enter to confirm):',\n choices,\n pageSize: 10,\n loop: false,\n });\n\n return selected;\n}\n\n/**\n * Prompt user to confirm action\n */\nexport async function promptConfirm(\n message: string,\n defaultValue: boolean = true\n): Promise<boolean> {\n return await confirm({\n message,\n default: defaultValue,\n });\n}\n\n/**\n * Prompt user for text input\n */\nexport async function promptInput(message: string, defaultValue?: string): Promise<string> {\n return await input({\n message,\n default: defaultValue,\n });\n}\n\n/**\n * Prompt user to select from options\n */\nexport async function promptSelect<T extends string>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return await select({\n message,\n choices,\n });\n}\n\n/**\n * Prompt for number of days to scan\n */\nexport async function promptDaysToScan(defaultDays: number = 30): Promise<number> {\n const choices = [\n { name: '7 days', value: '7', description: 'Last week' },\n { name: '30 days (Recommended)', value: '30', description: 'Last month' },\n { name: '60 days', value: '60', description: 'Last 2 months' },\n { name: '90 days', value: '90', description: 'Last 3 months' },\n { name: 'Custom', value: 'custom', description: 'Enter custom number of days' },\n ];\n\n const selected = await select({\n message: 'How many days back should we scan for PRs?',\n choices,\n default: '30',\n });\n\n if (selected === 'custom') {\n const customDays = await input({\n message: 'Enter number of days:',\n default: defaultDays.toString(),\n validate: (value) => {\n const num = parseInt(value, 10);\n if (isNaN(num) || num <= 0) {\n return 'Please enter a valid positive number';\n }\n return true;\n },\n });\n return parseInt(customDays, 10);\n }\n\n return parseInt(selected, 10);\n}\n\n/**\n * Prompt user to select sort option before PR selection\n */\nexport async function promptSortOption(): Promise<'date' | 'size' | 'files' | 'none'> {\n const choices = [\n {\n name: 'By date (newest first)',\n value: 'date' as const,\n description: 'Most recent PRs first',\n },\n { name: 'By size (largest first)', value: 'size' as const, description: 'Most lines changed' },\n { name: 'By files (most files)', value: 'files' as const, description: 'Most files changed' },\n { name: 'No sorting', value: 'none' as const, description: 'Keep original order' },\n ];\n\n return await select({\n message: 'How would you like to sort the PRs?',\n choices,\n default: 'date',\n });\n}\n\n/**\n * Prompt user to select organisation for brags\n */\nexport async function promptSelectOrganisation(\n organisations: OrganisationItem[]\n): Promise<string | null> {\n const choices = [\n { name: 'No company', value: 'none' as const },\n ...organisations.map((org) => ({\n name: org.name,\n value: org.id,\n })),\n ];\n\n const selected = await select({\n message: 'Attach brags to which company?',\n choices,\n default: 'none',\n });\n\n return selected === 'none' ? null : selected;\n}\n\n/**\n * Prompt user to review and edit brags before creation\n */\nexport async function promptReviewBrags(\n refinedBrags: RefinedBrag[] | RefinedCommit[],\n selectedCommits?: GitCommit[]\n): Promise<(RefinedBrag | RefinedCommit)[]> {\n const acceptedBrags: (RefinedBrag | RefinedCommit)[] = [];\n\n console.log('\\n' + theme.info('Review each brag before creation:') + '\\n');\n\n for (let i = 0; i < refinedBrags.length; i++) {\n let currentBrag = refinedBrags[i];\n const current = i + 1;\n const total = refinedBrags.length;\n let reviewingBrag = true;\n\n // Loop until user accepts, skips, or cancels\n while (reviewingBrag) {\n // Check if this is the new RefinedBrag type\n const isNewBragType = !('sha' in currentBrag);\n\n // Display brag details\n let displaySha: string = `#${i + 1}`;\n let prUrl: string | undefined;\n\n if (isNewBragType && selectedCommits) {\n const commit = selectedCommits[i];\n if (commit) {\n displaySha = commit.sha.startsWith('pr-')\n ? commit.sha.replace('pr-', '#')\n : commit.sha.substring(0, 7);\n prUrl = commit.url;\n }\n } else if (!isNewBragType) {\n const commit = currentBrag as RefinedCommit;\n displaySha = commit.sha.startsWith('pr-')\n ? commit.sha.replace('pr-', '#')\n : commit.sha.substring(0, 7);\n prUrl = commit.commit_url;\n } else {\n displaySha = `#${i + 1}`;\n }\n\n // Get impact score\n const impactScore = isNewBragType\n ? (currentBrag as RefinedBrag).suggested_impactLevel?.toString() || 'N/A'\n : (currentBrag as RefinedCommit).impact_score?.toString() || 'N/A';\n\n let bragDetails =\n `${theme.step(current, total)} ${colors.highlight(displaySha)}\\n\\n` +\n `${theme.label('Title')} ${colors.white(currentBrag.refined_title)}\\n\\n` +\n `${theme.label('Description')}\\n${colors.white(currentBrag.refined_description)}\\n\\n` +\n `${theme.label('Tags')} ${colors.primary((currentBrag.suggested_tags || []).join(', ') || 'none')}\\n\\n` +\n `${theme.label('Impact Score')} ${colors.highlight(impactScore)}`;\n\n // Add PR URL if available\n if (prUrl) {\n bragDetails += `\\n\\n${theme.label('PR Link')} ${colors.link(prUrl)}`;\n }\n\n console.log(boxen(bragDetails, boxStyles.info));\n console.log('');\n\n // Prompt for action\n const action = await select({\n message: `What would you like to do with this brag?`,\n choices: [\n { name: '✓ Accept', value: 'accept', description: 'Add this brag as-is' },\n { name: '✎ Edit title', value: 'edit-title', description: 'Modify the title' },\n {\n name: '✎ Edit description',\n value: 'edit-desc',\n description: 'Modify the description',\n },\n { name: '✎ Edit both', value: 'edit-both', description: 'Modify title and description' },\n { name: '✗ Skip', value: 'skip', description: 'Skip this brag' },\n ...(current < total\n ? [\n {\n name: '✓ Accept all remaining',\n value: 'accept-all',\n description: 'Accept this and all remaining brags',\n },\n ]\n : []),\n { name: '✗ Cancel', value: 'cancel', description: 'Cancel and discard all brags' },\n ],\n });\n\n if (action === 'cancel') {\n return [];\n }\n\n if (action === 'accept-all') {\n acceptedBrags.push(currentBrag);\n // Add all remaining brags\n for (let j = i + 1; j < refinedBrags.length; j++) {\n acceptedBrags.push(refinedBrags[j]);\n }\n reviewingBrag = false;\n // Skip to end since we accepted all\n i = refinedBrags.length - 1;\n break;\n }\n\n if (action === 'skip') {\n reviewingBrag = false;\n continue;\n }\n\n if (action === 'accept') {\n acceptedBrags.push(currentBrag);\n reviewingBrag = false;\n continue;\n }\n\n // Handle editing\n let editedBrag = { ...currentBrag };\n\n if (action === 'edit-title' || action === 'edit-both') {\n console.log('');\n const newTitle = await input({\n message: 'Enter new title:',\n default: currentBrag.refined_title,\n });\n editedBrag.refined_title = newTitle;\n }\n\n if (action === 'edit-desc' || action === 'edit-both') {\n console.log('');\n const newDesc = await editor({\n message: 'Edit description (will open your default editor):',\n default: currentBrag.refined_description,\n });\n editedBrag.refined_description = newDesc;\n }\n\n // Update current brag with edits and loop back to review\n currentBrag = editedBrag;\n console.log('\\n' + theme.success('✓ Changes saved. Review your edits:') + '\\n');\n }\n }\n\n return acceptedBrags;\n}\n","import Table from 'cli-table3';\nimport terminalLink from 'terminal-link';\nimport type { GitCommit } from '../types/git.types.js';\nimport type { RefinedCommit, RefinedBrag } from '../types/api.types.js';\nimport { theme, colors, getSizeIndicator, formatDiffStats, tableStyles } from './theme.js';\n\n/**\n * Format a commit for display in checkbox list\n */\nexport function formatCommitChoice(commit: GitCommit): string {\n // Handle PR format (pr-123) by displaying as #123\n let displaySha: string;\n if (commit.sha.startsWith('pr-')) {\n const prNumber = commit.sha.replace('pr-', '#');\n displaySha = colors.highlight(prNumber);\n } else {\n displaySha = colors.highlight(commit.sha.substring(0, 7));\n }\n\n const lines = commit.message.split('\\n');\n const title = lines[0]; // First line only\n\n // Extract PR body preview if available (lines after the first)\n let bodyPreview = '';\n if (lines.length > 1) {\n const body = lines.slice(1).join(' ').trim();\n if (body.length > 0) {\n const preview = body.length > 80 ? body.substring(0, 80) + '...' : body;\n bodyPreview = `\\n ${colors.infoDim(preview)}`;\n }\n }\n\n const author = colors.info(`by ${commit.author}`);\n const date = colors.info(new Date(commit.date).toLocaleDateString());\n\n let stats = '';\n let sizeIndicator = '';\n if (commit.diffStats) {\n const { filesChanged, insertions, deletions } = commit.diffStats;\n sizeIndicator = ` ${getSizeIndicator(insertions, deletions)}`;\n stats = colors.info(` [${filesChanged} files, ${formatDiffStats(insertions, deletions)}]`);\n }\n\n return `${displaySha} ${title}${sizeIndicator}${stats}\\n ${author} • ${date}${bodyPreview}`;\n}\n\n/**\n * Format refined commits as a preview table\n */\nexport function formatRefinedCommitsTable(\n brags: RefinedBrag[] | RefinedCommit[],\n selectedCommits?: GitCommit[]\n): string {\n const table = new Table({\n head: [\n colors.primary('SHA'),\n colors.primary('Original'),\n colors.primary('Refined Title'),\n colors.primary('Description'),\n colors.primary('Tags'),\n ],\n colWidths: [12, 28, 30, 40, 20],\n wordWrap: true,\n style: tableStyles.default.style,\n });\n\n brags.forEach((brag, index) => {\n // Handle both RefinedBrag and RefinedCommit types\n const isNewBragType = !('sha' in brag);\n\n // Get SHA - either from brag directly or from selectedCommits\n let displaySha: string = `#${index + 1}`;\n if (isNewBragType && selectedCommits) {\n const commit = selectedCommits[index];\n if (commit && commit.sha.startsWith('pr-')) {\n displaySha = commit.sha.replace('pr-', '#');\n } else if (commit) {\n displaySha = commit.sha.substring(0, 7);\n }\n } else if (!isNewBragType) {\n const commit = brag as RefinedCommit;\n if (commit.sha.startsWith('pr-')) {\n displaySha = commit.sha.replace('pr-', '#');\n } else {\n displaySha = commit.sha.substring(0, 7);\n }\n } else {\n displaySha = `#${index + 1}`;\n }\n\n // Get original message\n const original = isNewBragType\n ? typeof (brag as RefinedBrag).original_input === 'string'\n ? (brag as RefinedBrag).original_input.split('\\n')[0] || ''\n : 'Raw input'\n : (brag as RefinedCommit).original_message.split('\\n')[0] || '';\n\n const title = brag.refined_title;\n const description =\n brag.refined_description.length > 100\n ? brag.refined_description.substring(0, 97) + '...'\n : brag.refined_description;\n const tags = (brag.suggested_tags || []).join(', ') || 'none';\n\n // Add row number for easy reference\n const rowNum = colors.infoDim(`${index + 1}.`);\n\n table.push([\n `${rowNum} ${colors.highlight(displaySha)}`,\n colors.info(original),\n colors.white(title),\n colors.dim(description),\n colors.primary(tags),\n ]);\n });\n\n return table.toString();\n}\n\n/**\n * Format commit statistics\n */\nexport function formatCommitStats(commits: GitCommit[]): string {\n const totalFiles = commits.reduce((sum, c) => sum + (c.diffStats?.filesChanged || 0), 0);\n const totalInsertions = commits.reduce((sum, c) => sum + (c.diffStats?.insertions || 0), 0);\n const totalDeletions = commits.reduce((sum, c) => sum + (c.diffStats?.deletions || 0), 0);\n\n return (\n colors.info('Total changes: ') +\n colors.white(`${totalFiles} files`) +\n colors.info(', ') +\n formatDiffStats(totalInsertions, totalDeletions)\n );\n}\n\n/**\n * Format selection summary for user feedback\n */\nexport function formatSelectionSummary(count: number, commits: GitCommit[]): string {\n const totalFiles = commits.reduce((sum, c) => sum + (c.diffStats?.filesChanged || 0), 0);\n const totalInsertions = commits.reduce((sum, c) => sum + (c.diffStats?.insertions || 0), 0);\n const totalDeletions = commits.reduce((sum, c) => sum + (c.diffStats?.deletions || 0), 0);\n\n const selectedText = theme.success(`Selected ${theme.count(count)} PR${count > 1 ? 's' : ''}`);\n const stats = `${theme.count(totalFiles)} files changed, ${formatDiffStats(totalInsertions, totalDeletions)}`;\n\n return `\\n${selectedText}: ${stats}`;\n}\n\n/**\n * Format success message for created brags\n */\nexport function formatSuccessMessage(count: number): string {\n const emoji = '🎉';\n const title = colors.successBold(\n `${emoji} Successfully created ${count} brag${count > 1 ? 's' : ''}!`\n );\n const message = colors.white('\\nYour achievements are now saved and ready to showcase.');\n const hint =\n theme.secondary('\\nRun ') +\n theme.command('bragduck list') +\n theme.secondary(' to see all your brags');\n\n // Create clickable hyperlink using terminal-link (OSC 8 standard)\n // Supported by: iTerm2, Terminal.app, Hyper, Windows Terminal, VS Code terminal\n // Usage: CMD+click (macOS) or Ctrl+click (Windows/Linux)\n // Falls back to plain URL text in terminals without hyperlink support\n // Hover effects and exact behavior vary by terminal implementation\n const url = 'https://bragduck.com/app/brags';\n const clickableUrl = terminalLink(url, url, {\n fallback: () => colors.primary(url),\n });\n const webUrl =\n theme.secondary('\\n\\nOr, check ') + clickableUrl + theme.secondary(' to see all your brags');\n\n return `${title}${message}${hint}${webUrl}`;\n}\n\n/**\n * Format error message for display\n */\nexport function formatErrorMessage(message: string, hint?: string): string {\n const title = colors.errorBold('✗ Error');\n const error = colors.white(message);\n const hintText = hint ? theme.secondary('\\n\\nHint: ') + theme.command(hint) : '';\n\n return `${title}\\n\\n${error}${hintText}`;\n}\n\n/**\n * Format progress message\n */\nexport function formatProgress(current: number, total: number, label: string): string {\n const percentage = Math.round((current / total) * 100);\n const bar = '█'.repeat(Math.floor(percentage / 5)) + '░'.repeat(20 - Math.floor(percentage / 5));\n\n return `${colors.primary(bar)} ${colors.white(`${percentage}%`)} ${theme.progress(label)}`;\n}\n\n/**\n * Format hierarchical data with tree structure\n */\nexport function formatHierarchical(items: string[], isLast: boolean[] = []): string {\n return items\n .map((item, index) => {\n const isLastItem = index === items.length - 1;\n const prefix = isLast\n .slice(0, -1)\n .map((last) => (last ? ' ' : '│ '))\n .join('');\n const connector = isLastItem ? '└─' : '├─';\n\n return `${prefix}${connector} ${item}`;\n })\n .join('\\n');\n}\n","import ora, { Ora } from 'ora';\nimport { theme, colors } from './theme.js';\n\n/**\n * Create a spinner with consistent styling\n */\nexport function createSpinner(text: string): Ora {\n return ora({\n text,\n color: 'cyan',\n spinner: 'dots',\n });\n}\n\n/**\n * Create a step-aware spinner with progress indicator\n */\nexport function createStepSpinner(currentStep: number, totalSteps: number, text: string): Ora {\n const stepIndicator = theme.step(currentStep, totalSteps);\n return ora({\n text: `${stepIndicator} ${text}`,\n color: 'cyan',\n spinner: 'dots',\n });\n}\n\n/**\n * Update step spinner with new step and text\n */\nexport function updateStepSpinner(\n spinner: Ora,\n currentStep: number,\n totalSteps: number,\n text: string\n): void {\n const stepIndicator = theme.step(currentStep, totalSteps);\n spinner.text = `${stepIndicator} ${text}`;\n}\n\n/**\n * Spinner for fetching commits\n */\nexport function fetchingCommitsSpinner(days: number): Ora {\n return createSpinner(`Fetching commits from the last ${days} days...`);\n}\n\n/**\n * Spinner for fetching PRs\n */\nexport function fetchingPRsSpinner(days: number): Ora {\n return createSpinner(`Fetching merged PRs from the last ${days} days...`);\n}\n\n/**\n * Spinner for refining commits\n */\nexport function refiningCommitsSpinner(count: number): Ora {\n return createSpinner(`Refining ${count} commit${count > 1 ? 's' : ''} with AI...`);\n}\n\n/**\n * Spinner for creating brags\n */\nexport function creatingBragsSpinner(count: number): Ora {\n return createSpinner(`Creating ${count} brag${count > 1 ? 's' : ''}...`);\n}\n\n/**\n * Spinner for fetching brags\n */\nexport function fetchingBragsSpinner(): Ora {\n return createSpinner('Fetching your brags...');\n}\n\n/**\n * Update spinner with new text\n */\nexport function updateSpinner(spinner: Ora, text: string): void {\n spinner.text = text;\n}\n\n/**\n * Succeed spinner with custom text\n */\nexport function succeedSpinner(spinner: Ora, text?: string): void {\n if (text) {\n spinner.succeed(colors.success(text));\n } else {\n spinner.succeed();\n }\n}\n\n/**\n * Fail spinner with custom text\n */\nexport function failSpinner(spinner: Ora, text?: string): void {\n if (text) {\n spinner.fail(colors.error(text));\n } else {\n spinner.fail();\n }\n}\n\n/**\n * Warn spinner with custom text\n */\nexport function warnSpinner(spinner: Ora, text?: string): void {\n if (text) {\n spinner.warn(colors.warning(text));\n } else {\n spinner.warn();\n }\n}\n\n/**\n * Complete a step spinner with success\n */\nexport function succeedStepSpinner(\n spinner: Ora,\n currentStep: number,\n totalSteps: number,\n text: string\n): void {\n const stepIndicator = theme.step(currentStep, totalSteps);\n spinner.succeed(`${stepIndicator} ${colors.success(text)}`);\n}\n\n/**\n * Fail a step spinner with error\n */\nexport function failStepSpinner(\n spinner: Ora,\n currentStep: number,\n totalSteps: number,\n text: string\n): void {\n const stepIndicator = theme.step(currentStep, totalSteps);\n spinner.fail(`${stepIndicator} ${colors.error(text)}`);\n}\n","import { confirm } from '@inquirer/prompts';\nimport boxen from 'boxen';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { authService } from '../services/auth.service.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Logout command: Clear stored credentials\n */\nexport async function logoutCommand(): Promise<void> {\n // Check if user is authenticated\n const isAuthenticated = await authService.isAuthenticated();\n\n if (!isAuthenticated) {\n logger.log(\n boxen(\n `${chalk.yellow('Not currently authenticated')}\\n\\n${chalk.dim('Nothing to logout from')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n }\n )\n );\n return;\n }\n\n // Get user info to show in confirmation\n const userInfo = authService.getUserInfo();\n const userName = userInfo?.name || 'Unknown User';\n\n logger.log('');\n\n // Confirm logout\n const shouldLogout = await confirm({\n message: `Are you sure you want to logout? (${chalk.cyan(userName)})`,\n default: false,\n });\n\n if (!shouldLogout) {\n logger.info('Logout cancelled');\n return;\n }\n\n const spinner = ora('Logging out...').start();\n\n try {\n await authService.logout();\n spinner.succeed('Logged out successfully');\n logger.log('');\n\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Logged out successfully')}\\n\\n` +\n `${chalk.dim('Your credentials have been cleared')}\\n\\n` +\n `${chalk.dim('Run')} ${chalk.cyan('bragduck init')} ${chalk.dim('to login again')}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n } catch {\n spinner.fail('Logout failed');\n logger.error('Failed to logout. Please try again.');\n process.exit(1);\n }\n}\n","import boxen from 'boxen';\nimport chalk from 'chalk';\nimport { CancelPromptError } from '@inquirer/core';\nimport { githubService } from '../services/github.service.js';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from '../utils/logger.js';\nimport { openBrowser } from '../utils/browser.js';\nimport { ensureAuthenticated } from '../utils/auth-helper.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport {\n promptSelectCommits,\n promptDaysToScan,\n promptSortOption,\n promptReviewBrags,\n promptConfirm,\n promptSelectOrganisation,\n} from '../ui/prompts.js';\nimport { authService } from '../services/auth.service.js';\nimport { createStepSpinner, succeedStepSpinner, failStepSpinner } from '../ui/spinners.js';\nimport {\n formatRefinedCommitsTable,\n formatSuccessMessage,\n formatErrorMessage,\n formatCommitStats,\n formatSelectionSummary,\n} from '../ui/formatters.js';\nimport { theme, colors, boxStyles } from '../ui/theme.js';\nimport type { GitCommit } from '../types/git.types.js';\nimport type { CreateBragItem, RefinedBrag } from '../types/api.types.js';\nimport type { GitHubPR } from '../types/github.types.js';\n\n/**\n * Scan command options\n */\nexport interface ScanCommandOptions {\n days?: number;\n all?: boolean; // Include all commits, not just current user's\n}\n\n/**\n * Scan command: Scan git commits and create brags\n */\nexport async function scanCommand(options: ScanCommandOptions = {}): Promise<void> {\n // Deprecation warning\n logger.log('');\n logger.log(\n boxen(\n chalk.yellow.bold('⚠ Deprecation Notice') +\n '\\n\\n' +\n `The ${chalk.cyan('scan')} command is deprecated.\\n` +\n `Please use ${chalk.cyan('bragduck sync')} instead.\\n\\n` +\n chalk.dim('This command will be removed in v3.0.0'),\n {\n padding: 1,\n borderStyle: 'round',\n borderColor: 'yellow',\n dimBorder: true,\n }\n )\n );\n logger.log('');\n\n const TOTAL_STEPS = 5;\n\n try {\n // Step 1: Check authentication\n const isAuthenticated = await ensureAuthenticated();\n if (!isAuthenticated) {\n process.exit(1);\n }\n\n // Step 1.5: Check subscription plan\n logger.debug('Fetching subscription status...');\n const subscriptionStatus = await apiService.getSubscriptionStatus();\n\n logger.debug('Subscription status response:', JSON.stringify(subscriptionStatus, null, 2));\n logger.debug(\n `Checking tier: \"${subscriptionStatus.tier}\" (type: ${typeof subscriptionStatus.tier})`\n );\n logger.debug(`Tier === 'FREE': ${subscriptionStatus.tier === 'FREE'}`);\n\n if (subscriptionStatus.tier === 'FREE') {\n logger.debug('FREE tier detected - blocking scan command');\n logger.log('');\n logger.log(\n boxen(\n theme.warning('CLI Access Requires Subscription') +\n '\\n\\n' +\n 'The Bragduck CLI is available for Plus and Pro subscribers.\\n' +\n 'Upgrade now to unlock:\\n\\n' +\n ' • Automatic PR scanning\\n' +\n ' • AI-powered brag generation\\n' +\n ' • Unlimited brags\\n\\n' +\n colors.highlight('Start your free trial today!'),\n {\n ...boxStyles.warning,\n padding: 1,\n margin: 1,\n }\n )\n );\n logger.log('');\n\n const shouldOpenBrowser = await promptConfirm(\n 'Open subscription plans in your browser?',\n true\n );\n\n if (shouldOpenBrowser) {\n logger.log('');\n const plansUrl = 'https://bragduck.com/app/settings/plans';\n\n try {\n await openBrowser(plansUrl);\n logger.info(theme.secondary('Opening browser...'));\n } catch {\n logger.warning('Could not open browser automatically');\n logger.info(`Please visit: ${theme.value(plansUrl)}`);\n }\n }\n\n logger.log('');\n return;\n }\n\n logger.debug(`Subscription tier \"${subscriptionStatus.tier}\" - proceeding with scan`);\n\n // Step 2: Validate GitHub repository\n const repoSpinner = createStepSpinner(1, TOTAL_STEPS, 'Validating GitHub repository');\n repoSpinner.start();\n\n await githubService.validateGitHubRepository();\n const repoInfo = await githubService.getRepositoryInfo();\n\n succeedStepSpinner(\n repoSpinner,\n 1,\n TOTAL_STEPS,\n `Repository: ${theme.value(repoInfo.fullName)}`\n );\n logger.log('');\n\n // Step 3: Prompt for days to scan (if not provided)\n let days = options.days;\n if (!days) {\n const defaultDays = storageService.getConfig('defaultCommitDays');\n days = await promptDaysToScan(defaultDays);\n logger.log('');\n }\n\n // Step 4: Fetch PRs\n const prSpinner = createStepSpinner(\n 2,\n TOTAL_STEPS,\n `Fetching merged PRs from the last ${days} days`\n );\n prSpinner.start();\n\n let prs: GitHubPR[];\n if (options.all) {\n prs = await githubService.getMergedPRs({ days });\n } else {\n prs = await githubService.getPRsByCurrentUser({ days });\n }\n\n // Transform PRs to GitCommit format for UI compatibility\n const commits: GitCommit[] = prs.map((pr) => githubService.transformPRToCommit(pr));\n\n if (commits.length === 0) {\n failStepSpinner(prSpinner, 2, TOTAL_STEPS, `No merged PRs found in the last ${days} days`);\n logger.log('');\n logger.info('Try increasing the number of days or check your GitHub activity');\n return;\n }\n\n succeedStepSpinner(\n prSpinner,\n 2,\n TOTAL_STEPS,\n `Found ${theme.count(commits.length)} PR${commits.length > 1 ? 's' : ''}`\n );\n logger.log('');\n\n // Show commit statistics\n logger.log(formatCommitStats(commits));\n logger.log('');\n\n // Step 5: Sort and select PRs (skip sorting if only 1 PR)\n let sortedCommits = [...commits];\n if (commits.length > 1) {\n const sortOption = await promptSortOption();\n logger.log('');\n\n // Sort commits based on user preference\n if (sortOption === 'date') {\n sortedCommits.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());\n } else if (sortOption === 'size') {\n sortedCommits.sort((a, b) => {\n const sizeA = (a.diffStats?.insertions || 0) + (a.diffStats?.deletions || 0);\n const sizeB = (b.diffStats?.insertions || 0) + (b.diffStats?.deletions || 0);\n return sizeB - sizeA;\n });\n } else if (sortOption === 'files') {\n sortedCommits.sort((a, b) => {\n const filesA = a.diffStats?.filesChanged || 0;\n const filesB = b.diffStats?.filesChanged || 0;\n return filesB - filesA;\n });\n }\n }\n\n const selectedShas = await promptSelectCommits(sortedCommits);\n\n if (selectedShas.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No PRs selected. Scan cancelled.'));\n logger.log('');\n return;\n }\n\n const selectedCommits = sortedCommits.filter((c) => selectedShas.includes(c.sha));\n\n // Show selection summary\n logger.log(formatSelectionSummary(selectedCommits.length, selectedCommits));\n logger.log('');\n\n // Check for duplicate PRs already in Bragduck\n const existingBrags = await apiService.listBrags({ limit: 100 });\n logger.debug(`Fetched ${existingBrags.brags.length} existing brags`);\n\n // Match by PR URL stored in attachments\n const existingUrls = new Set(existingBrags.brags.flatMap((b) => b.attachments || []));\n logger.debug(`Existing PR URLs in attachments: ${existingUrls.size}`);\n\n const duplicates = selectedCommits.filter((c) => c.url && existingUrls.has(c.url));\n const newCommits = selectedCommits.filter((c) => !c.url || !existingUrls.has(c.url));\n\n logger.debug(`Duplicates: ${duplicates.length}, New: ${newCommits.length}`);\n\n if (duplicates.length > 0) {\n logger.log('');\n logger.info(\n colors.warning(\n `${duplicates.length} PR${duplicates.length > 1 ? 's' : ''} already added to Bragduck - skipping`\n )\n );\n logger.log('');\n }\n\n if (newCommits.length === 0) {\n logger.log('');\n logger.info(\n theme.secondary('All selected PRs already exist in Bragduck. Nothing to refine.')\n );\n logger.log('');\n return;\n }\n\n // Step 6: Refine commits with AI\n const refineSpinner = createStepSpinner(\n 3,\n TOTAL_STEPS,\n `Refining ${theme.count(newCommits.length)} PR${newCommits.length > 1 ? 's' : ''} with AI`\n );\n refineSpinner.start();\n\n const refineRequest = {\n brags: newCommits.map((c) => ({\n text: c.message,\n date: c.date,\n title: c.message.split('\\n')[0], // First line as initial title\n })),\n };\n\n const refineResponse = await apiService.refineBrags(refineRequest);\n let refinedBrags = refineResponse.refined_brags;\n\n succeedStepSpinner(refineSpinner, 3, TOTAL_STEPS, 'PRs refined successfully');\n logger.log('');\n\n // Step 7: Review and edit brags\n logger.info('Preview of refined brags:');\n logger.log('');\n logger.log(formatRefinedCommitsTable(refinedBrags, newCommits));\n logger.log('');\n\n // Interactive review with option to edit\n const acceptedBrags = await promptReviewBrags(refinedBrags, newCommits);\n\n if (acceptedBrags.length === 0) {\n logger.log('');\n logger.info(theme.secondary('No brags selected for creation. Scan cancelled.'));\n logger.log('');\n return;\n }\n\n logger.log('');\n\n // Step 8: Select organisation (if user has any)\n let selectedOrgId: string | null = null;\n const userInfo = authService.getUserInfo();\n if (userInfo?.id) {\n try {\n const orgsResponse = await apiService.listUserOrganisations(userInfo.id);\n if (orgsResponse.items.length > 0) {\n selectedOrgId = await promptSelectOrganisation(orgsResponse.items);\n logger.log('');\n }\n } catch {\n logger.debug('Failed to fetch organisations, skipping org selection');\n }\n }\n\n // Step 9: Create brags\n const createSpinner = createStepSpinner(\n 4,\n TOTAL_STEPS,\n `Creating ${theme.count(acceptedBrags.length)} brag${acceptedBrags.length > 1 ? 's' : ''}`\n );\n createSpinner.start();\n\n const createRequest = {\n brags: acceptedBrags.map((refined: RefinedBrag, index: number): CreateBragItem => {\n const originalCommit = newCommits[index];\n return {\n commit_sha: originalCommit?.sha || `brag-${index}`,\n title: refined.refined_title,\n description: refined.refined_description,\n tags: refined.suggested_tags,\n repository: repoInfo.url,\n date: originalCommit?.date || '',\n commit_url: originalCommit?.url || '',\n impact_score: refined.suggested_impactLevel,\n impact_description: refined.impact_description,\n attachments: originalCommit?.url ? [originalCommit.url] : [],\n orgId: selectedOrgId || undefined,\n };\n }),\n };\n\n const createResponse = await apiService.createBrags(createRequest);\n\n succeedStepSpinner(\n createSpinner,\n 4,\n TOTAL_STEPS,\n `Created ${theme.count(createResponse.created)} brag${createResponse.created > 1 ? 's' : ''}`\n );\n logger.log('');\n\n // Final: Show success message\n logger.log(boxen(formatSuccessMessage(createResponse.created), boxStyles.success));\n } catch (error) {\n // Handle user cancellation (Ctrl+C or ESC)\n if (error instanceof CancelPromptError) {\n logger.log('');\n logger.info(theme.secondary('Scan cancelled.'));\n logger.log('');\n return;\n }\n\n const err = error as BragduckError;\n\n logger.log('');\n logger.log(boxen(formatErrorMessage(err.message, getErrorHint(err)), boxStyles.error));\n\n process.exit(1);\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError): string {\n if (error.name === 'GitHubError') {\n return 'Make sure you are in a GitHub repository and have authenticated with \"gh auth login\"';\n }\n\n if (error.name === 'GitError') {\n return 'Make sure you are in a git repository. Note: Only GitHub repositories are supported for PR scanning.';\n }\n\n if (error.name === 'TokenExpiredError' || error.name === 'AuthenticationError') {\n return 'Run \"bragduck init\" to login again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'ApiError') {\n return 'The server might be experiencing issues. Try again later';\n }\n\n return 'Try running with DEBUG=* for more information';\n}\n","import boxen from 'boxen';\nimport Table from 'cli-table3';\nimport { apiService } from '../services/api.service.js';\nimport { ensureAuthenticated } from '../utils/auth-helper.js';\nimport { logger } from '../utils/logger.js';\nimport { formatErrorMessage } from '../ui/formatters.js';\nimport { fetchingBragsSpinner, succeedSpinner, failSpinner } from '../ui/spinners.js';\nimport { theme, colors, boxStyles, tableStyles } from '../ui/theme.js';\nimport type { BragduckError } from '../utils/errors.js';\nimport type { Brag } from '../types/api.types.js';\n\n/**\n * List command options\n */\nexport interface ListCommandOptions {\n limit?: number;\n offset?: number;\n tags?: string;\n search?: string;\n oneline?: boolean;\n}\n\n/**\n * List command: Fetch and display existing brags\n */\nexport async function listCommand(options: ListCommandOptions = {}): Promise<void> {\n logger.log('');\n\n try {\n // 1. Check authentication\n const isAuthenticated = await ensureAuthenticated();\n if (!isAuthenticated) {\n process.exit(1);\n }\n\n // 2. Parse options\n const limit = options.limit || 50;\n const offset = options.offset || 0;\n const tags = options.tags ? options.tags.split(',').map((t) => t.trim()) : undefined;\n const search = options.search;\n\n // 3. Fetch brags\n const spinner = fetchingBragsSpinner();\n spinner.start();\n\n const response = await apiService.listBrags({\n limit,\n offset,\n tags,\n search,\n });\n\n if (response.brags.length === 0) {\n failSpinner(spinner, 'No brags found');\n logger.log('');\n\n if (search || tags) {\n logger.info('Try adjusting your filters or run without filters to see all brags');\n } else {\n logger.info(\n theme.secondary('Run ') +\n theme.command('bragduck scan') +\n theme.secondary(' to create your first brag!')\n );\n }\n return;\n }\n\n succeedSpinner(spinner, `Found ${response.total} brag${response.total > 1 ? 's' : ''}`);\n logger.log('');\n\n // 4. Display brags\n if (options.oneline) {\n logger.log(formatBragsOneline(response.brags));\n } else {\n logger.log(formatBragsTable(response.brags));\n }\n logger.log('');\n\n // 5. Show pagination info\n if (response.has_more) {\n const nextOffset = offset + limit;\n logger.info(\n `Showing ${offset + 1}-${offset + response.brags.length} of ${response.total} total brags`\n );\n logger.info(\n theme.secondary('Run ') +\n theme.command(`bragduck list --offset ${nextOffset}`) +\n theme.secondary(' to see more')\n );\n logger.log('');\n } else if (offset > 0) {\n logger.info(\n `Showing ${offset + 1}-${offset + response.brags.length} of ${response.total} total brags`\n );\n logger.log('');\n }\n\n // 6. Show filter info if filters are applied\n if (search || tags) {\n const filterInfo: string[] = [];\n if (search) filterInfo.push(`search: \"${search}\"`);\n if (tags) filterInfo.push(`tags: ${tags.join(', ')}`);\n logger.info(theme.info(`Filters applied: ${filterInfo.join(', ')}`));\n logger.log('');\n }\n } catch (error) {\n const err = error as BragduckError;\n\n logger.log('');\n logger.log(boxen(formatErrorMessage(err.message, getErrorHint(err)), boxStyles.error));\n\n process.exit(1);\n }\n}\n\n/**\n * Format brags as a table\n */\nfunction formatBragsTable(brags: Brag[]): string {\n const table = new Table({\n head: [\n colors.primary('Date'),\n colors.primary('Title'),\n colors.primary('Description'),\n colors.primary('Tags'),\n colors.primary('Repository'),\n ],\n colWidths: [12, 30, 40, 20, 30],\n wordWrap: true,\n style: tableStyles.default.style,\n });\n\n brags.forEach((brag) => {\n const date = new Date(brag.date).toLocaleDateString();\n const title = brag.title;\n const description = truncateText(brag.description, 100);\n const tags = brag.tags.length > 0 ? brag.tags.join(', ') : colors.dim('none');\n const repository = brag.repository\n ? truncateText(extractRepoName(brag.repository), 25)\n : colors.dim('none');\n\n table.push([\n colors.highlight(date),\n colors.white(title),\n colors.dim(description),\n colors.primary(tags),\n colors.info(repository),\n ]);\n });\n\n return table.toString();\n}\n\n/**\n * Format brags as oneline output (date + title only)\n */\nfunction formatBragsOneline(brags: Brag[]): string {\n return brags\n .map((brag) => {\n const date = new Date(brag.date).toLocaleDateString();\n return `${colors.highlight(date)} ${colors.white(brag.title)}`;\n })\n .join('\\n');\n}\n\n/**\n * Truncate text with ellipsis\n */\nfunction truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n return text.substring(0, maxLength - 3) + '...';\n}\n\n/**\n * Extract repository name from URL\n */\nfunction extractRepoName(url: string): string {\n try {\n // Handle GitHub URLs like: https://github.com/user/repo.git\n const match = url.match(/([^/]+\\/[^/]+?)(\\.git)?$/);\n return match ? match[1]! : url;\n } catch {\n return url;\n }\n}\n\n/**\n * Get helpful hint based on error type\n */\nfunction getErrorHint(error: BragduckError): string {\n if (error.name === 'TokenExpiredError' || error.name === 'AuthenticationError') {\n return 'Run \"bragduck init\" to login again';\n }\n\n if (error.name === 'NetworkError') {\n return 'Check your internet connection and try again';\n }\n\n if (error.name === 'ApiError') {\n return 'The server might be experiencing issues. Try again later';\n }\n\n return 'Try running with DEBUG=* for more information';\n}\n","import boxen from 'boxen';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from '../utils/logger.js';\nimport { CONFIG_KEYS, DEFAULT_CONFIG } from '../constants.js';\nimport { formatErrorMessage } from '../ui/formatters.js';\nimport { ValidationError } from '../utils/errors.js';\nimport type { BragduckConfig } from '../types/config.types.js';\nimport type { SourceType } from '../types/source.types.js';\n\n/**\n * Valid configuration keys\n */\nconst VALID_CONFIG_KEYS = Object.values(CONFIG_KEYS);\n\n/**\n * Config subcommands\n */\ntype ConfigSubcommand = 'list' | 'get' | 'set';\n\n/**\n * Config command: Manage CLI configuration\n */\nexport async function configCommand(\n subcommand?: ConfigSubcommand,\n key?: string,\n value?: string\n): Promise<void> {\n logger.log('');\n\n try {\n // If no subcommand provided, default to 'list'\n if (!subcommand) {\n subcommand = 'list';\n }\n\n switch (subcommand) {\n case 'list':\n await handleListConfig();\n break;\n\n case 'get':\n if (!key) {\n throw new ValidationError('Config key is required for \"get\" command');\n }\n await handleGetConfig(key);\n break;\n\n case 'set':\n if (!key || value === undefined) {\n throw new ValidationError('Config key and value are required for \"set\" command');\n }\n await handleSetConfig(key, value);\n break;\n\n default:\n throw new ValidationError(\n `Invalid subcommand: \"${subcommand}\". Valid subcommands: list, get, set`\n );\n }\n } catch (error) {\n const err = error as Error;\n logger.log('');\n logger.log(\n boxen(formatErrorMessage(err.message, getConfigHint(err)), {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'red',\n })\n );\n\n process.exit(1);\n }\n}\n\n/**\n * Handle 'list' subcommand - Display all configuration values\n */\nasync function handleListConfig(): Promise<void> {\n const config = {\n defaultCommitDays: storageService.getConfig('defaultCommitDays'),\n autoVersionCheck: storageService.getConfig('autoVersionCheck'),\n defaultSource: storageService.getConfig('defaultSource'),\n sourcePriority: storageService.getConfig('sourcePriority'),\n jiraInstance: storageService.getConfig('jiraInstance'),\n confluenceInstance: storageService.getConfig('confluenceInstance'),\n gitlabInstance: storageService.getConfig('gitlabInstance'),\n };\n\n const table = new Table({\n head: [chalk.cyan('Key'), chalk.cyan('Value'), chalk.cyan('Default')],\n colWidths: [25, 40, 40],\n wordWrap: true,\n style: {\n head: [],\n border: ['gray'],\n },\n });\n\n table.push([\n chalk.white('defaultCommitDays'),\n chalk.yellow(String(config.defaultCommitDays)),\n chalk.dim(String(DEFAULT_CONFIG.defaultCommitDays)),\n ]);\n\n table.push([\n chalk.white('autoVersionCheck'),\n chalk.yellow(String(config.autoVersionCheck)),\n chalk.dim(String(DEFAULT_CONFIG.autoVersionCheck)),\n ]);\n\n table.push([\n chalk.white('defaultSource'),\n chalk.yellow(config.defaultSource || 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('sourcePriority'),\n chalk.yellow(config.sourcePriority ? config.sourcePriority.join(', ') : 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('jiraInstance'),\n chalk.yellow(config.jiraInstance || 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('confluenceInstance'),\n chalk.yellow(config.confluenceInstance || 'not set'),\n chalk.dim('not set'),\n ]);\n\n table.push([\n chalk.white('gitlabInstance'),\n chalk.yellow(config.gitlabInstance || 'not set'),\n chalk.dim('not set'),\n ]);\n\n logger.info('Current configuration:');\n logger.log('');\n logger.log(table.toString());\n logger.log('');\n logger.info(chalk.dim('To change a value: ') + chalk.cyan('bragduck config set <key> <value>'));\n logger.log('');\n}\n\n/**\n * Handle 'get' subcommand - Get a specific configuration value\n */\nasync function handleGetConfig(key: string): Promise<void> {\n validateConfigKey(key);\n\n const value = storageService.getConfig(key as keyof BragduckConfig);\n const defaultValue = DEFAULT_CONFIG[key as keyof typeof DEFAULT_CONFIG];\n\n logger.info(`Configuration for ${chalk.cyan(key)}:`);\n logger.log('');\n logger.log(` ${chalk.white('Current:')} ${chalk.yellow(String(value))}`);\n logger.log(` ${chalk.white('Default:')} ${chalk.dim(String(defaultValue))}`);\n logger.log('');\n\n if (value === defaultValue) {\n logger.info(chalk.dim('Using default value'));\n } else {\n logger.info(\n chalk.dim('Custom value set. Reset with: ') +\n chalk.cyan(`bragduck config set ${key} ${defaultValue}`)\n );\n }\n logger.log('');\n}\n\n/**\n * Handle 'set' subcommand - Set a configuration value\n */\nasync function handleSetConfig(key: string, value: string): Promise<void> {\n validateConfigKey(key);\n\n // Validate and convert value based on key type\n const typedValue = validateAndConvertValue(key, value);\n\n // Store the configuration\n storageService.setConfig(key as keyof BragduckConfig, typedValue);\n\n logger.log(\n boxen(\n `${chalk.green.bold('✓ Configuration updated')}\\n\\n` +\n `${chalk.white(key)}: ${chalk.yellow(String(typedValue))}`,\n {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'green',\n }\n )\n );\n}\n\n/**\n * Validate configuration key\n */\nfunction validateConfigKey(key: string): void {\n if (!VALID_CONFIG_KEYS.includes(key as any)) {\n throw new ValidationError(\n `Invalid config key: \"${key}\"\\n\\nValid keys:\\n${VALID_CONFIG_KEYS.map((k) => ` - ${k}`).join('\\n')}`\n );\n }\n}\n\n/**\n * Validate and convert value based on key type\n */\nfunction validateAndConvertValue(\n key: string,\n value: string\n): number | boolean | string | SourceType[] {\n switch (key) {\n case CONFIG_KEYS.DEFAULT_COMMIT_DAYS: {\n // Convert to number and validate\n const days = parseInt(value, 10);\n if (isNaN(days) || days < 1 || days > 365) {\n throw new ValidationError(\n `Invalid value for defaultCommitDays: \"${value}\"\\n\\nMust be a number between 1 and 365`\n );\n }\n return days;\n }\n\n case CONFIG_KEYS.AUTO_VERSION_CHECK: {\n // Convert to boolean\n const lowerValue = value.toLowerCase();\n if (lowerValue === 'true' || lowerValue === '1' || lowerValue === 'yes') {\n return true;\n } else if (lowerValue === 'false' || lowerValue === '0' || lowerValue === 'no') {\n return false;\n }\n throw new ValidationError(\n `Invalid value for autoVersionCheck: \"${value}\"\\n\\nMust be one of: true, false, yes, no, 1, 0`\n );\n }\n\n case CONFIG_KEYS.DEFAULT_SOURCE: {\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n if (!validSources.includes(value as SourceType)) {\n throw new ValidationError(\n `Invalid source: \"${value}\"\\n\\nValid sources: ${validSources.join(', ')}`\n );\n }\n return value as SourceType;\n }\n\n case CONFIG_KEYS.SOURCE_PRIORITY: {\n const sources = value.split(',').map((s) => s.trim());\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n for (const source of sources) {\n if (!validSources.includes(source as SourceType)) {\n throw new ValidationError(\n `Invalid source in priority list: \"${source}\"\\n\\nValid sources: ${validSources.join(', ')}`\n );\n }\n }\n return sources as SourceType[];\n }\n\n case CONFIG_KEYS.JIRA_INSTANCE:\n case CONFIG_KEYS.CONFLUENCE_INSTANCE:\n case CONFIG_KEYS.GITLAB_INSTANCE: {\n // Basic hostname/URL validation\n if (!value.match(/^[a-zA-Z0-9.-]+(:[0-9]+)?(\\/.*)?$/)) {\n throw new ValidationError(\n `Invalid instance URL: \"${value}\"\\n\\nMust be a valid hostname (e.g., company.atlassian.net, gitlab.company.com)`\n );\n }\n return value;\n }\n\n default:\n // This should never happen due to validateConfigKey check\n throw new ValidationError(`Unknown config key: \"${key}\"`);\n }\n}\n\n/**\n * Get helpful hint for config errors\n */\nfunction getConfigHint(error: any): string {\n if (error.name === 'ValidationError') {\n return 'Run \"bragduck config list\" to see all available configuration keys';\n }\n\n return 'Run \"bragduck config --help\" for usage information';\n}\n"],"mappings":"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","names":["fileURLToPath","path","config","join","randomBytes","readFileSync","fileURLToPath","dirname","join","packageJsonPath","__dirname","packageJson","version","__filename","readFileSync","fileURLToPath","dirname","join","chalk","boxen","packageJsonPath","__dirname","packageJson","__filename","ofetch","readFileSync","fileURLToPath","URLSearchParams","dirname","join","packageJsonPath","__dirname","packageJson","__filename","version","readFileSync","fileURLToPath","dirname","join","chalk","exec","promisify","existsSync","join","path","execAsync","promisify","exec","chalk","chalk","select","boxen","exec","promisify","execAsync","promisify","exec","exec","promisify","URLSearchParams","execAsync","promisify","exec","URLSearchParams","boxen","boxen","chalk","input","boxen","input","boxen","boxen","ora","ora","select","createSpinner","boxen","getErrorHint","confirm","boxen","chalk","ora","boxen","chalk","boxen","chalk","createSpinner","getErrorHint","boxen","Table","boxen","getErrorHint","Table","boxen","chalk","Table","boxen","config","Table","chalk","__filename","fileURLToPath","__dirname","dirname","join","readFileSync"]}
|