green-screen-react 1.1.3 → 1.2.0

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/GreenScreenTerminal.tsx","../src/adapters/RestAdapter.ts","../src/adapters/WebSocketAdapter.ts","../src/hooks/useTerminal.ts","../src/hooks/useTypingAnimation.ts","../src/utils/grid.ts","../src/protocols/tn5250.ts","../src/protocols/tn3270.ts","../src/protocols/vt.ts","../src/protocols/hp6530.ts","../src/protocols/registry.ts","../src/components/TerminalBootLoader.tsx","../src/components/Icons.tsx","../src/components/InlineSignIn.tsx","../src/utils/rendering.ts"],"sourcesContent":["// Components\nexport { GreenScreenTerminal } from './components/GreenScreenTerminal';\nexport type { GreenScreenTerminalProps } from './components/GreenScreenTerminal';\nexport { TerminalBootLoader } from './components/TerminalBootLoader';\nexport type { TerminalBootLoaderProps } from './components/TerminalBootLoader';\nexport { InlineSignIn } from './components/InlineSignIn';\nexport type { InlineSignInProps } from './components/InlineSignIn';\n\n// Icons\nexport { TerminalIcon, WifiIcon, WifiOffIcon, AlertTriangleIcon, RefreshIcon, KeyIcon, MinimizeIcon } from './components/Icons';\n\n// Adapters\nexport { RestAdapter } from './adapters/RestAdapter';\nexport type { RestAdapterOptions } from './adapters/RestAdapter';\nexport { WebSocketAdapter } from './adapters/WebSocketAdapter';\nexport type { WebSocketAdapterOptions } from './adapters/WebSocketAdapter';\nexport type {\n TerminalAdapter,\n TerminalProtocol,\n ProtocolProfile,\n ProtocolColorProfile,\n ScreenData,\n ConnectionStatus,\n SendResult,\n ConnectConfig,\n Field,\n} from './adapters/types';\n\n// Hooks\nexport { useTypingAnimation } from './hooks/useTypingAnimation';\nexport {\n useTerminalConnection,\n useTerminalScreen,\n useTerminalInput,\n} from './hooks/useTerminal';\n\n// Protocols\nexport { getProtocolProfile } from './protocols/registry';\nexport { tn5250Profile } from './protocols/tn5250';\nexport { tn3270Profile } from './protocols/tn3270';\nexport { vtProfile } from './protocols/vt';\nexport { hp6530Profile } from './protocols/hp6530';\n\n// Utilities\nexport { positionToRowCol, isFieldEntry } from './utils/grid';\nexport { getRowColorClass, parseHeaderRow } from './utils/rendering';\n","import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport type { TerminalAdapter, ScreenData, ConnectionStatus, Field, TerminalProtocol, ProtocolProfile, ConnectConfig } from '../adapters/types';\nimport { RestAdapter } from '../adapters/RestAdapter';\nimport { WebSocketAdapter } from '../adapters/WebSocketAdapter';\nimport { useTerminalScreen, useTerminalInput, useTerminalConnection } from '../hooks/useTerminal';\nimport { useTypingAnimation } from '../hooks/useTypingAnimation';\nimport { getProtocolProfile } from '../protocols/registry';\nimport { TerminalBootLoader as DefaultBootLoader } from './TerminalBootLoader';\nimport { TerminalIcon, WifiIcon, WifiOffIcon, AlertTriangleIcon, RefreshIcon, KeyIcon, MinimizeIcon, HelpIcon } from './Icons';\nimport { InlineSignIn } from './InlineSignIn';\n\n/* ── No-op adapter (placeholder before connection) ───────────────── */\n\nconst noopResult = { success: false, error: 'No adapter configured' };\nconst noopAdapter: TerminalAdapter = {\n getScreen: async () => null,\n getStatus: async () => ({ connected: false, status: 'disconnected' }),\n sendText: async () => noopResult,\n sendKey: async () => noopResult,\n setCursor: async () => noopResult,\n connect: async () => noopResult,\n disconnect: async () => noopResult,\n reconnect: async () => noopResult,\n};\n\n/* ── Component Props ──────────────────────────────────────────────── */\n\nexport interface GreenScreenTerminalProps {\n /** Adapter for communicating with the terminal backend (optional — auto-created from sign-in form or baseUrl) */\n adapter?: TerminalAdapter;\n /** Base URL for the terminal API — convenience shorthand that auto-creates a RestAdapter */\n baseUrl?: string;\n /** Worker/proxy WebSocket URL — convenience shorthand that auto-creates a WebSocketAdapter */\n workerUrl?: string;\n /** Terminal protocol (determines color conventions, header label, etc.) */\n protocol?: TerminalProtocol;\n /** Custom protocol profile (overrides protocol param) */\n protocolProfile?: ProtocolProfile;\n /** Direct screen data injection (bypasses polling) */\n screenData?: ScreenData | null;\n /** Direct connection status injection */\n connectionStatus?: ConnectionStatus | null;\n\n /** Whether the terminal is read-only (no keyboard input) */\n readOnly?: boolean;\n /** Polling interval in ms (0 to disable polling; default 2000) */\n pollInterval?: number;\n /** Whether to auto-reconnect on disconnect (default true) */\n autoReconnect?: boolean;\n /** Max auto-reconnect attempts (default 5) */\n maxReconnectAttempts?: number;\n\n /** Compact embedded mode */\n embedded?: boolean;\n /** Show the header bar (default true) */\n showHeader?: boolean;\n /** Enable typing animation (default false) */\n typingAnimation?: boolean;\n /** Typing animation budget in ms (default 60) */\n typingBudgetMs?: number;\n\n /** Show inline sign-in form when disconnected (default true) */\n inlineSignIn?: boolean;\n /** Default protocol for the sign-in form dropdown (default 'tn5250') */\n defaultProtocol?: TerminalProtocol;\n /** Callback when sign-in form is submitted */\n onSignIn?: (config: ConnectConfig) => void;\n /** Show \"press Enter to continue\" hint after auto sign-in (for external adapter flows) */\n autoSignedIn?: boolean;\n /** Disable auto-focus on the terminal after connecting (default false) */\n autoFocusDisabled?: boolean;\n\n /** Custom boot loader element, or false to disable */\n bootLoader?: React.ReactNode | false;\n /** When true, dismiss the boot loader. If provided, overrides the default\n * \"dismiss when screen data arrives\" behavior. Use to keep the boot loader\n * visible during sign-in, startup command execution, etc. */\n bootLoaderReady?: boolean;\n /** Content for the right side of the header */\n headerRight?: React.ReactNode;\n /** Content rendered after the connection status groups (WiFi+host, Key+username) */\n statusActions?: React.ReactNode;\n /** Overlay content (e.g. \"Extracting...\" state) */\n overlay?: React.ReactNode;\n /** Callback for notifications (replaces toast) */\n onNotification?: (message: string, type: 'info' | 'error') => void;\n /** Callback when screen content changes */\n onScreenChange?: (screen: ScreenData) => void;\n /** Callback for minimize action (embedded mode) */\n onMinimize?: () => void;\n\n /** Additional CSS class name */\n className?: string;\n /** Inline styles */\n style?: React.CSSProperties;\n}\n\n/**\n * GreenScreenTerminal — Multi-protocol legacy terminal emulator component.\n *\n * Renders a terminal screen with:\n * - Green-on-black terminal aesthetic with protocol-specific color conventions\n * - Connection status indicator\n * - Keyboard input support (text, function keys, tab)\n * - Auto-reconnect with exponential backoff\n * - Typing animation for field entries\n * - Focus lock mode for keyboard capture\n *\n * Supports: TN5250 (IBM i), TN3270 (z/OS), VT (OpenVMS/Pick), HP 6530 (NonStop)\n */\nexport function GreenScreenTerminal({\n adapter: externalAdapter,\n baseUrl,\n workerUrl,\n protocol,\n protocolProfile: customProfile,\n screenData: externalScreenData,\n connectionStatus: externalStatus,\n readOnly = false,\n pollInterval = 2000,\n autoReconnect: autoReconnectEnabled = true,\n maxReconnectAttempts: maxAttempts = 5,\n embedded = false,\n showHeader = true,\n typingAnimation = false,\n typingBudgetMs = 60,\n inlineSignIn = true,\n defaultProtocol: signInDefaultProtocol,\n onSignIn,\n autoSignedIn,\n autoFocusDisabled = false,\n bootLoader,\n bootLoaderReady,\n headerRight,\n statusActions,\n overlay,\n onNotification,\n onScreenChange,\n onMinimize,\n className,\n style,\n}: GreenScreenTerminalProps) {\n const profile = customProfile ?? getProtocolProfile(protocol);\n\n // --- Resolve adapter: explicit > baseUrl > workerUrl > internal (from sign-in) > default WebSocket > noop ---\n const [internalAdapter, setInternalAdapter] = useState<TerminalAdapter | null>(null);\n const baseUrlAdapter = useMemo(\n () => baseUrl ? new RestAdapter({ baseUrl }) : null,\n [baseUrl],\n );\n const workerUrlAdapter = useMemo(\n () => workerUrl ? new WebSocketAdapter({ workerUrl }) : null,\n [workerUrl],\n );\n // Default WebSocketAdapter (auto-detects env vars, falls back to localhost:3001) when no adapter is configured\n const defaultWsAdapter = useMemo(\n () => (!externalAdapter && !baseUrl && !workerUrl) ? new WebSocketAdapter() : null,\n [externalAdapter, baseUrl, workerUrl],\n );\n const adapter = externalAdapter ?? baseUrlAdapter ?? workerUrlAdapter ?? internalAdapter ?? defaultWsAdapter ?? noopAdapter;\n const isUsingDefaultAdapter = adapter === defaultWsAdapter;\n\n // --- Data sources ---\n const shouldPoll = pollInterval > 0 && !externalScreenData;\n const { data: polledScreenData, error: screenError } = useTerminalScreen(adapter, pollInterval, shouldPoll);\n const { sendText: _sendText, sendKey: _sendKey } = useTerminalInput(adapter);\n const { connect, reconnect, loading: reconnecting, error: connectError } = useTerminalConnection(adapter);\n\n const rawScreenData = externalScreenData ?? polledScreenData;\n\n const connStatus = externalStatus ?? (rawScreenData ? { connected: true, status: 'authenticated' as const } : { connected: false, status: 'disconnected' as const });\n\n // Typing animation\n const { displayedContent, animatedCursorPos } = useTypingAnimation(\n rawScreenData?.content,\n typingAnimation,\n typingBudgetMs,\n );\n\n const screenData = useMemo(() => {\n if (!rawScreenData) return null;\n return { ...rawScreenData, content: displayedContent };\n }, [rawScreenData, displayedContent]);\n\n // Notify parent on screen changes\n const prevScreenSigRef = useRef<string | undefined>(undefined);\n useEffect(() => {\n if (screenData && onScreenChange && screenData.screen_signature !== prevScreenSigRef.current) {\n prevScreenSigRef.current = screenData.screen_signature;\n onScreenChange(screenData);\n }\n }, [screenData, onScreenChange]);\n\n const sendText = useCallback(async (text: string) => _sendText(text), [_sendText]);\n const sendKey = useCallback(async (key: string) => _sendKey(key), [_sendKey]);\n\n // --- Optimistic edits ---\n // Characters typed by the user are applied optimistically to the displayed\n // content before the proxy responds. Cleared on full screen updates.\n const [optimisticEdits, setOptimisticEdits] = useState<Array<{ row: number; col: number; ch: string }>>([]);\n const prevScreenContentForEdits = useRef<string | undefined>(undefined);\n useEffect(() => {\n // Clear optimistic edits whenever the screen content changes (not just signature).\n // This prevents stale keystrokes from persisting across screen transitions when\n // the adapter talks to the proxy directly and the WS broadcast hasn't caught up.\n const content = rawScreenData?.content;\n if (content && content !== prevScreenContentForEdits.current) {\n prevScreenContentForEdits.current = content;\n setOptimisticEdits([]);\n }\n }, [rawScreenData?.content]);\n\n // --- UI State ---\n const [inputText, setInputText] = useState('');\n const [isFocused, setIsFocused] = useState(false);\n const [showSignInHint, setShowSignInHint] = useState(false);\n const [showShortcuts, setShowShortcuts] = useState(false);\n const prevAutoSignedIn = useRef(false);\n useEffect(() => {\n if (autoSignedIn && !prevAutoSignedIn.current) setShowSignInHint(true);\n prevAutoSignedIn.current = !!autoSignedIn;\n }, [autoSignedIn]);\n const terminalRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const [syncedCursor, setSyncedCursor] = useState<{ row: number; col: number } | null>(null);\n const prevRawContentRef = useRef('');\n\n useEffect(() => {\n const newContent = rawScreenData?.content || '';\n if (prevRawContentRef.current && newContent && newContent !== prevRawContentRef.current) {\n setSyncedCursor(null);\n setInputText('');\n if (showSignInHint) setShowSignInHint(false);\n }\n prevRawContentRef.current = newContent;\n }, [rawScreenData?.content]);\n\n // --- Auto-reconnect ---\n const [autoReconnectAttempt, setAutoReconnectAttempt] = useState(0);\n const [isAutoReconnecting, setIsAutoReconnecting] = useState(false);\n const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const wasConnectedRef = useRef(false);\n const isConnectedRef = useRef(false);\n\n useEffect(() => { isConnectedRef.current = connStatus?.connected ?? false; }, [connStatus?.connected]);\n\n useEffect(() => {\n if (!autoReconnectEnabled) return;\n const isConnected = connStatus?.connected;\n\n if (isConnected) {\n wasConnectedRef.current = true;\n if (reconnectTimeoutRef.current) { clearTimeout(reconnectTimeoutRef.current); reconnectTimeoutRef.current = null; }\n setAutoReconnectAttempt(0);\n setIsAutoReconnecting(false);\n } else if (wasConnectedRef.current && !isConnected && !isAutoReconnecting && !reconnecting) {\n if (autoReconnectAttempt < maxAttempts) {\n setIsAutoReconnecting(true);\n const delay = Math.pow(2, autoReconnectAttempt) * 1000;\n reconnectTimeoutRef.current = setTimeout(async () => {\n if (isConnectedRef.current) { setIsAutoReconnecting(false); return; }\n onNotification?.(`Auto-reconnect attempt ${autoReconnectAttempt + 1}/${maxAttempts}`, 'info');\n try {\n const result = await reconnect();\n if (!result?.success) setAutoReconnectAttempt(prev => prev + 1);\n } catch {\n onNotification?.('Auto-reconnect failed', 'error');\n setAutoReconnectAttempt(prev => prev + 1);\n }\n setIsAutoReconnecting(false);\n }, delay);\n }\n }\n return () => { if (reconnectTimeoutRef.current) clearTimeout(reconnectTimeoutRef.current); };\n }, [connStatus?.connected, autoReconnectAttempt, isAutoReconnecting, reconnecting, reconnect, autoReconnectEnabled, maxAttempts, onNotification]);\n\n // --- Inline sign-in ---\n const [connecting, setConnecting] = useState(false);\n const [signInError, setSignInError] = useState<string | null>(null);\n const handleSignIn = useCallback(async (config: ConnectConfig) => {\n // If the caller provided onSignIn, let them handle connection setup\n if (onSignIn) {\n onSignIn(config);\n return;\n }\n setConnecting(true);\n setSignInError(null);\n try {\n // Auto-create adapter from sign-in config when no external adapter is provided\n if (!externalAdapter && !baseUrlAdapter) {\n const port = config.port ? `:${config.port}` : '';\n const newAdapter = new RestAdapter({ baseUrl: `http://${config.host}${port}` });\n setInternalAdapter(newAdapter);\n await newAdapter.connect(config);\n if (config.username && config.password) setShowSignInHint(true);\n return;\n }\n await connect(config);\n if (config.username && config.password) setShowSignInHint(true);\n } catch (err) {\n setSignInError(err instanceof Error ? err.message : String(err));\n setConnecting(false);\n }\n // Note: connecting is cleared by the screenData effect below, not here —\n // the connect() promise may resolve before the screen is actually ready.\n }, [connect, onSignIn, externalAdapter, baseUrlAdapter]);\n\n // Clear connecting state when screen data arrives or connection is confirmed\n useEffect(() => {\n if (connecting && screenData?.content) setConnecting(false);\n }, [connecting, screenData?.content]);\n\n // --- Boot loader ---\n const [showBootLoader, setShowBootLoader] = useState(bootLoader !== false);\n const [bootFadingOut, setBootFadingOut] = useState(false);\n\n useEffect(() => {\n if (!showBootLoader) return;\n // If bootLoaderReady is provided, only dismiss when it becomes true.\n // Otherwise fall back to dismissing when screen data arrives.\n const shouldDismiss = bootLoaderReady !== undefined\n ? bootLoaderReady\n : !!screenData?.content;\n if (shouldDismiss) {\n setBootFadingOut(true);\n setShowBootLoader(false);\n const timer = setTimeout(() => setBootFadingOut(false), 400);\n return () => clearTimeout(timer);\n }\n }, [screenData?.content, showBootLoader, bootLoaderReady]);\n\n // --- Focus management ---\n const FOCUS_STORAGE_KEY = 'gs-terminal-focused';\n\n // Restore focus from localStorage on mount (if auto-focus enabled)\n useEffect(() => {\n if (!autoFocusDisabled && !readOnly) {\n try {\n if (localStorage.getItem(FOCUS_STORAGE_KEY) === 'true') {\n setIsFocused(true);\n }\n } catch { /* localStorage unavailable */ }\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Persist focus state to localStorage\n useEffect(() => {\n if (autoFocusDisabled) return;\n try { localStorage.setItem(FOCUS_STORAGE_KEY, String(isFocused)); } catch { /* noop */ }\n }, [isFocused, autoFocusDisabled]);\n\n // Sync DOM focus with isFocused state\n useEffect(() => {\n if (isFocused) inputRef.current?.focus();\n }, [isFocused]);\n\n // Auto-focus terminal when screen data arrives (i.e. connected)\n const hadScreenData = useRef(false);\n useEffect(() => {\n if (screenData?.content && !hadScreenData.current && !autoFocusDisabled && !readOnly) {\n hadScreenData.current = true;\n setIsFocused(true);\n }\n if (!screenData?.content) hadScreenData.current = false;\n }, [screenData?.content, autoFocusDisabled, readOnly]);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (terminalRef.current && !terminalRef.current.contains(event.target as Node)) setIsFocused(false);\n };\n if (isFocused) document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [isFocused]);\n\n useEffect(() => {\n if (readOnly && isFocused) { setIsFocused(false); inputRef.current?.blur(); }\n }, [readOnly, isFocused]);\n\n const screenContentRef = useRef<HTMLDivElement>(null);\n const charWidthRef = useRef<number>(0);\n\n const handleTerminalClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n if (readOnly) return;\n setIsFocused(true);\n inputRef.current?.focus();\n\n // Click-to-cursor: calculate which row/col was clicked\n const contentEl = screenContentRef.current;\n if (!contentEl || !screenData?.fields) return;\n\n // Measure 1ch width in current font\n if (!charWidthRef.current) {\n const span = document.createElement('span');\n span.style.cssText = 'position:absolute;visibility:hidden;font:inherit;white-space:pre';\n span.textContent = 'X';\n contentEl.appendChild(span);\n charWidthRef.current = span.getBoundingClientRect().width;\n contentEl.removeChild(span);\n }\n\n const rect = contentEl.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n const ROW_HEIGHT = 21;\n const charWidth = charWidthRef.current;\n if (!charWidth) return;\n\n const clickedRow = Math.floor(y / ROW_HEIGHT);\n const clickedCol = Math.floor(x / charWidth);\n\n if (clickedRow < 0 || clickedRow >= (screenData.rows || 24) ||\n clickedCol < 0 || clickedCol >= (screenData.cols || 80)) return;\n\n // Send cursor position to proxy (async, fire-and-forget for responsiveness)\n setSyncedCursor({ row: clickedRow, col: clickedCol });\n adapter.setCursor?.(clickedRow, clickedCol).then(r => {\n if (r?.cursor_row !== undefined) {\n setSyncedCursor({ row: r.cursor_row, col: r.cursor_col! });\n }\n });\n }, [readOnly, screenData, adapter]);\n\n // --- Field helpers ---\n const getCurrentField = useCallback(() => {\n const fields = screenData?.fields || [];\n const cursorRow = syncedCursor?.row ?? screenData?.cursor_row ?? 0;\n const cursorCol = syncedCursor?.col ?? screenData?.cursor_col ?? 0;\n for (const field of fields) {\n if (field.is_input && field.row === cursorRow && cursorCol >= field.col && cursorCol < field.col + field.length) return field;\n }\n return null;\n }, [screenData, syncedCursor]);\n\n // --- Keyboard handling ---\n // Characters are sent immediately to the proxy (no client-side buffering).\n // This keeps the proxy screen buffer in sync so arrow keys, backspace,\n // delete, and insert mode all work correctly at any cursor position.\n const handleKeyDown = async (e: React.KeyboardEvent) => {\n if (readOnly) { e.preventDefault(); return; }\n\n if (e.key === 'Escape') { e.preventDefault(); setIsFocused(false); inputRef.current?.blur(); return; }\n\n // Ctrl+R: Reset (clear keyboard lock and error line)\n if (e.ctrlKey && e.key === 'r') {\n e.preventDefault();\n const kr = await sendKey('RESET');\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n return;\n }\n\n // Ctrl+Enter: Field Exit (right-adjust and advance)\n if (e.ctrlKey && e.key === 'Enter') {\n e.preventDefault();\n const kr = await sendKey('FIELD_EXIT');\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n return;\n }\n\n const keyMap: Record<string, string> = {\n Enter: 'ENTER', Tab: 'TAB', Backspace: 'BACKSPACE', Delete: 'DELETE',\n ArrowUp: 'UP', ArrowDown: 'DOWN', ArrowLeft: 'LEFT', ArrowRight: 'RIGHT',\n PageUp: 'PAGEUP', PageDown: 'PAGEDOWN', Home: 'HOME', End: 'END', Insert: 'INSERT',\n };\n\n // F-keys\n if (e.key.startsWith('F') && e.key.length <= 3) {\n e.preventDefault();\n const fKey = e.key.toUpperCase();\n if (/^F([1-9]|1[0-9]|2[0-4])$/.test(fKey)) {\n const kr = await sendKey(fKey);\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n return;\n }\n }\n\n // Action/navigation keys\n if (keyMap[e.key]) {\n e.preventDefault();\n const kr = await sendKey(keyMap[e.key]);\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n }\n };\n\n const handleInput = async (e: React.ChangeEvent<HTMLInputElement>) => {\n if (readOnly) { e.target.value = ''; return; }\n const newText = e.target.value;\n if (newText.length > inputText.length) {\n const newChars = newText.substring(inputText.length);\n // Optimistic: show character immediately at cursor position\n const curRow = syncedCursor?.row ?? screenData?.cursor_row ?? 0;\n const curCol = syncedCursor?.col ?? screenData?.cursor_col ?? 0;\n const edits: Array<{ row: number; col: number; ch: string }> = [];\n for (let i = 0; i < newChars.length; i++) {\n edits.push({ row: curRow, col: curCol + i, ch: newChars[i] });\n }\n setOptimisticEdits(prev => [...prev, ...edits]);\n setSyncedCursor({ row: curRow, col: curCol + newChars.length });\n // Send to proxy in background (cursor-only response)\n sendText(newChars).then(r => {\n if (r.cursor_row !== undefined) setSyncedCursor({ row: r.cursor_row, col: r.cursor_col! });\n });\n }\n setInputText('');\n e.target.value = '';\n };\n\n // --- Cursor ---\n const termCols = screenData?.cols || profile.defaultCols;\n const getCursorPos = () => {\n if (animatedCursorPos) return animatedCursorPos;\n let cursorRow = syncedCursor?.row ?? screenData?.cursor_row ?? 0;\n let cursorCol = syncedCursor?.col ?? screenData?.cursor_col ?? 0;\n while (cursorCol >= termCols) { cursorCol -= termCols; cursorRow += 1; }\n return { row: cursorRow, col: cursorCol };\n };\n\n // --- Rendering helpers ---\n const renderTextWithUnderlines = useCallback((text: string, keyPrefix: string): React.ReactNode => {\n const underscoreRegex = /_{2,}/g;\n const segments: React.ReactNode[] = [];\n let lastIndex = 0;\n let match;\n let segmentIndex = 0;\n while ((match = underscoreRegex.exec(text)) !== null) {\n if (match.index > lastIndex) segments.push(<span key={`${keyPrefix}-t-${segmentIndex}`}>{text.substring(lastIndex, match.index)}</span>);\n const count = match[0].length;\n segments.push(<span key={`${keyPrefix}-u-${segmentIndex}`} style={{ borderBottom: '1px solid var(--gs-green, #10b981)', display: 'inline-block', width: `${count}ch` }}>{' '.repeat(count)}</span>);\n lastIndex = match.index + match[0].length;\n segmentIndex++;\n }\n if (lastIndex < text.length) segments.push(<span key={`${keyPrefix}-e`}>{text.substring(lastIndex)}</span>);\n return segments.length > 0 ? <>{segments}</> : <>{text}</>;\n }, []);\n\n const renderRowWithFields = useCallback((line: string, rowIndex: number, fields: Field[]): React.ReactNode => {\n const inputFields = fields.filter(f => f.row === rowIndex && f.is_input);\n const highlightedFields = fields.filter(f => f.row === rowIndex && f.is_protected && f.is_highlighted);\n const reverseFields = fields.filter(f => f.row === rowIndex && f.is_protected && f.is_reverse);\n const colorFields = fields.filter(f => f.row === rowIndex && f.is_protected && (f as any).color && !f.is_highlighted && !f.is_reverse);\n const allRowFields = [...inputFields, ...highlightedFields, ...reverseFields, ...colorFields];\n\n if (allRowFields.length === 0) return <span>{line}</span>;\n\n const sorted = [...allRowFields].sort((a, b) => a.col - b.col);\n const segs: React.ReactNode[] = [];\n let lastEnd = 0;\n const cols = screenData?.cols || profile.defaultCols;\n\n sorted.forEach((field, idx) => {\n const fs = field.col;\n const fe = Math.min(field.col + field.length, cols);\n if (fs > lastEnd) segs.push(<span key={`t${idx}`}>{line.substring(lastEnd, fs)}</span>);\n const fc = line.substring(fs, fe);\n\n // Resolve color from field's 5250 color attribute\n const colorVar = (field as any).color\n ? `var(--gs-${(field as any).color}, var(--gs-green))`\n : undefined;\n\n if (field.is_input) {\n const fieldWidth = Math.min(field.length, cols - fs);\n const fieldClass = showSignInHint ? 'gs-confirmed-field' : (field.is_underscored ? 'gs-input-field' : undefined);\n segs.push(<span key={`f${idx}`} className={fieldClass || undefined} style={{ display: 'inline-block', width: `${fieldWidth}ch`, overflow: 'hidden', color: colorVar }}>{fc}</span>);\n } else if (field.is_reverse) {\n segs.push(<span key={`v${idx}`} style={{ color: colorVar || 'var(--gs-red, #FF5555)', fontWeight: 'bold' }}>{fc}</span>);\n } else if (colorVar) {\n segs.push(<span key={`h${idx}`} style={{ color: colorVar }}>{fc}</span>);\n } else if (field.is_highlighted) {\n segs.push(<span key={`h${idx}`} style={{ color: 'var(--gs-white, #FFFFFF)' }}>{fc}</span>);\n } else {\n segs.push(<span key={`h${idx}`}>{fc}</span>);\n }\n lastEnd = fe;\n });\n if (lastEnd < line.length) segs.push(<span key=\"te\">{line.substring(lastEnd)}</span>);\n return <>{segs}</>;\n }, [renderTextWithUnderlines, screenData?.cols, profile.defaultCols, showSignInHint]);\n\n // --- Screen rendering ---\n const renderScreen = () => {\n if (showBootLoader && !screenData?.content) {\n if (bootLoader === false) return null;\n if (bootLoader) return <>{bootLoader}</>;\n return <DefaultBootLoader brandText={profile.bootText} />;\n }\n if (bootFadingOut && screenData?.content) return <div className=\"gs-fade-in\">{renderScreenContent()}</div>;\n if (!screenData?.content) {\n if (inlineSignIn && !connStatus?.connected) {\n return (\n <div style={{ width: '100%', height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <InlineSignIn defaultProtocol={signInDefaultProtocol || protocol || 'tn5250'} loading={connecting || reconnecting} error={signInError || connectError} onConnect={handleSignIn} />\n </div>\n );\n }\n return (\n <div style={{ width: `${screenData?.cols || profile.defaultCols}ch`, height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <div style={{ textAlign: 'center' }}>\n <div style={{ color: '#808080', marginBottom: '12px' }}><TerminalIcon size={40} /></div>\n <p style={{ fontFamily: 'var(--gs-font)', fontSize: '12px', color: connStatus?.status === 'connecting' ? '#f59e0b' : connStatus?.status === 'loading' ? '#94a3b8' : '#808080' }}>\n {connStatus?.connected ? 'Waiting for screen data...' : connStatus?.status === 'connecting' ? 'Connecting...' : connStatus?.status === 'loading' ? 'Loading...' : 'Not connected'}\n </p>\n {!connStatus?.connected && isUsingDefaultAdapter && (\n <p style={{ fontFamily: 'var(--gs-font)', fontSize: '11px', color: '#606060', marginTop: '8px' }}>\n Start the proxy: <code style={{ color: '#10b981' }}>npx green-screen-proxy --mock</code>\n </p>\n )}\n </div>\n </div>\n );\n }\n return renderScreenContent();\n };\n\n const renderScreenContent = () => {\n if (!screenData?.content) return null;\n const termRows = screenData.rows || profile.defaultRows;\n const cols = screenData.cols || profile.defaultCols;\n const lines = screenData.content.split('\\n');\n const rows: string[] = [];\n for (let i = 0; i < termRows; i++) rows.push((lines[i] || '').padEnd(cols, ' '));\n\n const fields = screenData.fields || [];\n const ROW_HEIGHT = 21;\n const cursor = getCursorPos();\n const hasCursor = screenData.cursor_row !== undefined && screenData.cursor_col !== undefined;\n // Only show cursor when it's inside a visible input field (not non-display/password)\n const cursorInInputField = hasCursor && fields.some(f =>\n f.is_input && !(f as any).is_non_display &&\n f.row === cursor.row &&\n cursor.col >= f.col && cursor.col < f.col + f.length\n );\n\n return (\n <div style={{ fontFamily: 'var(--gs-font)', fontSize: '13px', position: 'relative', width: `${cols}ch` }}>\n {rows.map((line, index) => {\n // Apply optimistic edits to this row\n let displayLine = line;\n const rowEdits = optimisticEdits.filter(e => e.row === index);\n if (rowEdits.length > 0) {\n const chars = displayLine.split('');\n for (const edit of rowEdits) {\n if (edit.col >= 0 && edit.col < chars.length) chars[edit.col] = edit.ch;\n }\n displayLine = chars.join('');\n }\n const headerSegments = index === 0 ? profile.colors.parseHeaderRow(displayLine) : null;\n return (\n <div key={index} className={headerSegments ? '' : profile.colors.getRowColorClass(index, displayLine, termRows)} style={{ height: `${ROW_HEIGHT}px`, lineHeight: `${ROW_HEIGHT}px`, whiteSpace: 'pre', position: 'relative' }}>\n {headerSegments\n ? headerSegments.map((seg, i) => <span key={i} className={seg.colorClass}>{seg.text}</span>)\n : renderRowWithFields(displayLine, index, fields)}\n {cursorInInputField && !showSignInHint && index === cursor.row && (\n <span className=\"gs-cursor\" style={{ position: 'absolute', left: `${cursor.col}ch`, width: '1ch', height: `${ROW_HEIGHT}px`, top: 0, pointerEvents: 'none' }} />\n )}\n </div>\n );\n })}\n {showSignInHint && (\n <div className=\"gs-signin-hint\">\n Signed in — press Enter to continue\n </div>\n )}\n {screenData.cursor_row !== undefined && screenData.cursor_col !== undefined && (\n <span style={{ position: 'absolute', bottom: 0, right: 0, fontFamily: 'var(--gs-font)', fontSize: '10px', color: 'var(--gs-green, #10b981)', pointerEvents: 'none', opacity: 0.6 }}>\n {String(screenData.cursor_row + 1).padStart(2, '0')}/{String(screenData.cursor_col + 1).padStart(3, '0')}\n </span>\n )}\n </div>\n );\n };\n\n const handleReconnect = async () => {\n setAutoReconnectAttempt(0);\n setIsAutoReconnecting(false);\n if (reconnectTimeoutRef.current) { clearTimeout(reconnectTimeoutRef.current); reconnectTimeoutRef.current = null; }\n await reconnect();\n };\n\n const getStatusColor = (status?: string) => {\n switch (status) {\n case 'authenticated': return 'var(--gs-green, #10b981)';\n case 'connected': return '#F59E0B';\n case 'connecting': return '#64748b';\n case 'error': return '#EF4444';\n default: return '#64748b';\n }\n };\n\n return (\n <div className={`gs-terminal ${isFocused ? 'gs-terminal-focused' : ''} ${className || ''}`} style={style}>\n {showHeader && (\n <div className=\"gs-header\">\n {embedded ? (\n <>\n <span className=\"gs-header-left\">\n <TerminalIcon size={14} />\n <span>TERMINAL</span>\n {isFocused && <span className=\"gs-badge-focused\">FOCUSED</span>}\n {screenData?.timestamp && <span className=\"gs-timestamp\">{new Date(screenData.timestamp).toLocaleTimeString()}</span>}\n <span className=\"gs-hint\">{readOnly ? 'Read-only' : isFocused ? 'ESC to exit focus' : 'Click to control'}</span>\n {screenData?.keyboard_locked && <span className=\"gs-badge-lock\">X II</span>}\n {screenData?.insert_mode && <span className=\"gs-badge-ins\">INS</span>}\n </span>\n <div className=\"gs-header-right\">\n {connStatus?.status && connStatus.status !== 'loading' && <KeyIcon size={12} style={{ color: getStatusColor(connStatus.status) }} />}\n {connStatus && connStatus.status !== 'loading' && (connStatus.connected\n ? <WifiIcon size={12} style={{ color: 'var(--gs-green, #10b981)' }} />\n : <WifiOffIcon size={12} style={{ color: '#FF6B00' }} />)}\n {statusActions}\n {onMinimize && <button onClick={(e) => { e.stopPropagation(); onMinimize(); }} className=\"gs-btn-icon\" title=\"Minimize terminal\"><MinimizeIcon /></button>}\n <button onClick={(e) => { e.stopPropagation(); setShowShortcuts(s => !s); }} className=\"gs-btn-icon\" title=\"Keyboard shortcuts\"><HelpIcon size={12} /></button>\n {headerRight}\n </div>\n </>\n ) : (\n <>\n <span className=\"gs-header-left\">\n <TerminalIcon size={14} />\n <span>{profile.headerLabel}</span>\n {isFocused && <span className=\"gs-badge-focused\">FOCUSED</span>}\n {screenData?.timestamp && <span className=\"gs-timestamp\">{new Date(screenData.timestamp).toLocaleTimeString()}</span>}\n <span className=\"gs-hint\">{readOnly ? 'Read-only mode' : isFocused ? 'ESC to exit focus' : 'Click terminal to control'}</span>\n {screenData?.keyboard_locked && <span className=\"gs-badge-lock\">X II</span>}\n {screenData?.insert_mode && <span className=\"gs-badge-ins\">INS</span>}\n </span>\n <div className=\"gs-header-right\">\n {connStatus && connStatus.status !== 'loading' && (\n <div className=\"gs-status-group\">\n {connStatus.connected ? (\n <>\n <WifiIcon size={12} style={{ color: 'var(--gs-green, #10b981)' }} />\n <span className=\"gs-host\">{connStatus.host}</span>\n </>\n ) : (\n <>\n <WifiOffIcon size={12} style={{ color: '#FF6B00' }} />\n <span className=\"gs-disconnected-text\">\n {isAutoReconnecting || reconnecting\n ? `RECONNECTING${autoReconnectAttempt > 0 ? ` (${autoReconnectAttempt}/${maxAttempts})` : '...'}`\n : autoReconnectAttempt >= maxAttempts ? 'DISCONNECTED (auto-retry exhausted)' : 'DISCONNECTED'}\n </span>\n <button onClick={handleReconnect} disabled={reconnecting || isAutoReconnecting} className=\"gs-btn-icon\" title=\"Reconnect\">\n <RefreshIcon size={12} className={reconnecting || isAutoReconnecting ? 'gs-spin' : ''} />\n </button>\n </>\n )}\n </div>\n )}\n {connStatus?.status && (\n <div className=\"gs-status-group\">\n <KeyIcon size={12} style={{ color: getStatusColor(connStatus.status) }} />\n {connStatus.username && <span className=\"gs-host\">{connStatus.username}</span>}\n </div>\n )}\n {statusActions}\n <button onClick={(e) => { e.stopPropagation(); setShowShortcuts(s => !s); }} className=\"gs-btn-icon\" title=\"Keyboard shortcuts\"><HelpIcon size={12} /></button>\n {headerRight}\n </div>\n </>\n )}\n </div>\n )}\n\n <div className=\"gs-body\">\n <div ref={terminalRef} onClick={handleTerminalClick} className={`gs-screen ${embedded ? 'gs-screen-embedded' : ''}`}\n style={!embedded ? { width: `calc(${screenData?.cols || profile.defaultCols}ch + 24px)`, fontSize: (screenData?.cols ?? profile.defaultCols) > 80 ? '11px' : '13px', fontFamily: 'var(--gs-font)' } : undefined}>\n {screenError != null && (\n <div className=\"gs-error-banner\">\n <AlertTriangleIcon size={14} />\n <span>{String(screenError)}</span>\n </div>\n )}\n <div ref={screenContentRef} className=\"gs-screen-content\">{renderScreen()}</div>\n {overlay}\n {showShortcuts && (\n <div className=\"gs-shortcuts-panel\">\n <div className=\"gs-shortcuts-header\">\n <span>Keyboard Shortcuts</span>\n <button className=\"gs-btn-icon\" onClick={() => setShowShortcuts(false)} style={{ pointerEvents: 'auto' }}>&times;</button>\n </div>\n <table className=\"gs-shortcuts-table\">\n <tbody>\n <tr><td className=\"gs-shortcut-key\">Ctrl+Enter</td><td>Field Exit</td></tr>\n <tr><td className=\"gs-shortcut-key\">Ctrl+R</td><td>Reset</td></tr>\n <tr><td className=\"gs-shortcut-key\">Insert</td><td>Insert / Overwrite</td></tr>\n <tr><td className=\"gs-shortcut-key\">Page Up</td><td>Roll Down</td></tr>\n <tr><td className=\"gs-shortcut-key\">Page Down</td><td>Roll Up</td></tr>\n <tr><td className=\"gs-shortcut-key\">Click</td><td>Focus / Position cursor</td></tr>\n <tr><td className=\"gs-shortcut-key\">Escape</td><td>Exit focus mode</td></tr>\n </tbody>\n </table>\n </div>\n )}\n {connStatus && !connStatus.connected && screenData && (\n <div className=\"gs-overlay\">\n <WifiOffIcon size={28} />\n <span>{isAutoReconnecting || reconnecting ? 'Reconnecting...' : connStatus?.status === 'connecting' ? 'Connecting...' : 'Disconnected'}</span>\n {connStatus.error && !isAutoReconnecting && !reconnecting && (\n <span style={{ fontSize: '0.75em', opacity: 0.7, maxWidth: '80%', textAlign: 'center', wordBreak: 'break-word' }}>{connStatus.error}</span>\n )}\n </div>\n )}\n <input ref={inputRef} type=\"text\" value={inputText} onChange={handleInput} onKeyDown={handleKeyDown}\n style={{ position: 'absolute', opacity: 0, pointerEvents: 'none', fontSize: '13px', lineHeight: '21px', fontFamily: 'var(--gs-font)', padding: 0, border: 'none', height: '21px' }}\n autoComplete=\"off\" autoCorrect=\"off\" autoCapitalize=\"off\" spellCheck={false} />\n </div>\n </div>\n </div>\n );\n}\n","import type { TerminalAdapter, ScreenData, ConnectionStatus, SendResult, ConnectConfig } from './types';\n\nexport interface RestAdapterOptions {\n /** Base URL for the terminal API (e.g. \"https://myhost.com/api/terminal\") */\n baseUrl: string;\n /** Optional headers to include with every request (e.g. Authorization) */\n headers?: Record<string, string>;\n /** Optional function that returns headers (called per-request, useful for dynamic tokens) */\n getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n}\n\n/**\n * REST API adapter for terminal communication.\n *\n * Expects a backend that exposes these endpoints relative to `baseUrl`:\n * - GET /screen → ScreenData\n * - GET /status → ConnectionStatus\n * - POST /send-text → SendResult (body: { text })\n * - POST /send-key → SendResult (body: { key })\n * - POST /connect → SendResult\n * - POST /disconnect → SendResult\n * - POST /reconnect → SendResult\n */\nexport class RestAdapter implements TerminalAdapter {\n private baseUrl: string;\n private staticHeaders: Record<string, string>;\n private getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n\n constructor(options: RestAdapterOptions) {\n // Remove trailing slash\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.staticHeaders = options.headers || {};\n this.getHeaders = options.getHeaders;\n }\n\n private async buildHeaders(): Promise<Record<string, string>> {\n const dynamic = this.getHeaders ? await this.getHeaders() : {};\n return {\n 'Content-Type': 'application/json',\n ...this.staticHeaders,\n ...dynamic,\n };\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers = await this.buildHeaders();\n const response = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const detail = await response.json().catch(() => ({}));\n throw new Error(detail?.detail || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n async getScreen(): Promise<ScreenData | null> {\n try {\n return await this.request<ScreenData>('GET', '/screen');\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n // 503/404 expected when no active connection\n if (message.includes('503') || message.includes('404')) {\n return null;\n }\n throw e;\n }\n }\n\n async getStatus(): Promise<ConnectionStatus> {\n return this.request<ConnectionStatus>('GET', '/status');\n }\n\n async sendText(text: string): Promise<SendResult> {\n return this.request<SendResult>('POST', '/send-text', { text });\n }\n\n async sendKey(key: string): Promise<SendResult> {\n return this.request<SendResult>('POST', '/send-key', { key });\n }\n\n async setCursor(row: number, col: number): Promise<SendResult> {\n return this.request<SendResult>('POST', '/set-cursor', { row, col });\n }\n\n async connect(config?: ConnectConfig): Promise<SendResult> {\n return this.request<SendResult>('POST', '/connect', config);\n }\n\n async disconnect(): Promise<SendResult> {\n return this.request<SendResult>('POST', '/disconnect');\n }\n\n async reconnect(): Promise<SendResult> {\n return this.request<SendResult>('POST', '/reconnect');\n }\n}\n","import type { TerminalAdapter, ScreenData, ConnectionStatus, SendResult, ConnectConfig } from './types';\n\nexport interface WebSocketAdapterOptions {\n /** URL of the green-screen proxy or worker. Auto-detected from env vars, defaults to http://localhost:3001 */\n workerUrl?: string;\n}\n\n/**\n * WebSocket adapter that connects to a green-screen proxy or Cloudflare Worker.\n * The backend holds the TCP connection to the legacy host and relays protocol data.\n *\n * Unlike RestAdapter (which polls over HTTP), this adapter receives real-time\n * screen updates via WebSocket push.\n *\n * workerUrl resolution order:\n * 1. Explicit `workerUrl` option\n * 2. VITE_GREEN_SCREEN_URL / VITE_WORKER_URL (Vite)\n * 3. NEXT_PUBLIC_GREEN_SCREEN_URL (Next.js)\n * 4. REACT_APP_GREEN_SCREEN_URL (CRA)\n * 5. http://localhost:3001\n */\nexport class WebSocketAdapter implements TerminalAdapter {\n private workerUrl: string;\n private ws: WebSocket | null = null;\n private screen: ScreenData | null = null;\n private status: ConnectionStatus = { connected: false, status: 'disconnected' };\n private pendingScreenResolver: ((value: ScreenData | null) => void) | null = null;\n private pendingConnectResolver: ((result: SendResult) => void) | null = null;\n private connectingPromise: Promise<void> | null = null;\n private screenListeners: Set<(screen: ScreenData) => void> = new Set();\n private statusListeners: Set<(status: ConnectionStatus) => void> = new Set();\n private _sessionId: string | null = null;\n\n constructor(options: WebSocketAdapterOptions = {}) {\n this.workerUrl = (\n options.workerUrl\n || WebSocketAdapter.detectEnvUrl()\n || 'http://localhost:3001'\n ).replace(/\\/+$/, '');\n }\n\n private static detectEnvUrl(): string | undefined {\n try {\n if (typeof import.meta !== 'undefined' && (import.meta as any).env) {\n const env = (import.meta as any).env;\n return env.VITE_GREEN_SCREEN_URL || env.VITE_WORKER_URL || undefined;\n }\n } catch { /* import.meta not available */ }\n try {\n // Use indirect eval to avoid static analysis picking up 'process' as a Node global\n const p = typeof globalThis !== 'undefined' && (globalThis as any).process;\n if (p && p.env) {\n return p.env.NEXT_PUBLIC_GREEN_SCREEN_URL\n || p.env.REACT_APP_GREEN_SCREEN_URL\n || undefined;\n }\n } catch { /* process not available */ }\n return undefined;\n }\n\n /** The proxy-side session ID (available after connect or reattach) */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /** Subscribe to real-time screen updates */\n onScreen(listener: (screen: ScreenData) => void): () => void {\n this.screenListeners.add(listener);\n return () => this.screenListeners.delete(listener);\n }\n\n /** Subscribe to status changes */\n onStatus(listener: (status: ConnectionStatus) => void): () => void {\n this.statusListeners.add(listener);\n return () => this.statusListeners.delete(listener);\n }\n\n async getScreen(): Promise<ScreenData | null> {\n return this.screen;\n }\n\n async getStatus(): Promise<ConnectionStatus> {\n return this.status;\n }\n\n async sendText(text: string): Promise<SendResult> {\n return this.sendAndWaitForScreen({ type: 'text', text });\n }\n\n async sendKey(key: string): Promise<SendResult> {\n return this.sendAndWaitForScreen({ type: 'key', key });\n }\n\n async setCursor(row: number, col: number): Promise<SendResult> {\n return this.sendAndWaitForScreen({ type: 'setCursor', row, col });\n }\n\n async connect(config?: ConnectConfig): Promise<SendResult> {\n await this.ensureWebSocket();\n\n if (!config) {\n return { success: false, error: 'ConnectConfig required' };\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.pendingConnectResolver = null;\n resolve({ success: false, error: 'Connection timeout' });\n }, 30000);\n\n this.pendingConnectResolver = (result: SendResult) => {\n clearTimeout(timeout);\n resolve(result);\n };\n\n this.wsSend({\n type: 'connect',\n host: config.host,\n port: config.port,\n protocol: config.protocol,\n username: config.username,\n password: config.password,\n terminalType: config.terminalType,\n });\n });\n }\n\n /**\n * Reattach to an existing proxy session (e.g. after page reload).\n * The proxy keeps the TCP connection alive; this just reconnects the\n * WebSocket and receives the current screen.\n */\n async reattach(sessionId: string): Promise<SendResult> {\n await this.ensureWebSocket();\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.pendingConnectResolver = null;\n resolve({ success: false, error: 'Reattach timeout' });\n }, 10000);\n\n this.pendingConnectResolver = (result: SendResult) => {\n clearTimeout(timeout);\n resolve(result);\n };\n\n this.wsSend({ type: 'reattach', sessionId });\n });\n }\n\n async disconnect(): Promise<SendResult> {\n this.wsSend({ type: 'disconnect' });\n this.status = { connected: false, status: 'disconnected' };\n this._sessionId = null;\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n return { success: true };\n }\n\n async reconnect(): Promise<SendResult> {\n return { success: false, error: 'Use disconnect() then connect() instead' };\n }\n\n /** Close the WebSocket without sending disconnect (session stays alive on proxy) */\n dispose(): void {\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n\n private async ensureWebSocket(): Promise<void> {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) return;\n if (this.connectingPromise) return this.connectingPromise;\n\n this.connectingPromise = new Promise<void>((resolve, reject) => {\n const wsUrl = this.workerUrl.replace(/^http/, 'ws') + '/ws';\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => resolve();\n this.ws.onerror = () => reject(new Error('WebSocket connection failed'));\n\n this.ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n this.handleMessage(msg);\n } catch { /* ignore non-JSON messages */ }\n };\n\n this.ws.onclose = () => {\n this.status = { connected: false, status: 'disconnected' };\n for (const listener of this.statusListeners) listener(this.status);\n };\n }).finally(() => {\n this.connectingPromise = null;\n });\n\n return this.connectingPromise;\n }\n\n private handleMessage(msg: any): void {\n switch (msg.type) {\n case 'screen': {\n this.screen = msg.data;\n for (const listener of this.screenListeners) listener(msg.data);\n if (this.pendingScreenResolver) {\n const resolver = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n resolver(msg.data);\n }\n break;\n }\n\n case 'cursor': {\n // Lightweight cursor-only response for local operations (arrows, Tab)\n // Resolve pending promise with just cursor position, no screen update\n if (this.pendingScreenResolver) {\n const resolver = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n resolver({\n cursor_row: msg.data.cursor_row,\n cursor_col: msg.data.cursor_col,\n content: this.screen?.content ?? '',\n screen_signature: this.screen?.screen_signature ?? '',\n } as any);\n }\n break;\n }\n\n case 'status':\n this.status = msg.data;\n for (const listener of this.statusListeners) listener(msg.data);\n break;\n\n case 'connected':\n this._sessionId = msg.sessionId ?? null;\n if (this.pendingConnectResolver) {\n const resolver = this.pendingConnectResolver;\n this.pendingConnectResolver = null;\n resolver({ success: true });\n }\n break;\n\n case 'error': {\n if (this.pendingConnectResolver) {\n const resolver = this.pendingConnectResolver;\n this.pendingConnectResolver = null;\n resolver({ success: false, error: msg.message });\n } else if (this.pendingScreenResolver) {\n const resolver = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n resolver(null);\n }\n break;\n }\n }\n }\n\n private sendAndWaitForScreen(msg: object): Promise<SendResult> {\n return new Promise((resolve) => {\n // Flush any existing pending resolver with current screen data\n if (this.pendingScreenResolver) {\n const old = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n old(this.screen);\n }\n\n const timeout = setTimeout(() => {\n this.pendingScreenResolver = null;\n resolve({ success: true, ...this.screenToResult() });\n }, 5000);\n\n this.pendingScreenResolver = (screen: ScreenData | null) => {\n clearTimeout(timeout);\n if (screen) {\n resolve({\n success: true,\n cursor_row: screen.cursor_row,\n cursor_col: screen.cursor_col,\n content: screen.content,\n screen_signature: screen.screen_signature,\n });\n } else {\n resolve({ success: false, error: 'No screen data received' });\n }\n };\n\n this.wsSend(msg);\n });\n }\n\n private screenToResult(): Partial<SendResult> {\n if (!this.screen) return {};\n return {\n cursor_row: this.screen.cursor_row,\n cursor_col: this.screen.cursor_col,\n content: this.screen.content,\n screen_signature: this.screen.screen_signature,\n };\n }\n\n private wsSend(data: object): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(data));\n }\n }\n}\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport type { TerminalAdapter, ScreenData, ConnectionStatus, SendResult, ConnectConfig } from '../adapters/types';\n\n/**\n * Hook for terminal connection management via adapter.\n */\nexport function useTerminalConnection(adapter: TerminalAdapter) {\n const [status, setStatus] = useState<ConnectionStatus | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const fetchStatus = useCallback(async () => {\n try {\n const result = await adapter.getStatus();\n setStatus(result);\n return result;\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return null;\n }\n }, [adapter]);\n\n const connect = useCallback(async (config?: ConnectConfig) => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.connect(config);\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n const disconnect = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n await adapter.disconnect();\n setStatus(prev => prev ? { ...prev, connected: false, status: 'disconnected' } : null);\n return { success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n const reconnect = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.reconnect();\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n return { status, loading, error, fetchStatus, connect, disconnect, reconnect };\n}\n\n/**\n * Hook for terminal screen content with polling.\n */\nexport function useTerminalScreen(\n adapter: TerminalAdapter,\n interval: number = 2000,\n enabled: boolean = true,\n) {\n const [data, setData] = useState<ScreenData | null>(null);\n const [error, setError] = useState<unknown>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n useEffect(() => {\n if (!enabled) {\n if (intervalRef.current) clearInterval(intervalRef.current);\n return;\n }\n\n const poll = async () => {\n try {\n const screen = await adapter.getScreen();\n if (screen) setData(screen);\n setError(null);\n } catch (err) {\n setError(err);\n }\n };\n\n poll(); // Initial fetch\n intervalRef.current = setInterval(poll, interval);\n\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, [adapter, interval, enabled]);\n\n return { data, error };\n}\n\n/**\n * Hook for terminal operations (sendText, sendKey).\n */\nexport function useTerminalInput(adapter: TerminalAdapter) {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const sendText = useCallback(async (text: string): Promise<SendResult> => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.sendText(text);\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n const sendKey = useCallback(async (key: string): Promise<SendResult> => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.sendKey(key);\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n return { loading, error, sendText, sendKey };\n}\n","import { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { positionToRowCol, isFieldEntry } from '../utils/grid';\n\n/**\n * Hook for typing animation effect on terminal screen content.\n * Reveals characters progressively when screen content changes.\n * Also provides animated cursor position that follows the typing.\n *\n * Uses a queue-based model: incoming content updates are queued when an\n * animation is in progress, then played sequentially. This prevents\n * blinks (no mid-animation cancellation) and skips (every field entry\n * gets its own animation). Queue depth is capped to avoid falling\n * behind real-time.\n *\n * Screen transitions (large changes) always display SYNCHRONOUSLY.\n */\nexport function useTypingAnimation(\n content: string | null | undefined,\n enabled: boolean = true,\n typingBudgetMs: number = 100,\n) {\n const FRAME_DELAY = 16; // ~60fps\n\n const previousContentRef = useRef('');\n const targetContentRef = useRef('');\n const contentQueueRef = useRef<string[]>([]);\n const isAnimatingRef = useRef(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rafRef = useRef<number | null>(null);\n\n const [animatedContent, setAnimatedContent] = useState('');\n const [isAnimating, setIsAnimating] = useState(false);\n const [animatedCursorPos, setAnimatedCursorPos] = useState<{ row: number; col: number } | null>(null);\n\n const cancelAnimation = () => {\n if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; }\n if (rafRef.current) { cancelAnimationFrame(rafRef.current); rafRef.current = null; }\n };\n\n const showInstant = useCallback((c: string) => {\n cancelAnimation();\n setAnimatedContent(c);\n setAnimatedCursorPos(null);\n setIsAnimating(false);\n isAnimatingRef.current = false;\n previousContentRef.current = c;\n targetContentRef.current = '';\n }, []);\n\n const processNextRef = useRef<(() => void) | null>(null);\n\n const startFieldAnimation = useCallback((fromContent: string, toContent: string) => {\n let diffStart = -1;\n let diffEnd = 0;\n const maxLen = Math.max(fromContent.length, toContent.length);\n for (let i = 0; i < maxLen; i++) {\n if ((fromContent[i] || ' ') !== (toContent[i] || ' ')) {\n if (diffStart === -1) diffStart = i;\n diffEnd = i;\n }\n }\n if (diffStart === -1) { showInstant(toContent); return; }\n\n setIsAnimating(true);\n isAnimatingRef.current = true;\n targetContentRef.current = toContent;\n\n const diffLength = diffEnd - diffStart + 1;\n\n const oldRegion = fromContent.substring(diffStart, diffEnd + 1);\n const isCorrection = oldRegion.replace(/[_\\s\\n]/g, '').length > 0;\n\n const finishAnimation = () => {\n setAnimatedContent(toContent);\n setIsAnimating(false);\n isAnimatingRef.current = false;\n setAnimatedCursorPos(null);\n previousContentRef.current = toContent;\n targetContentRef.current = '';\n timeoutRef.current = null;\n rafRef.current = null;\n if (processNextRef.current) processNextRef.current();\n };\n\n if (isCorrection) {\n const CORRECTION_BUDGET = 400;\n const removalBudget = Math.floor(CORRECTION_BUDGET * 0.4);\n const typingBudget = CORRECTION_BUDGET - removalBudget;\n const removalFrames = Math.max(2, Math.floor(removalBudget / FRAME_DELAY));\n const typingFrames = Math.max(2, Math.floor(typingBudget / FRAME_DELAY));\n const removalCPF = Math.max(1, Math.ceil(diffLength / removalFrames));\n const typingCPF = Math.max(1, Math.ceil(diffLength / typingFrames));\n\n let removePos = diffEnd + 1;\n let typePos = diffStart;\n\n const buildRemovalContent = (erasedFrom: number) => {\n const before = fromContent.substring(0, diffStart);\n const remaining = fromContent.substring(diffStart, erasedFrom);\n const erased = ' '.repeat(Math.max(0, diffEnd + 1 - erasedFrom));\n const after = toContent.substring(diffEnd + 1);\n return before + remaining + erased + after;\n };\n\n const buildTypingContent = (revealedUpTo: number) => {\n const before = toContent.substring(0, diffStart);\n const revealed = toContent.substring(diffStart, revealedUpTo);\n const hidden = toContent.substring(revealedUpTo, diffEnd + 1).replace(/[^\\n]/g, ' ');\n const after = toContent.substring(diffEnd + 1);\n return before + revealed + hidden + after;\n };\n\n const animateTyping = () => {\n typePos += typingCPF;\n if (typePos >= diffEnd + 1) {\n finishAnimation();\n } else {\n setAnimatedContent(buildTypingContent(typePos));\n setAnimatedCursorPos(positionToRowCol(toContent, typePos));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateTyping);\n }, FRAME_DELAY);\n }\n };\n\n const animateRemoval = () => {\n removePos -= removalCPF;\n if (removePos <= diffStart) {\n setAnimatedContent(buildTypingContent(diffStart));\n setAnimatedCursorPos(positionToRowCol(toContent, diffStart));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateTyping);\n }, FRAME_DELAY);\n } else {\n setAnimatedContent(buildRemovalContent(removePos));\n setAnimatedCursorPos(positionToRowCol(fromContent, removePos));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateRemoval);\n }, FRAME_DELAY);\n }\n };\n\n setAnimatedCursorPos(positionToRowCol(fromContent, diffEnd));\n setAnimatedContent(buildRemovalContent(diffEnd + 1));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateRemoval);\n }, FRAME_DELAY);\n } else {\n let currentPos = diffStart;\n const totalFrames = Math.max(1, Math.floor(typingBudgetMs / FRAME_DELAY));\n const charsPerFrame = Math.max(1, Math.ceil(diffLength / totalFrames));\n\n setAnimatedCursorPos(positionToRowCol(toContent, diffStart));\n\n const buildDisplayContent = (revealedUpTo: number) => {\n const before = toContent.substring(0, diffStart);\n const revealed = toContent.substring(diffStart, revealedUpTo);\n const hidden = toContent.substring(revealedUpTo, diffEnd + 1).replace(/[^\\n]/g, ' ');\n const after = toContent.substring(diffEnd + 1);\n return before + revealed + hidden + after;\n };\n\n const animate = () => {\n currentPos += charsPerFrame;\n if (currentPos >= diffEnd + 1) {\n finishAnimation();\n } else {\n setAnimatedContent(buildDisplayContent(currentPos));\n setAnimatedCursorPos(positionToRowCol(toContent, currentPos));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animate);\n }, FRAME_DELAY);\n }\n };\n\n setAnimatedContent(buildDisplayContent(diffStart));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animate);\n }, FRAME_DELAY);\n }\n }, [showInstant, typingBudgetMs]);\n\n processNextRef.current = () => {\n const queue = contentQueueRef.current;\n if (queue.length === 0) return;\n\n while (queue.length > 2) queue.shift();\n\n const next = queue.shift()!;\n const base = previousContentRef.current;\n\n if (isFieldEntry(base, next)) {\n startFieldAnimation(base, next);\n } else {\n showInstant(next);\n if (queue.length > 0 && processNextRef.current) processNextRef.current();\n }\n };\n\n const shouldAnimate = enabled && content && isFieldEntry(previousContentRef.current, content);\n if (!shouldAnimate && !isAnimatingRef.current && content !== previousContentRef.current) {\n previousContentRef.current = content || '';\n }\n\n useEffect(() => {\n if (!enabled || !content) {\n cancelAnimation();\n contentQueueRef.current = [];\n showInstant(content || '');\n previousContentRef.current = content || '';\n return;\n }\n\n const currentTarget = targetContentRef.current || previousContentRef.current;\n if (content === currentTarget) return;\n\n if (isAnimatingRef.current) {\n if (!isFieldEntry(currentTarget, content)) {\n contentQueueRef.current = [];\n showInstant(content);\n } else {\n contentQueueRef.current.push(content);\n if (contentQueueRef.current.length > 3) {\n contentQueueRef.current = contentQueueRef.current.slice(-2);\n }\n }\n return;\n }\n\n const prev = previousContentRef.current;\n if (!isFieldEntry(prev, content)) {\n showInstant(content);\n return;\n }\n startFieldAnimation(prev, content);\n\n return cancelAnimation;\n }, [content, enabled, showInstant, startFieldAnimation]);\n\n const animationActive = isAnimatingRef.current;\n\n const displayedContent = useMemo(() => {\n if (!enabled || !content) return content || '';\n if (animationActive) return animatedContent;\n return content;\n }, [enabled, content, animationActive, animatedContent]);\n\n const effectiveCursorPos = animationActive ? animatedCursorPos : null;\n\n return { displayedContent, isAnimating, animatedCursorPos: effectiveCursorPos };\n}\n","/**\n * Convert a linear position in screen content to row/col coordinates.\n * Content is lines of characters separated by newlines.\n */\nexport function positionToRowCol(content: string, position: number): { row: number; col: number } {\n let row = 0;\n let col = 0;\n for (let i = 0; i < position && i < content.length; i++) {\n if (content[i] === '\\n') {\n row++;\n col = 0;\n } else {\n col++;\n }\n }\n return { row, col };\n}\n\n/**\n * Detect if a content change is a field entry (small, localized change)\n * vs a screen transition (large, distributed change).\n *\n * Field entries: < 50 changed characters within a span of < 100 positions.\n * Screen transitions: everything else.\n */\nexport function isFieldEntry(previousContent: string | null | undefined, content: string | null | undefined): boolean {\n if (!previousContent || !content) return false;\n\n let diffCount = 0;\n let diffStart = -1;\n let diffEnd = 0;\n const maxLen = Math.max(previousContent.length, content.length);\n\n for (let i = 0; i < maxLen; i++) {\n const oldChar = previousContent[i] || ' ';\n const newChar = content[i] || ' ';\n if (oldChar !== newChar) {\n diffCount++;\n if (diffStart === -1) diffStart = i;\n diffEnd = i;\n }\n }\n\n const diffSpan = diffEnd - diffStart + 1;\n // Field entry: small number of changes (< 50 chars), localized (span < 100)\n return diffCount > 2 && diffCount < 50 && diffSpan < 100;\n}\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const tn5250Profile: ProtocolProfile = {\n protocol: 'tn5250',\n displayName: 'IBM TN5250',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: 'TN5250 TERMINAL',\n bootText: 'TN5250',\n colors: {\n getRowColorClass(rowIndex: number, rowContent: string, totalRows: number): string {\n if (rowIndex === 0 && rowContent.trim().length > 0) return 'gs-row-title';\n if (rowIndex >= totalRows - 2) return 'gs-row-fkey';\n if (/F\\d{1,2}=/.test(rowContent)) return 'gs-row-fkey';\n if (/Select one of the following/i.test(rowContent)) return 'gs-row-subtitle';\n return 'gs-row-content';\n },\n parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n if (line.trim().length === 0) return null;\n const trimmed = line.trimStart();\n const leftMatch = trimmed.match(/^(\\S+)/);\n if (leftMatch) {\n const leftId = leftMatch[1];\n const leftEnd = line.indexOf(leftId) + leftId.length;\n const rightMatch = line.trimEnd().match(/(\\S+)$/);\n if (rightMatch && rightMatch[1] !== leftId) {\n const rightStart = line.lastIndexOf(rightMatch[1]);\n return [\n { text: line.substring(0, leftEnd), colorClass: 'gs-row-fkey' },\n { text: line.substring(leftEnd, rightStart), colorClass: 'gs-row-title' },\n { text: line.substring(rightStart), colorClass: 'gs-row-content' },\n ];\n }\n }\n return [{ text: line, colorClass: 'gs-row-title' }];\n },\n },\n};\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const tn3270Profile: ProtocolProfile = {\n protocol: 'tn3270',\n displayName: 'IBM TN3270',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: 'TN3270 TERMINAL',\n bootText: 'TN3270',\n colors: {\n getRowColorClass(rowIndex: number, rowContent: string, totalRows: number): string {\n // z/OS ISPF conventions: row 0 = title, last 2 rows = PF keys/command\n if (rowIndex === 0 && rowContent.trim().length > 0) return 'gs-row-title';\n if (rowIndex >= totalRows - 2) return 'gs-row-fkey';\n if (/PF\\d{1,2}[=/]/.test(rowContent) || /F\\d{1,2}=/.test(rowContent)) return 'gs-row-fkey';\n if (/COMMAND\\s*===>/i.test(rowContent) || /===>/.test(rowContent)) return 'gs-row-subtitle';\n if (/OPTION\\s*===>/i.test(rowContent)) return 'gs-row-subtitle';\n return 'gs-row-content';\n },\n parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n if (line.trim().length === 0) return null;\n // ISPF: typically \"Menu Utilities Compilers ...\" action bar or panel title\n const trimmed = line.trimStart();\n const leftMatch = trimmed.match(/^(\\S+)/);\n if (leftMatch) {\n const leftId = leftMatch[1];\n const leftEnd = line.indexOf(leftId) + leftId.length;\n const rightMatch = line.trimEnd().match(/(\\S+)$/);\n if (rightMatch && rightMatch[1] !== leftId) {\n const rightStart = line.lastIndexOf(rightMatch[1]);\n return [\n { text: line.substring(0, leftEnd), colorClass: 'gs-row-fkey' },\n { text: line.substring(leftEnd, rightStart), colorClass: 'gs-row-title' },\n { text: line.substring(rightStart), colorClass: 'gs-row-content' },\n ];\n }\n }\n return [{ text: line, colorClass: 'gs-row-title' }];\n },\n },\n};\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const vtProfile: ProtocolProfile = {\n protocol: 'vt',\n displayName: 'VT Terminal',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: 'VT TERMINAL',\n bootText: 'VT220',\n colors: {\n getRowColorClass(_rowIndex: number, _rowContent: string, _totalRows: number): string {\n // VT terminals use inline escape-sequence-driven colors, not row-based conventions.\n // All rows default to green; actual colors come from ANSI attributes in the data stream.\n return 'gs-row-content';\n },\n parseHeaderRow(_line: string): { text: string; colorClass: string }[] | null {\n // VT has no header row convention\n return null;\n },\n },\n};\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const hp6530Profile: ProtocolProfile = {\n protocol: 'hp6530',\n displayName: 'HP 6530',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: '6530 TERMINAL',\n bootText: 'HP6530',\n colors: {\n getRowColorClass(rowIndex: number, rowContent: string, totalRows: number): string {\n // HP NonStop 6530: row 0 = status/title, last row = function key labels\n if (rowIndex === 0 && rowContent.trim().length > 0) return 'gs-row-title';\n if (rowIndex >= totalRows - 1) return 'gs-row-fkey';\n if (/F\\d{1,2}[=\\-]/.test(rowContent) || /SF\\d{1,2}/.test(rowContent)) return 'gs-row-fkey';\n return 'gs-row-content';\n },\n parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n if (line.trim().length === 0) return null;\n return [{ text: line, colorClass: 'gs-row-title' }];\n },\n },\n};\n","import type { TerminalProtocol, ProtocolProfile } from '../adapters/types';\nimport { tn5250Profile } from './tn5250';\nimport { tn3270Profile } from './tn3270';\nimport { vtProfile } from './vt';\nimport { hp6530Profile } from './hp6530';\n\nconst profiles: Record<TerminalProtocol, ProtocolProfile> = {\n tn5250: tn5250Profile,\n tn3270: tn3270Profile,\n vt: vtProfile,\n hp6530: hp6530Profile,\n};\n\n/**\n * Get a protocol profile by type. Defaults to TN5250 for backward compatibility.\n */\nexport function getProtocolProfile(protocol?: TerminalProtocol): ProtocolProfile {\n return profiles[protocol || 'tn5250'];\n}\n","import React, { useState, useEffect, useRef } from 'react';\n\nexport interface TerminalBootLoaderProps {\n /** Text to display during boot animation */\n brandText?: string;\n /** Speed in ms per character */\n charSpeed?: number;\n /** Optional logo element to render alongside the text */\n logo?: React.ReactNode;\n /** Height of the boot loader container */\n height?: number | string;\n}\n\n/**\n * Animated boot loader for the terminal.\n * Shows a typewriter-style text reveal animation.\n */\nexport function TerminalBootLoader({\n brandText = 'TERMINAL',\n charSpeed = 80,\n logo,\n height = 504,\n}: TerminalBootLoaderProps) {\n const [charCount, setCharCount] = useState(0);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n useEffect(() => {\n intervalRef.current = setInterval(() => {\n setCharCount(prev => {\n if (prev >= brandText.length) {\n if (intervalRef.current) clearInterval(intervalRef.current);\n return prev;\n }\n return prev + 1;\n });\n }, charSpeed);\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, [brandText, charSpeed]);\n\n const displayed = brandText.substring(0, charCount);\n\n return (\n <div\n className=\"gs-boot-loader\"\n style={{\n height: typeof height === 'number' ? `${height}px` : height,\n backgroundColor: 'var(--gs-bg, #000)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontFamily: 'var(--gs-font)',\n fontSize: '13px',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n {logo}\n <h1\n style={{\n fontFamily: 'var(--gs-font)',\n fontSize: '1.5rem',\n letterSpacing: '0.1em',\n color: 'var(--gs-green, #10b981)',\n textShadow: '0 0 12px rgba(16, 185, 129, 0.4)',\n margin: 0,\n }}\n >\n {displayed}\n <span\n className=\"tn5250-cursor\"\n style={{\n display: 'inline-block',\n width: '0.6ch',\n height: '1.2em',\n verticalAlign: 'middle',\n marginLeft: '2px',\n }}\n />\n </h1>\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nexport const TerminalIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"4 17 10 11 4 5\" /><line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\" />\n </svg>\n);\n\nexport const WifiIcon = ({ size = 12, className, style: s }: { size?: number; className?: string; style?: React.CSSProperties }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} style={s}>\n <path d=\"M5 12.55a11 11 0 0 1 14.08 0\" /><path d=\"M1.42 9a16 16 0 0 1 21.16 0\" /><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\" /><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\" />\n </svg>\n);\n\nexport const WifiOffIcon = ({ size = 12, className, style: s }: { size?: number; className?: string; style?: React.CSSProperties }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} style={s}>\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" /><path d=\"M16.72 11.06A10.94 10.94 0 0 1 19 12.55\" /><path d=\"M5 12.55a10.94 10.94 0 0 1 5.17-2.39\" /><path d=\"M10.71 5.05A16 16 0 0 1 22.56 9\" /><path d=\"M1.42 9a15.91 15.91 0 0 1 4.7-2.88\" /><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\" /><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\" />\n </svg>\n);\n\nexport const AlertTriangleIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\" /><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" /><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n);\n\nexport const RefreshIcon = ({ size = 12, className }: { size?: number; className?: string }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}>\n <polyline points=\"23 4 23 10 17 10\" /><polyline points=\"1 20 1 14 7 14\" /><path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\" />\n </svg>\n);\n\nexport const KeyIcon = ({ size = 12, style: s }: { size?: number; style?: React.CSSProperties }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={s}>\n <path d=\"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4\" />\n </svg>\n);\n\nexport const HelpIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\" /><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n);\n\nexport const MinimizeIcon = () => (\n <svg width={14} height={14} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M4 14h6v6M3 21l7-7M20 10h-6V4M21 3l-7 7\" />\n </svg>\n);\n","import React, { useState } from 'react';\nimport type { TerminalProtocol, ConnectConfig } from '../adapters/types';\nimport { TerminalIcon, AlertTriangleIcon, RefreshIcon } from './Icons';\n\nconst PROTOCOL_OPTIONS: { value: TerminalProtocol; label: string }[] = [\n { value: 'tn5250', label: 'TN5250 (IBM i)' },\n { value: 'tn3270', label: 'TN3270 (Mainframe)' },\n { value: 'vt', label: 'VT220' },\n { value: 'hp6530', label: 'HP 6530 (NonStop)' },\n];\n\n/** Terminal type options per protocol (only protocols with >1 option need a dropdown) */\nconst TERMINAL_TYPE_OPTIONS: Partial<Record<TerminalProtocol, { value: string; label: string }[]>> = {\n tn5250: [\n { value: 'IBM-3179-2', label: '24 × 80 (Standard)' },\n { value: 'IBM-3477-FC', label: '27 × 132 (Wide)' },\n ],\n tn3270: [\n { value: 'IBM-3278-2', label: '24 × 80 (Model 2)' },\n { value: 'IBM-3278-3', label: '32 × 80 (Model 3)' },\n { value: 'IBM-3278-4', label: '43 × 80 (Model 4)' },\n { value: 'IBM-3278-5', label: '27 × 132 (Model 5)' },\n ],\n};\n\nexport interface InlineSignInProps {\n defaultProtocol: TerminalProtocol;\n loading: boolean;\n error: string | null;\n onConnect: (config: ConnectConfig) => void;\n}\n\nexport function InlineSignIn({ defaultProtocol, loading: externalLoading, error, onConnect }: InlineSignInProps) {\n const [host, setHost] = useState('');\n const [port, setPort] = useState('');\n const [selectedProtocol, setSelectedProtocol] = useState<TerminalProtocol>(defaultProtocol);\n const [terminalType, setTerminalType] = useState('');\n const [username, setUsername] = useState('');\n const [password, setPassword] = useState('');\n\n const termTypeOptions = TERMINAL_TYPE_OPTIONS[selectedProtocol];\n const [submitted, setSubmitted] = useState(false);\n\n const loading = externalLoading || submitted;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setSubmitted(true);\n onConnect({\n host,\n port: port ? parseInt(port, 10) : 23,\n protocol: selectedProtocol,\n ...(username.trim() ? { username: username.trim() } : {}),\n ...(password ? { password } : {}),\n ...(terminalType ? { terminalType } : {}),\n });\n };\n\n const inputStyle: React.CSSProperties = {\n width: '100%',\n padding: '6px 8px',\n backgroundColor: 'rgba(16, 185, 129, 0.05)',\n border: '1px solid var(--gs-card-border, #1e293b)',\n color: 'var(--gs-green, #10b981)',\n fontFamily: 'var(--gs-font)',\n fontSize: '13px',\n outline: 'none',\n boxSizing: 'border-box',\n };\n\n const labelStyle: React.CSSProperties = {\n display: 'block',\n marginBottom: '4px',\n fontSize: '10px',\n letterSpacing: '0.1em',\n textTransform: 'uppercase',\n color: 'var(--gs-muted, #94a3b8)',\n fontFamily: 'var(--gs-font)',\n };\n\n if (loading) {\n return (\n <div className=\"gs-signin\" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '12px' }}>\n <RefreshIcon size={28} className=\"gs-spin\" />\n <div style={{ fontSize: '11px', letterSpacing: '0.15em', textTransform: 'uppercase', color: 'var(--gs-muted)', fontFamily: 'var(--gs-font)' }}>\n Connecting to {host || 'host'}...\n </div>\n </div>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"gs-signin\">\n <div style={{ textAlign: 'center', marginBottom: '16px' }}>\n <TerminalIcon size={28} />\n <div style={{ fontSize: '11px', letterSpacing: '0.15em', textTransform: 'uppercase', color: 'var(--gs-muted)', marginTop: '8px' }}>Connect to Host</div>\n </div>\n\n <div className=\"gs-signin-row\">\n <div style={{ flex: 1 }}>\n <label style={labelStyle}>Host <span style={{ color: '#ef4444' }}>*</span></label>\n <input style={inputStyle} value={host} onChange={e => setHost(e.target.value)} placeholder=\"192.168.1.100\" required autoFocus />\n </div>\n <div style={{ width: '72px' }}>\n <label style={labelStyle}>Port</label>\n <input style={inputStyle} value={port} onChange={e => setPort(e.target.value)} placeholder=\"23\" type=\"number\" min=\"1\" max=\"65535\" />\n </div>\n </div>\n\n <div>\n <label style={labelStyle}>Protocol <span style={{ color: '#ef4444' }}>*</span></label>\n <select style={{ ...inputStyle, appearance: 'none' }} value={selectedProtocol} onChange={e => { setSelectedProtocol(e.target.value as TerminalProtocol); setTerminalType(''); }}>\n {PROTOCOL_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}\n </select>\n </div>\n\n {termTypeOptions && termTypeOptions.length > 1 && (\n <div>\n <label style={labelStyle}>Screen Size</label>\n <select style={{ ...inputStyle, appearance: 'none' }} value={terminalType || termTypeOptions[0].value} onChange={e => setTerminalType(e.target.value)}>\n {termTypeOptions.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}\n </select>\n </div>\n )}\n\n <div>\n <label style={labelStyle}>Username</label>\n <input style={inputStyle} value={username} onChange={e => setUsername(e.target.value)} autoComplete=\"username\" />\n </div>\n\n <div>\n <label style={labelStyle}>Password</label>\n <input style={inputStyle} type=\"password\" value={password} onChange={e => setPassword(e.target.value)} autoComplete=\"current-password\" />\n </div>\n\n {error && (\n <div style={{ color: '#FF6B00', fontSize: '11px', fontFamily: 'var(--gs-font)', display: 'flex', alignItems: 'center', gap: '6px' }}>\n <AlertTriangleIcon size={12} />\n <span>{error}</span>\n </div>\n )}\n\n <button type=\"submit\" disabled={!host} className=\"gs-signin-btn\">\n Connect\n </button>\n </form>\n );\n}\n","import { getProtocolProfile } from '../protocols/registry';\n\n/**\n * Get the appropriate CSS class name for a row.\n * Delegates to the TN5250 protocol profile for backward compatibility.\n *\n * For protocol-aware rendering, use `getProtocolProfile(protocol).colors.getRowColorClass()`.\n */\nexport function getRowColorClass(rowIndex: number, rowContent: string): string {\n return getProtocolProfile('tn5250').colors.getRowColorClass(rowIndex, rowContent, 24);\n}\n\n/**\n * Parse the header row into colored segments.\n * Delegates to the TN5250 protocol profile for backward compatibility.\n *\n * For protocol-aware rendering, use `getProtocolProfile(protocol).colors.parseHeaderRow()`.\n */\nexport function parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n return getProtocolProfile('tn5250').colors.parseHeaderRow(line);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;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;;;ACAA,IAAAA,gBAAyE;;;ACuBlE,IAAM,cAAN,MAA6C;AAAA,EAKlD,YAAY,SAA6B;AAEvC,SAAK,UAAU,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AACjD,SAAK,gBAAgB,QAAQ,WAAW,CAAC;AACzC,SAAK,aAAa,QAAQ;AAAA,EAC5B;AAAA,EAEA,MAAc,eAAgD;AAC5D,UAAM,UAAU,KAAK,aAAa,MAAM,KAAK,WAAW,IAAI,CAAC;AAC7D,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAc,QAAW,QAAgB,MAAc,MAA4B;AACjF,UAAM,UAAU,MAAM,KAAK,aAAa;AACxC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MACrD;AAAA,MACA;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,SAAS,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACrD,YAAM,IAAI,MAAM,QAAQ,UAAU,QAAQ,SAAS,MAAM,EAAE;AAAA,IAC7D;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAEA,MAAM,YAAwC;AAC5C,QAAI;AACF,aAAO,MAAM,KAAK,QAAoB,OAAO,SAAS;AAAA,IACxD,SAAS,GAAY;AACnB,YAAM,UAAU,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAEzD,UAAI,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,KAAK,GAAG;AACtD,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,YAAuC;AAC3C,WAAO,KAAK,QAA0B,OAAO,SAAS;AAAA,EACxD;AAAA,EAEA,MAAM,SAAS,MAAmC;AAChD,WAAO,KAAK,QAAoB,QAAQ,cAAc,EAAE,KAAK,CAAC;AAAA,EAChE;AAAA,EAEA,MAAM,QAAQ,KAAkC;AAC9C,WAAO,KAAK,QAAoB,QAAQ,aAAa,EAAE,IAAI,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,UAAU,KAAa,KAAkC;AAC7D,WAAO,KAAK,QAAoB,QAAQ,eAAe,EAAE,KAAK,IAAI,CAAC;AAAA,EACrE;AAAA,EAEA,MAAM,QAAQ,QAA6C;AACzD,WAAO,KAAK,QAAoB,QAAQ,YAAY,MAAM;AAAA,EAC5D;AAAA,EAEA,MAAM,aAAkC;AACtC,WAAO,KAAK,QAAoB,QAAQ,aAAa;AAAA,EACvD;AAAA,EAEA,MAAM,YAAiC;AACrC,WAAO,KAAK,QAAoB,QAAQ,YAAY;AAAA,EACtD;AACF;;;ACpGA;AAqBO,IAAM,mBAAN,MAAM,kBAA4C;AAAA,EAYvD,YAAY,UAAmC,CAAC,GAAG;AAVnD,SAAQ,KAAuB;AAC/B,SAAQ,SAA4B;AACpC,SAAQ,SAA2B,EAAE,WAAW,OAAO,QAAQ,eAAe;AAC9E,SAAQ,wBAAqE;AAC7E,SAAQ,yBAAgE;AACxE,SAAQ,oBAA0C;AAClD,SAAQ,kBAAqD,oBAAI,IAAI;AACrE,SAAQ,kBAA2D,oBAAI,IAAI;AAC3E,SAAQ,aAA4B;AAGlC,SAAK,aACH,QAAQ,aACL,kBAAiB,aAAa,KAC9B,yBACH,QAAQ,QAAQ,EAAE;AAAA,EACtB;AAAA,EAEA,OAAe,eAAmC;AAChD,QAAI;AACF,UAAI,OAAO,gBAAgB,eAAgB,YAAoB,KAAK;AAClE,cAAM,MAAO,YAAoB;AACjC,eAAO,IAAI,yBAAyB,IAAI,mBAAmB;AAAA,MAC7D;AAAA,IACF,QAAQ;AAAA,IAAkC;AAC1C,QAAI;AAEF,YAAM,IAAI,OAAO,eAAe,eAAgB,WAAmB;AACnE,UAAI,KAAK,EAAE,KAAK;AACd,eAAO,EAAE,IAAI,gCACR,EAAE,IAAI,8BACN;AAAA,MACP;AAAA,IACF,QAAQ;AAAA,IAA8B;AACtC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,YAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,SAAS,UAAoD;AAC3D,SAAK,gBAAgB,IAAI,QAAQ;AACjC,WAAO,MAAM,KAAK,gBAAgB,OAAO,QAAQ;AAAA,EACnD;AAAA;AAAA,EAGA,SAAS,UAA0D;AACjE,SAAK,gBAAgB,IAAI,QAAQ;AACjC,WAAO,MAAM,KAAK,gBAAgB,OAAO,QAAQ;AAAA,EACnD;AAAA,EAEA,MAAM,YAAwC;AAC5C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,YAAuC;AAC3C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,SAAS,MAAmC;AAChD,WAAO,KAAK,qBAAqB,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,EACzD;AAAA,EAEA,MAAM,QAAQ,KAAkC;AAC9C,WAAO,KAAK,qBAAqB,EAAE,MAAM,OAAO,IAAI,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,UAAU,KAAa,KAAkC;AAC7D,WAAO,KAAK,qBAAqB,EAAE,MAAM,aAAa,KAAK,IAAI,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,QAAQ,QAA6C;AACzD,UAAM,KAAK,gBAAgB;AAE3B,QAAI,CAAC,QAAQ;AACX,aAAO,EAAE,SAAS,OAAO,OAAO,yBAAyB;AAAA,IAC3D;AAEA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,UAAU,WAAW,MAAM;AAC/B,aAAK,yBAAyB;AAC9B,gBAAQ,EAAE,SAAS,OAAO,OAAO,qBAAqB,CAAC;AAAA,MACzD,GAAG,GAAK;AAER,WAAK,yBAAyB,CAAC,WAAuB;AACpD,qBAAa,OAAO;AACpB,gBAAQ,MAAM;AAAA,MAChB;AAEA,WAAK,OAAO;AAAA,QACV,MAAM;AAAA,QACN,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,QACjB,cAAc,OAAO;AAAA,MACvB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAS,WAAwC;AACrD,UAAM,KAAK,gBAAgB;AAE3B,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,UAAU,WAAW,MAAM;AAC/B,aAAK,yBAAyB;AAC9B,gBAAQ,EAAE,SAAS,OAAO,OAAO,mBAAmB,CAAC;AAAA,MACvD,GAAG,GAAK;AAER,WAAK,yBAAyB,CAAC,WAAuB;AACpD,qBAAa,OAAO;AACpB,gBAAQ,MAAM;AAAA,MAChB;AAEA,WAAK,OAAO,EAAE,MAAM,YAAY,UAAU,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAkC;AACtC,SAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAClC,SAAK,SAAS,EAAE,WAAW,OAAO,QAAQ,eAAe;AACzD,SAAK,aAAa;AAClB,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AACd,WAAK,KAAK;AAAA,IACZ;AACA,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAAA,EAEA,MAAM,YAAiC;AACrC,WAAO,EAAE,SAAS,OAAO,OAAO,0CAA0C;AAAA,EAC5E;AAAA;AAAA,EAGA,UAAgB;AACd,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AACd,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAc,kBAAiC;AAC7C,QAAI,KAAK,MAAM,KAAK,GAAG,eAAe,UAAU,KAAM;AACtD,QAAI,KAAK,kBAAmB,QAAO,KAAK;AAExC,SAAK,oBAAoB,IAAI,QAAc,CAAC,SAAS,WAAW;AAC9D,YAAM,QAAQ,KAAK,UAAU,QAAQ,SAAS,IAAI,IAAI;AACtD,WAAK,KAAK,IAAI,UAAU,KAAK;AAE7B,WAAK,GAAG,SAAS,MAAM,QAAQ;AAC/B,WAAK,GAAG,UAAU,MAAM,OAAO,IAAI,MAAM,6BAA6B,CAAC;AAEvE,WAAK,GAAG,YAAY,CAAC,UAAU;AAC7B,YAAI;AACF,gBAAM,MAAM,KAAK,MAAM,MAAM,IAAI;AACjC,eAAK,cAAc,GAAG;AAAA,QACxB,QAAQ;AAAA,QAAiC;AAAA,MAC3C;AAEA,WAAK,GAAG,UAAU,MAAM;AACtB,aAAK,SAAS,EAAE,WAAW,OAAO,QAAQ,eAAe;AACzD,mBAAW,YAAY,KAAK,gBAAiB,UAAS,KAAK,MAAM;AAAA,MACnE;AAAA,IACF,CAAC,EAAE,QAAQ,MAAM;AACf,WAAK,oBAAoB;AAAA,IAC3B,CAAC;AAED,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,cAAc,KAAgB;AACpC,YAAQ,IAAI,MAAM;AAAA,MAChB,KAAK,UAAU;AACb,aAAK,SAAS,IAAI;AAClB,mBAAW,YAAY,KAAK,gBAAiB,UAAS,IAAI,IAAI;AAC9D,YAAI,KAAK,uBAAuB;AAC9B,gBAAM,WAAW,KAAK;AACtB,eAAK,wBAAwB;AAC7B,mBAAS,IAAI,IAAI;AAAA,QACnB;AACA;AAAA,MACF;AAAA,MAEA,KAAK,UAAU;AAGb,YAAI,KAAK,uBAAuB;AAC9B,gBAAM,WAAW,KAAK;AACtB,eAAK,wBAAwB;AAC7B,mBAAS;AAAA,YACP,YAAY,IAAI,KAAK;AAAA,YACrB,YAAY,IAAI,KAAK;AAAA,YACrB,SAAS,KAAK,QAAQ,WAAW;AAAA,YACjC,kBAAkB,KAAK,QAAQ,oBAAoB;AAAA,UACrD,CAAQ;AAAA,QACV;AACA;AAAA,MACF;AAAA,MAEA,KAAK;AACH,aAAK,SAAS,IAAI;AAClB,mBAAW,YAAY,KAAK,gBAAiB,UAAS,IAAI,IAAI;AAC9D;AAAA,MAEF,KAAK;AACH,aAAK,aAAa,IAAI,aAAa;AACnC,YAAI,KAAK,wBAAwB;AAC/B,gBAAM,WAAW,KAAK;AACtB,eAAK,yBAAyB;AAC9B,mBAAS,EAAE,SAAS,KAAK,CAAC;AAAA,QAC5B;AACA;AAAA,MAEF,KAAK,SAAS;AACZ,YAAI,KAAK,wBAAwB;AAC/B,gBAAM,WAAW,KAAK;AACtB,eAAK,yBAAyB;AAC9B,mBAAS,EAAE,SAAS,OAAO,OAAO,IAAI,QAAQ,CAAC;AAAA,QACjD,WAAW,KAAK,uBAAuB;AACrC,gBAAM,WAAW,KAAK;AACtB,eAAK,wBAAwB;AAC7B,mBAAS,IAAI;AAAA,QACf;AACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qBAAqB,KAAkC;AAC7D,WAAO,IAAI,QAAQ,CAAC,YAAY;AAE9B,UAAI,KAAK,uBAAuB;AAC9B,cAAM,MAAM,KAAK;AACjB,aAAK,wBAAwB;AAC7B,YAAI,KAAK,MAAM;AAAA,MACjB;AAEA,YAAM,UAAU,WAAW,MAAM;AAC/B,aAAK,wBAAwB;AAC7B,gBAAQ,EAAE,SAAS,MAAM,GAAG,KAAK,eAAe,EAAE,CAAC;AAAA,MACrD,GAAG,GAAI;AAEP,WAAK,wBAAwB,CAAC,WAA8B;AAC1D,qBAAa,OAAO;AACpB,YAAI,QAAQ;AACV,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,YAAY,OAAO;AAAA,YACnB,YAAY,OAAO;AAAA,YACnB,SAAS,OAAO;AAAA,YAChB,kBAAkB,OAAO;AAAA,UAC3B,CAAC;AAAA,QACH,OAAO;AACL,kBAAQ,EAAE,SAAS,OAAO,OAAO,0BAA0B,CAAC;AAAA,QAC9D;AAAA,MACF;AAEA,WAAK,OAAO,GAAG;AAAA,IACjB,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAsC;AAC5C,QAAI,CAAC,KAAK,OAAQ,QAAO,CAAC;AAC1B,WAAO;AAAA,MACL,YAAY,KAAK,OAAO;AAAA,MACxB,YAAY,KAAK,OAAO;AAAA,MACxB,SAAS,KAAK,OAAO;AAAA,MACrB,kBAAkB,KAAK,OAAO;AAAA,IAChC;AAAA,EACF;AAAA,EAEQ,OAAO,MAAoB;AACjC,QAAI,KAAK,MAAM,KAAK,GAAG,eAAe,UAAU,MAAM;AACpD,WAAK,GAAG,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,IACnC;AAAA,EACF;AACF;;;ACpTA,mBAAyD;AAMlD,SAAS,sBAAsB,SAA0B;AAC9D,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAkC,IAAI;AAClE,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAwB,IAAI;AAEtD,QAAM,kBAAc,0BAAY,YAAY;AAC1C,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,UAAU;AACvC,gBAAU,MAAM;AAChB,aAAO;AAAA,IACT,SAAS,KAAc;AACrB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAS,OAAO;AAChB,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,cAAU,0BAAY,OAAO,WAA2B;AAC5D,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,QAAQ,MAAM;AAC3C,aAAO,EAAE,GAAG,QAAQ,SAAS,KAAK;AAAA,IACpC,SAAS,KAAc;AACrB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAS,OAAO;AAChB,aAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,IAC1C,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,iBAAa,0BAAY,YAAY;AACzC,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,QAAQ,WAAW;AACzB,gBAAU,UAAQ,OAAO,EAAE,GAAG,MAAM,WAAW,OAAO,QAAQ,eAAe,IAAI,IAAI;AACrF,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB,SAAS,KAAc;AACrB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAS,OAAO;AAChB,aAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,IAC1C,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,gBAAY,0BAAY,YAAY;AACxC,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,UAAU;AACvC,aAAO,EAAE,GAAG,QAAQ,SAAS,KAAK;AAAA,IACpC,SAAS,KAAc;AACrB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAS,OAAO;AAChB,aAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,IAC1C,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO,EAAE,QAAQ,SAAS,OAAO,aAAa,SAAS,YAAY,UAAU;AAC/E;AAKO,SAAS,kBACd,SACA,WAAmB,KACnB,UAAmB,MACnB;AACA,QAAM,CAAC,MAAM,OAAO,QAAI,uBAA4B,IAAI;AACxD,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAkB,IAAI;AAChD,QAAM,kBAAc,qBAA8C,IAAI;AAEtE,8BAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ,UAAI,YAAY,QAAS,eAAc,YAAY,OAAO;AAC1D;AAAA,IACF;AAEA,UAAM,OAAO,YAAY;AACvB,UAAI;AACF,cAAM,SAAS,MAAM,QAAQ,UAAU;AACvC,YAAI,OAAQ,SAAQ,MAAM;AAC1B,iBAAS,IAAI;AAAA,MACf,SAAS,KAAK;AACZ,iBAAS,GAAG;AAAA,MACd;AAAA,IACF;AAEA,SAAK;AACL,gBAAY,UAAU,YAAY,MAAM,QAAQ;AAEhD,WAAO,MAAM;AACX,UAAI,YAAY,QAAS,eAAc,YAAY,OAAO;AAAA,IAC5D;AAAA,EACF,GAAG,CAAC,SAAS,UAAU,OAAO,CAAC;AAE/B,SAAO,EAAE,MAAM,MAAM;AACvB;AAKO,SAAS,iBAAiB,SAA0B;AACzD,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAwB,IAAI;AAEtD,QAAM,eAAW,0BAAY,OAAO,SAAsC;AACxE,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,SAAS,IAAI;AAC1C,aAAO,EAAE,GAAG,QAAQ,SAAS,KAAK;AAAA,IACpC,SAAS,KAAc;AACrB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAS,OAAO;AAChB,aAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,IAC1C,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,cAAU,0BAAY,OAAO,QAAqC;AACtE,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,QAAQ,GAAG;AACxC,aAAO,EAAE,GAAG,QAAQ,SAAS,KAAK;AAAA,IACpC,SAAS,KAAc;AACrB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAS,OAAO;AAChB,aAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,IAC1C,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO,EAAE,SAAS,OAAO,UAAU,QAAQ;AAC7C;;;ACrJA,IAAAC,gBAAkE;;;ACI3D,SAAS,iBAAiB,SAAiB,UAAgD;AAChG,MAAI,MAAM;AACV,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,YAAY,IAAI,QAAQ,QAAQ,KAAK;AACvD,QAAI,QAAQ,CAAC,MAAM,MAAM;AACvB;AACA,YAAM;AAAA,IACR,OAAO;AACL;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,KAAK,IAAI;AACpB;AASO,SAAS,aAAa,iBAA4C,SAA6C;AACpH,MAAI,CAAC,mBAAmB,CAAC,QAAS,QAAO;AAEzC,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,QAAM,SAAS,KAAK,IAAI,gBAAgB,QAAQ,QAAQ,MAAM;AAE9D,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,UAAM,UAAU,gBAAgB,CAAC,KAAK;AACtC,UAAM,UAAU,QAAQ,CAAC,KAAK;AAC9B,QAAI,YAAY,SAAS;AACvB;AACA,UAAI,cAAc,GAAI,aAAY;AAClC,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,WAAW,UAAU,YAAY;AAEvC,SAAO,YAAY,KAAK,YAAY,MAAM,WAAW;AACvD;;;AD9BO,SAAS,mBACd,SACA,UAAmB,MACnB,iBAAyB,KACzB;AACA,QAAM,cAAc;AAEpB,QAAM,yBAAqB,sBAAO,EAAE;AACpC,QAAM,uBAAmB,sBAAO,EAAE;AAClC,QAAM,sBAAkB,sBAAiB,CAAC,CAAC;AAC3C,QAAM,qBAAiB,sBAAO,KAAK;AACnC,QAAM,iBAAa,sBAA6C,IAAI;AACpE,QAAM,aAAS,sBAAsB,IAAI;AAEzC,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,wBAAS,EAAE;AACzD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAA8C,IAAI;AAEpG,QAAM,kBAAkB,MAAM;AAC5B,QAAI,WAAW,SAAS;AAAE,mBAAa,WAAW,OAAO;AAAG,iBAAW,UAAU;AAAA,IAAM;AACvF,QAAI,OAAO,SAAS;AAAE,2BAAqB,OAAO,OAAO;AAAG,aAAO,UAAU;AAAA,IAAM;AAAA,EACrF;AAEA,QAAM,kBAAc,2BAAY,CAAC,MAAc;AAC7C,oBAAgB;AAChB,uBAAmB,CAAC;AACpB,yBAAqB,IAAI;AACzB,mBAAe,KAAK;AACpB,mBAAe,UAAU;AACzB,uBAAmB,UAAU;AAC7B,qBAAiB,UAAU;AAAA,EAC7B,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAiB,sBAA4B,IAAI;AAEvD,QAAM,0BAAsB,2BAAY,CAAC,aAAqB,cAAsB;AAClF,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,UAAM,SAAS,KAAK,IAAI,YAAY,QAAQ,UAAU,MAAM;AAC5D,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,WAAK,YAAY,CAAC,KAAK,UAAU,UAAU,CAAC,KAAK,MAAM;AACrD,YAAI,cAAc,GAAI,aAAY;AAClC,kBAAU;AAAA,MACZ;AAAA,IACF;AACA,QAAI,cAAc,IAAI;AAAE,kBAAY,SAAS;AAAG;AAAA,IAAQ;AAExD,mBAAe,IAAI;AACnB,mBAAe,UAAU;AACzB,qBAAiB,UAAU;AAE3B,UAAM,aAAa,UAAU,YAAY;AAEzC,UAAM,YAAY,YAAY,UAAU,WAAW,UAAU,CAAC;AAC9D,UAAM,eAAe,UAAU,QAAQ,YAAY,EAAE,EAAE,SAAS;AAEhE,UAAM,kBAAkB,MAAM;AAC5B,yBAAmB,SAAS;AAC5B,qBAAe,KAAK;AACpB,qBAAe,UAAU;AACzB,2BAAqB,IAAI;AACzB,yBAAmB,UAAU;AAC7B,uBAAiB,UAAU;AAC3B,iBAAW,UAAU;AACrB,aAAO,UAAU;AACjB,UAAI,eAAe,QAAS,gBAAe,QAAQ;AAAA,IACrD;AAEA,QAAI,cAAc;AAChB,YAAM,oBAAoB;AAC1B,YAAM,gBAAgB,KAAK,MAAM,oBAAoB,GAAG;AACxD,YAAM,eAAe,oBAAoB;AACzC,YAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,MAAM,gBAAgB,WAAW,CAAC;AACzE,YAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,eAAe,WAAW,CAAC;AACvE,YAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,aAAa,CAAC;AACpE,YAAM,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,YAAY,CAAC;AAElE,UAAI,YAAY,UAAU;AAC1B,UAAI,UAAU;AAEd,YAAM,sBAAsB,CAAC,eAAuB;AAClD,cAAM,SAAS,YAAY,UAAU,GAAG,SAAS;AACjD,cAAM,YAAY,YAAY,UAAU,WAAW,UAAU;AAC7D,cAAM,SAAS,IAAI,OAAO,KAAK,IAAI,GAAG,UAAU,IAAI,UAAU,CAAC;AAC/D,cAAM,QAAQ,UAAU,UAAU,UAAU,CAAC;AAC7C,eAAO,SAAS,YAAY,SAAS;AAAA,MACvC;AAEA,YAAM,qBAAqB,CAAC,iBAAyB;AACnD,cAAM,SAAS,UAAU,UAAU,GAAG,SAAS;AAC/C,cAAM,WAAW,UAAU,UAAU,WAAW,YAAY;AAC5D,cAAM,SAAS,UAAU,UAAU,cAAc,UAAU,CAAC,EAAE,QAAQ,UAAU,GAAG;AACnF,cAAM,QAAQ,UAAU,UAAU,UAAU,CAAC;AAC7C,eAAO,SAAS,WAAW,SAAS;AAAA,MACtC;AAEA,YAAM,gBAAgB,MAAM;AAC1B,mBAAW;AACX,YAAI,WAAW,UAAU,GAAG;AAC1B,0BAAgB;AAAA,QAClB,OAAO;AACL,6BAAmB,mBAAmB,OAAO,CAAC;AAC9C,+BAAqB,iBAAiB,WAAW,OAAO,CAAC;AACzD,qBAAW,UAAU,WAAW,MAAM;AACpC,mBAAO,UAAU,sBAAsB,aAAa;AAAA,UACtD,GAAG,WAAW;AAAA,QAChB;AAAA,MACF;AAEA,YAAM,iBAAiB,MAAM;AAC3B,qBAAa;AACb,YAAI,aAAa,WAAW;AAC1B,6BAAmB,mBAAmB,SAAS,CAAC;AAChD,+BAAqB,iBAAiB,WAAW,SAAS,CAAC;AAC3D,qBAAW,UAAU,WAAW,MAAM;AACpC,mBAAO,UAAU,sBAAsB,aAAa;AAAA,UACtD,GAAG,WAAW;AAAA,QAChB,OAAO;AACL,6BAAmB,oBAAoB,SAAS,CAAC;AACjD,+BAAqB,iBAAiB,aAAa,SAAS,CAAC;AAC7D,qBAAW,UAAU,WAAW,MAAM;AACpC,mBAAO,UAAU,sBAAsB,cAAc;AAAA,UACvD,GAAG,WAAW;AAAA,QAChB;AAAA,MACF;AAEA,2BAAqB,iBAAiB,aAAa,OAAO,CAAC;AAC3D,yBAAmB,oBAAoB,UAAU,CAAC,CAAC;AACnD,iBAAW,UAAU,WAAW,MAAM;AACpC,eAAO,UAAU,sBAAsB,cAAc;AAAA,MACvD,GAAG,WAAW;AAAA,IAChB,OAAO;AACL,UAAI,aAAa;AACjB,YAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,iBAAiB,WAAW,CAAC;AACxE,YAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,WAAW,CAAC;AAErE,2BAAqB,iBAAiB,WAAW,SAAS,CAAC;AAE3D,YAAM,sBAAsB,CAAC,iBAAyB;AACpD,cAAM,SAAS,UAAU,UAAU,GAAG,SAAS;AAC/C,cAAM,WAAW,UAAU,UAAU,WAAW,YAAY;AAC5D,cAAM,SAAS,UAAU,UAAU,cAAc,UAAU,CAAC,EAAE,QAAQ,UAAU,GAAG;AACnF,cAAM,QAAQ,UAAU,UAAU,UAAU,CAAC;AAC7C,eAAO,SAAS,WAAW,SAAS;AAAA,MACtC;AAEA,YAAM,UAAU,MAAM;AACpB,sBAAc;AACd,YAAI,cAAc,UAAU,GAAG;AAC7B,0BAAgB;AAAA,QAClB,OAAO;AACL,6BAAmB,oBAAoB,UAAU,CAAC;AAClD,+BAAqB,iBAAiB,WAAW,UAAU,CAAC;AAC5D,qBAAW,UAAU,WAAW,MAAM;AACpC,mBAAO,UAAU,sBAAsB,OAAO;AAAA,UAChD,GAAG,WAAW;AAAA,QAChB;AAAA,MACF;AAEA,yBAAmB,oBAAoB,SAAS,CAAC;AACjD,iBAAW,UAAU,WAAW,MAAM;AACpC,eAAO,UAAU,sBAAsB,OAAO;AAAA,MAChD,GAAG,WAAW;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,CAAC;AAEhC,iBAAe,UAAU,MAAM;AAC7B,UAAM,QAAQ,gBAAgB;AAC9B,QAAI,MAAM,WAAW,EAAG;AAExB,WAAO,MAAM,SAAS,EAAG,OAAM,MAAM;AAErC,UAAM,OAAO,MAAM,MAAM;AACzB,UAAM,OAAO,mBAAmB;AAEhC,QAAI,aAAa,MAAM,IAAI,GAAG;AAC5B,0BAAoB,MAAM,IAAI;AAAA,IAChC,OAAO;AACL,kBAAY,IAAI;AAChB,UAAI,MAAM,SAAS,KAAK,eAAe,QAAS,gBAAe,QAAQ;AAAA,IACzE;AAAA,EACF;AAEA,QAAM,gBAAgB,WAAW,WAAW,aAAa,mBAAmB,SAAS,OAAO;AAC5F,MAAI,CAAC,iBAAiB,CAAC,eAAe,WAAW,YAAY,mBAAmB,SAAS;AACvF,uBAAmB,UAAU,WAAW;AAAA,EAC1C;AAEA,+BAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,SAAS;AACxB,sBAAgB;AAChB,sBAAgB,UAAU,CAAC;AAC3B,kBAAY,WAAW,EAAE;AACzB,yBAAmB,UAAU,WAAW;AACxC;AAAA,IACF;AAEA,UAAM,gBAAgB,iBAAiB,WAAW,mBAAmB;AACrE,QAAI,YAAY,cAAe;AAE/B,QAAI,eAAe,SAAS;AAC1B,UAAI,CAAC,aAAa,eAAe,OAAO,GAAG;AACzC,wBAAgB,UAAU,CAAC;AAC3B,oBAAY,OAAO;AAAA,MACrB,OAAO;AACL,wBAAgB,QAAQ,KAAK,OAAO;AACpC,YAAI,gBAAgB,QAAQ,SAAS,GAAG;AACtC,0BAAgB,UAAU,gBAAgB,QAAQ,MAAM,EAAE;AAAA,QAC5D;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,OAAO,mBAAmB;AAChC,QAAI,CAAC,aAAa,MAAM,OAAO,GAAG;AAChC,kBAAY,OAAO;AACnB;AAAA,IACF;AACA,wBAAoB,MAAM,OAAO;AAEjC,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,SAAS,aAAa,mBAAmB,CAAC;AAEvD,QAAM,kBAAkB,eAAe;AAEvC,QAAM,uBAAmB,uBAAQ,MAAM;AACrC,QAAI,CAAC,WAAW,CAAC,QAAS,QAAO,WAAW;AAC5C,QAAI,gBAAiB,QAAO;AAC5B,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,SAAS,iBAAiB,eAAe,CAAC;AAEvD,QAAM,qBAAqB,kBAAkB,oBAAoB;AAEjE,SAAO,EAAE,kBAAkB,aAAa,mBAAmB,mBAAmB;AAChF;;;AExPO,IAAM,gBAAiC;AAAA,EAC5C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,UAAU;AAAA,EACV,QAAQ;AAAA,IACN,iBAAiB,UAAkB,YAAoB,WAA2B;AAChF,UAAI,aAAa,KAAK,WAAW,KAAK,EAAE,SAAS,EAAG,QAAO;AAC3D,UAAI,YAAY,YAAY,EAAG,QAAO;AACtC,UAAI,YAAY,KAAK,UAAU,EAAG,QAAO;AACzC,UAAI,+BAA+B,KAAK,UAAU,EAAG,QAAO;AAC5D,aAAO;AAAA,IACT;AAAA,IACA,eAAe,MAA6D;AAC1E,UAAI,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO;AACrC,YAAM,UAAU,KAAK,UAAU;AAC/B,YAAM,YAAY,QAAQ,MAAM,QAAQ;AACxC,UAAI,WAAW;AACb,cAAM,SAAS,UAAU,CAAC;AAC1B,cAAM,UAAU,KAAK,QAAQ,MAAM,IAAI,OAAO;AAC9C,cAAM,aAAa,KAAK,QAAQ,EAAE,MAAM,QAAQ;AAChD,YAAI,cAAc,WAAW,CAAC,MAAM,QAAQ;AAC1C,gBAAM,aAAa,KAAK,YAAY,WAAW,CAAC,CAAC;AACjD,iBAAO;AAAA,YACL,EAAE,MAAM,KAAK,UAAU,GAAG,OAAO,GAAG,YAAY,cAAc;AAAA,YAC9D,EAAE,MAAM,KAAK,UAAU,SAAS,UAAU,GAAG,YAAY,eAAe;AAAA,YACxE,EAAE,MAAM,KAAK,UAAU,UAAU,GAAG,YAAY,iBAAiB;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC,EAAE,MAAM,MAAM,YAAY,eAAe,CAAC;AAAA,IACpD;AAAA,EACF;AACF;;;ACnCO,IAAM,gBAAiC;AAAA,EAC5C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,UAAU;AAAA,EACV,QAAQ;AAAA,IACN,iBAAiB,UAAkB,YAAoB,WAA2B;AAEhF,UAAI,aAAa,KAAK,WAAW,KAAK,EAAE,SAAS,EAAG,QAAO;AAC3D,UAAI,YAAY,YAAY,EAAG,QAAO;AACtC,UAAI,gBAAgB,KAAK,UAAU,KAAK,YAAY,KAAK,UAAU,EAAG,QAAO;AAC7E,UAAI,kBAAkB,KAAK,UAAU,KAAK,OAAO,KAAK,UAAU,EAAG,QAAO;AAC1E,UAAI,iBAAiB,KAAK,UAAU,EAAG,QAAO;AAC9C,aAAO;AAAA,IACT;AAAA,IACA,eAAe,MAA6D;AAC1E,UAAI,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO;AAErC,YAAM,UAAU,KAAK,UAAU;AAC/B,YAAM,YAAY,QAAQ,MAAM,QAAQ;AACxC,UAAI,WAAW;AACb,cAAM,SAAS,UAAU,CAAC;AAC1B,cAAM,UAAU,KAAK,QAAQ,MAAM,IAAI,OAAO;AAC9C,cAAM,aAAa,KAAK,QAAQ,EAAE,MAAM,QAAQ;AAChD,YAAI,cAAc,WAAW,CAAC,MAAM,QAAQ;AAC1C,gBAAM,aAAa,KAAK,YAAY,WAAW,CAAC,CAAC;AACjD,iBAAO;AAAA,YACL,EAAE,MAAM,KAAK,UAAU,GAAG,OAAO,GAAG,YAAY,cAAc;AAAA,YAC9D,EAAE,MAAM,KAAK,UAAU,SAAS,UAAU,GAAG,YAAY,eAAe;AAAA,YACxE,EAAE,MAAM,KAAK,UAAU,UAAU,GAAG,YAAY,iBAAiB;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC,EAAE,MAAM,MAAM,YAAY,eAAe,CAAC;AAAA,IACpD;AAAA,EACF;AACF;;;ACtCO,IAAM,YAA6B;AAAA,EACxC,UAAU;AAAA,EACV,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,UAAU;AAAA,EACV,QAAQ;AAAA,IACN,iBAAiB,WAAmB,aAAqB,YAA4B;AAGnF,aAAO;AAAA,IACT;AAAA,IACA,eAAe,OAA8D;AAE3E,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AClBO,IAAM,gBAAiC;AAAA,EAC5C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,UAAU;AAAA,EACV,QAAQ;AAAA,IACN,iBAAiB,UAAkB,YAAoB,WAA2B;AAEhF,UAAI,aAAa,KAAK,WAAW,KAAK,EAAE,SAAS,EAAG,QAAO;AAC3D,UAAI,YAAY,YAAY,EAAG,QAAO;AACtC,UAAI,gBAAgB,KAAK,UAAU,KAAK,YAAY,KAAK,UAAU,EAAG,QAAO;AAC7E,aAAO;AAAA,IACT;AAAA,IACA,eAAe,MAA6D;AAC1E,UAAI,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO;AACrC,aAAO,CAAC,EAAE,MAAM,MAAM,YAAY,eAAe,CAAC;AAAA,IACpD;AAAA,EACF;AACF;;;AChBA,IAAM,WAAsD;AAAA,EAC1D,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,QAAQ;AACV;AAKO,SAAS,mBAAmB,UAA8C;AAC/E,SAAO,SAAS,YAAY,QAAQ;AACtC;;;AClBA,IAAAC,gBAAmD;AA0D3C;AAzCD,SAAS,mBAAmB;AAAA,EACjC,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ;AAAA,EACA,SAAS;AACX,GAA4B;AAC1B,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,CAAC;AAC5C,QAAM,kBAAc,sBAA8C,IAAI;AAEtE,+BAAU,MAAM;AACd,gBAAY,UAAU,YAAY,MAAM;AACtC,mBAAa,UAAQ;AACnB,YAAI,QAAQ,UAAU,QAAQ;AAC5B,cAAI,YAAY,QAAS,eAAc,YAAY,OAAO;AAC1D,iBAAO;AAAA,QACT;AACA,eAAO,OAAO;AAAA,MAChB,CAAC;AAAA,IACH,GAAG,SAAS;AACZ,WAAO,MAAM;AACX,UAAI,YAAY,QAAS,eAAc,YAAY,OAAO;AAAA,IAC5D;AAAA,EACF,GAAG,CAAC,WAAW,SAAS,CAAC;AAEzB,QAAM,YAAY,UAAU,UAAU,GAAG,SAAS;AAElD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,QAAQ,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,QACrD,iBAAiB;AAAA,QACjB,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,MAEA,uDAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,OAAO,GAC9D;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,eAAe;AAAA,cACf,OAAO;AAAA,cACP,YAAY;AAAA,cACZ,QAAQ;AAAA,YACV;AAAA,YAEC;AAAA;AAAA,cACD;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,eAAe;AAAA,oBACf,YAAY;AAAA,kBACd;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;;;AChFE,IAAAC,sBAAA;AADK,IAAM,eAAe,CAAC,EAAE,OAAO,GAAG,MACvC,8CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACzI;AAAA,+CAAC,cAAS,QAAO,kBAAiB;AAAA,EAAE,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,GAC5E;AAGK,IAAM,WAAW,CAAC,EAAE,OAAO,IAAI,WAAW,OAAO,EAAE,MACxD,8CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,WAAsB,OAAO,GAC9K;AAAA,+CAAC,UAAK,GAAE,gCAA+B;AAAA,EAAE,6CAAC,UAAK,GAAE,+BAA8B;AAAA,EAAE,6CAAC,UAAK,GAAE,gCAA+B;AAAA,EAAE,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ,IAAG,MAAK;AAAA,GACrK;AAGK,IAAM,cAAc,CAAC,EAAE,OAAO,IAAI,WAAW,OAAO,EAAE,MAC3D,8CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,WAAsB,OAAO,GAC9K;AAAA,+CAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,EAAE,6CAAC,UAAK,GAAE,2CAA0C;AAAA,EAAE,6CAAC,UAAK,GAAE,wCAAuC;AAAA,EAAE,6CAAC,UAAK,GAAE,mCAAkC;AAAA,EAAE,6CAAC,UAAK,GAAE,sCAAqC;AAAA,EAAE,6CAAC,UAAK,GAAE,gCAA+B;AAAA,EAAE,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ,IAAG,MAAK;AAAA,GAC1T;AAGK,IAAM,oBAAoB,CAAC,EAAE,OAAO,GAAG,MAC5C,8CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACzI;AAAA,+CAAC,UAAK,GAAE,4FAA2F;AAAA,EAAE,6CAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK;AAAA,EAAE,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ,IAAG,MAAK;AAAA,GACvL;AAGK,IAAM,cAAc,CAAC,EAAE,OAAO,IAAI,UAAU,MACjD,8CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,WACjJ;AAAA,+CAAC,cAAS,QAAO,oBAAmB;AAAA,EAAE,6CAAC,cAAS,QAAO,kBAAiB;AAAA,EAAE,6CAAC,UAAK,GAAE,wEAAuE;AAAA,GAC3J;AAGK,IAAM,UAAU,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,MAC5C,6CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,OAAO,GACxJ,uDAAC,UAAK,GAAE,2HAA0H,GACpI;AAGK,IAAM,WAAW,CAAC,EAAE,OAAO,GAAG,MACnC,8CAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACzI;AAAA,+CAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK;AAAA,EAAE,6CAAC,UAAK,GAAE,wCAAuC;AAAA,EAAE,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,SAAQ,IAAG,MAAK;AAAA,GAC7H;AAGK,IAAM,eAAe,MAC1B,6CAAC,SAAI,OAAO,IAAI,QAAQ,IAAI,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAC5F,uDAAC,UAAK,GAAE,2CAA0C,GACpD;;;AC/CF,IAAAC,gBAAgC;AAmFxB,IAAAC,sBAAA;AA/ER,IAAM,mBAAiE;AAAA,EACrE,EAAE,OAAO,UAAU,OAAO,iBAAiB;AAAA,EAC3C,EAAE,OAAO,UAAU,OAAO,qBAAqB;AAAA,EAC/C,EAAE,OAAO,MAAM,OAAO,QAAQ;AAAA,EAC9B,EAAE,OAAO,UAAU,OAAO,oBAAoB;AAChD;AAGA,IAAM,wBAA+F;AAAA,EACnG,QAAQ;AAAA,IACN,EAAE,OAAO,cAAc,OAAO,wBAAqB;AAAA,IACnD,EAAE,OAAO,eAAe,OAAO,qBAAkB;AAAA,EACnD;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,OAAO,cAAc,OAAO,uBAAoB;AAAA,IAClD,EAAE,OAAO,cAAc,OAAO,uBAAoB;AAAA,IAClD,EAAE,OAAO,cAAc,OAAO,uBAAoB;AAAA,IAClD,EAAE,OAAO,cAAc,OAAO,wBAAqB;AAAA,EACrD;AACF;AASO,SAAS,aAAa,EAAE,iBAAiB,SAAS,iBAAiB,OAAO,UAAU,GAAsB;AAC/G,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAS,EAAE;AACnC,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAS,EAAE;AACnC,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,wBAA2B,eAAe;AAC1F,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAS,EAAE;AACnD,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,EAAE;AAC3C,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,EAAE;AAE3C,QAAM,kBAAkB,sBAAsB,gBAAgB;AAC9D,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAEhD,QAAM,UAAU,mBAAmB;AAEnC,QAAM,eAAe,CAAC,MAAuB;AAC3C,MAAE,eAAe;AACjB,iBAAa,IAAI;AACjB,cAAU;AAAA,MACR;AAAA,MACA,MAAM,OAAO,SAAS,MAAM,EAAE,IAAI;AAAA,MAClC,UAAU;AAAA,MACV,GAAI,SAAS,KAAK,IAAI,EAAE,UAAU,SAAS,KAAK,EAAE,IAAI,CAAC;AAAA,MACvD,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,IACzC,CAAC;AAAA,EACH;AAEA,QAAM,aAAkC;AAAA,IACtC,OAAO;AAAA,IACP,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AAEA,QAAM,aAAkC;AAAA,IACtC,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU;AAAA,IACV,eAAe;AAAA,IACf,eAAe;AAAA,IACf,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AAEA,MAAI,SAAS;AACX,WACE,8CAAC,SAAI,WAAU,aAAY,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,gBAAgB,UAAU,KAAK,OAAO,GACxI;AAAA,mDAAC,eAAY,MAAM,IAAI,WAAU,WAAU;AAAA,MAC3C,8CAAC,SAAI,OAAO,EAAE,UAAU,QAAQ,eAAe,UAAU,eAAe,aAAa,OAAO,mBAAmB,YAAY,iBAAiB,GAAG;AAAA;AAAA,QAC9H,QAAQ;AAAA,QAAO;AAAA,SAChC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,8CAAC,UAAK,UAAU,cAAc,WAAU,aACtC;AAAA,kDAAC,SAAI,OAAO,EAAE,WAAW,UAAU,cAAc,OAAO,GACtD;AAAA,mDAAC,gBAAa,MAAM,IAAI;AAAA,MACxB,6CAAC,SAAI,OAAO,EAAE,UAAU,QAAQ,eAAe,UAAU,eAAe,aAAa,OAAO,mBAAmB,WAAW,MAAM,GAAG,6BAAe;AAAA,OACpJ;AAAA,IAEA,8CAAC,SAAI,WAAU,iBACb;AAAA,oDAAC,SAAI,OAAO,EAAE,MAAM,EAAE,GACpB;AAAA,sDAAC,WAAM,OAAO,YAAY;AAAA;AAAA,UAAK,6CAAC,UAAK,OAAO,EAAE,OAAO,UAAU,GAAG,eAAC;AAAA,WAAO;AAAA,QAC1E,6CAAC,WAAM,OAAO,YAAY,OAAO,MAAM,UAAU,OAAK,QAAQ,EAAE,OAAO,KAAK,GAAG,aAAY,iBAAgB,UAAQ,MAAC,WAAS,MAAC;AAAA,SAChI;AAAA,MACA,8CAAC,SAAI,OAAO,EAAE,OAAO,OAAO,GAC1B;AAAA,qDAAC,WAAM,OAAO,YAAY,kBAAI;AAAA,QAC9B,6CAAC,WAAM,OAAO,YAAY,OAAO,MAAM,UAAU,OAAK,QAAQ,EAAE,OAAO,KAAK,GAAG,aAAY,MAAK,MAAK,UAAS,KAAI,KAAI,KAAI,SAAQ;AAAA,SACpI;AAAA,OACF;AAAA,IAEA,8CAAC,SACC;AAAA,oDAAC,WAAM,OAAO,YAAY;AAAA;AAAA,QAAS,6CAAC,UAAK,OAAO,EAAE,OAAO,UAAU,GAAG,eAAC;AAAA,SAAO;AAAA,MAC9E,6CAAC,YAAO,OAAO,EAAE,GAAG,YAAY,YAAY,OAAO,GAAG,OAAO,kBAAkB,UAAU,OAAK;AAAE,4BAAoB,EAAE,OAAO,KAAyB;AAAG,wBAAgB,EAAE;AAAA,MAAG,GAC3K,2BAAiB,IAAI,OAAK,6CAAC,YAAqB,OAAO,EAAE,OAAQ,YAAE,SAA5B,EAAE,KAAgC,CAAS,GACrF;AAAA,OACF;AAAA,IAEC,mBAAmB,gBAAgB,SAAS,KAC3C,8CAAC,SACC;AAAA,mDAAC,WAAM,OAAO,YAAY,yBAAW;AAAA,MACrC,6CAAC,YAAO,OAAO,EAAE,GAAG,YAAY,YAAY,OAAO,GAAG,OAAO,gBAAgB,gBAAgB,CAAC,EAAE,OAAO,UAAU,OAAK,gBAAgB,EAAE,OAAO,KAAK,GACjJ,0BAAgB,IAAI,OAAK,6CAAC,YAAqB,OAAO,EAAE,OAAQ,YAAE,SAA5B,EAAE,KAAgC,CAAS,GACpF;AAAA,OACF;AAAA,IAGF,8CAAC,SACC;AAAA,mDAAC,WAAM,OAAO,YAAY,sBAAQ;AAAA,MAClC,6CAAC,WAAM,OAAO,YAAY,OAAO,UAAU,UAAU,OAAK,YAAY,EAAE,OAAO,KAAK,GAAG,cAAa,YAAW;AAAA,OACjH;AAAA,IAEA,8CAAC,SACC;AAAA,mDAAC,WAAM,OAAO,YAAY,sBAAQ;AAAA,MAClC,6CAAC,WAAM,OAAO,YAAY,MAAK,YAAW,OAAO,UAAU,UAAU,OAAK,YAAY,EAAE,OAAO,KAAK,GAAG,cAAa,oBAAmB;AAAA,OACzI;AAAA,IAEC,SACC,8CAAC,SAAI,OAAO,EAAE,OAAO,WAAW,UAAU,QAAQ,YAAY,kBAAkB,SAAS,QAAQ,YAAY,UAAU,KAAK,MAAM,GAChI;AAAA,mDAAC,qBAAkB,MAAM,IAAI;AAAA,MAC7B,6CAAC,UAAM,iBAAM;AAAA,OACf;AAAA,IAGF,6CAAC,YAAO,MAAK,UAAS,UAAU,CAAC,MAAM,WAAU,iBAAgB,qBAEjE;AAAA,KACF;AAEJ;;;AbyXiD,IAAAC,sBAAA;AA/fjD,IAAM,aAAa,EAAE,SAAS,OAAO,OAAO,wBAAwB;AACpE,IAAM,cAA+B;AAAA,EACnC,WAAW,YAAY;AAAA,EACvB,WAAW,aAAa,EAAE,WAAW,OAAO,QAAQ,eAAe;AAAA,EACnE,UAAU,YAAY;AAAA,EACtB,SAAS,YAAY;AAAA,EACrB,WAAW,YAAY;AAAA,EACvB,SAAS,YAAY;AAAA,EACrB,YAAY,YAAY;AAAA,EACxB,WAAW,YAAY;AACzB;AAuFO,SAAS,oBAAoB;AAAA,EAClC,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,eAAe;AAAA,EACf,eAAe,uBAAuB;AAAA,EACtC,sBAAsB,cAAc;AAAA,EACpC,WAAW;AAAA,EACX,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA6B;AAC3B,QAAM,UAAU,iBAAiB,mBAAmB,QAAQ;AAG5D,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,wBAAiC,IAAI;AACnF,QAAM,qBAAiB;AAAA,IACrB,MAAM,UAAU,IAAI,YAAY,EAAE,QAAQ,CAAC,IAAI;AAAA,IAC/C,CAAC,OAAO;AAAA,EACV;AACA,QAAM,uBAAmB;AAAA,IACvB,MAAM,YAAY,IAAI,iBAAiB,EAAE,UAAU,CAAC,IAAI;AAAA,IACxD,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,uBAAmB;AAAA,IACvB,MAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,YAAa,IAAI,iBAAiB,IAAI;AAAA,IAC9E,CAAC,iBAAiB,SAAS,SAAS;AAAA,EACtC;AACA,QAAM,UAAU,mBAAmB,kBAAkB,oBAAoB,mBAAmB,oBAAoB;AAChH,QAAM,wBAAwB,YAAY;AAG1C,QAAM,aAAa,eAAe,KAAK,CAAC;AACxC,QAAM,EAAE,MAAM,kBAAkB,OAAO,YAAY,IAAI,kBAAkB,SAAS,cAAc,UAAU;AAC1G,QAAM,EAAE,UAAU,WAAW,SAAS,SAAS,IAAI,iBAAiB,OAAO;AAC3E,QAAM,EAAE,SAAS,WAAW,SAAS,cAAc,OAAO,aAAa,IAAI,sBAAsB,OAAO;AAExG,QAAM,gBAAgB,sBAAsB;AAE5C,QAAM,aAAa,mBAAmB,gBAAgB,EAAE,WAAW,MAAM,QAAQ,gBAAyB,IAAI,EAAE,WAAW,OAAO,QAAQ,eAAwB;AAGlK,QAAM,EAAE,kBAAkB,kBAAkB,IAAI;AAAA,IAC9C,eAAe;AAAA,IACf;AAAA,IACA;AAAA,EACF;AAEA,QAAM,iBAAa,uBAAQ,MAAM;AAC/B,QAAI,CAAC,cAAe,QAAO;AAC3B,WAAO,EAAE,GAAG,eAAe,SAAS,iBAAiB;AAAA,EACvD,GAAG,CAAC,eAAe,gBAAgB,CAAC;AAGpC,QAAM,uBAAmB,sBAA2B,MAAS;AAC7D,+BAAU,MAAM;AACd,QAAI,cAAc,kBAAkB,WAAW,qBAAqB,iBAAiB,SAAS;AAC5F,uBAAiB,UAAU,WAAW;AACtC,qBAAe,UAAU;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,YAAY,cAAc,CAAC;AAE/B,QAAM,eAAW,2BAAY,OAAO,SAAiB,UAAU,IAAI,GAAG,CAAC,SAAS,CAAC;AACjF,QAAM,cAAU,2BAAY,OAAO,QAAgB,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC;AAK5E,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,wBAA0D,CAAC,CAAC;AAC1G,QAAM,gCAA4B,sBAA2B,MAAS;AACtE,+BAAU,MAAM;AAId,UAAM,UAAU,eAAe;AAC/B,QAAI,WAAW,YAAY,0BAA0B,SAAS;AAC5D,gCAA0B,UAAU;AACpC,yBAAmB,CAAC,CAAC;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,eAAe,OAAO,CAAC;AAG3B,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,EAAE;AAC7C,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAC1D,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAS,KAAK;AACxD,QAAM,uBAAmB,sBAAO,KAAK;AACrC,+BAAU,MAAM;AACd,QAAI,gBAAgB,CAAC,iBAAiB,QAAS,mBAAkB,IAAI;AACrE,qBAAiB,UAAU,CAAC,CAAC;AAAA,EAC/B,GAAG,CAAC,YAAY,CAAC;AACjB,QAAM,kBAAc,sBAAuB,IAAI;AAC/C,QAAM,eAAW,sBAAyB,IAAI;AAC9C,QAAM,CAAC,cAAc,eAAe,QAAI,wBAA8C,IAAI;AAC1F,QAAM,wBAAoB,sBAAO,EAAE;AAEnC,+BAAU,MAAM;AACd,UAAM,aAAa,eAAe,WAAW;AAC7C,QAAI,kBAAkB,WAAW,cAAc,eAAe,kBAAkB,SAAS;AACvF,sBAAgB,IAAI;AACpB,mBAAa,EAAE;AACf,UAAI,eAAgB,mBAAkB,KAAK;AAAA,IAC7C;AACA,sBAAkB,UAAU;AAAA,EAC9B,GAAG,CAAC,eAAe,OAAO,CAAC;AAG3B,QAAM,CAAC,sBAAsB,uBAAuB,QAAI,wBAAS,CAAC;AAClE,QAAM,CAAC,oBAAoB,qBAAqB,QAAI,wBAAS,KAAK;AAClE,QAAM,0BAAsB,sBAA6C,IAAI;AAC7E,QAAM,sBAAkB,sBAAO,KAAK;AACpC,QAAM,qBAAiB,sBAAO,KAAK;AAEnC,+BAAU,MAAM;AAAE,mBAAe,UAAU,YAAY,aAAa;AAAA,EAAO,GAAG,CAAC,YAAY,SAAS,CAAC;AAErG,+BAAU,MAAM;AACd,QAAI,CAAC,qBAAsB;AAC3B,UAAM,cAAc,YAAY;AAEhC,QAAI,aAAa;AACf,sBAAgB,UAAU;AAC1B,UAAI,oBAAoB,SAAS;AAAE,qBAAa,oBAAoB,OAAO;AAAG,4BAAoB,UAAU;AAAA,MAAM;AAClH,8BAAwB,CAAC;AACzB,4BAAsB,KAAK;AAAA,IAC7B,WAAW,gBAAgB,WAAW,CAAC,eAAe,CAAC,sBAAsB,CAAC,cAAc;AAC1F,UAAI,uBAAuB,aAAa;AACtC,8BAAsB,IAAI;AAC1B,cAAM,QAAQ,KAAK,IAAI,GAAG,oBAAoB,IAAI;AAClD,4BAAoB,UAAU,WAAW,YAAY;AACnD,cAAI,eAAe,SAAS;AAAE,kCAAsB,KAAK;AAAG;AAAA,UAAQ;AACpE,2BAAiB,0BAA0B,uBAAuB,CAAC,IAAI,WAAW,IAAI,MAAM;AAC5F,cAAI;AACF,kBAAM,SAAS,MAAM,UAAU;AAC/B,gBAAI,CAAC,QAAQ,QAAS,yBAAwB,UAAQ,OAAO,CAAC;AAAA,UAChE,QAAQ;AACN,6BAAiB,yBAAyB,OAAO;AACjD,oCAAwB,UAAQ,OAAO,CAAC;AAAA,UAC1C;AACA,gCAAsB,KAAK;AAAA,QAC7B,GAAG,KAAK;AAAA,MACV;AAAA,IACF;AACA,WAAO,MAAM;AAAE,UAAI,oBAAoB,QAAS,cAAa,oBAAoB,OAAO;AAAA,IAAG;AAAA,EAC7F,GAAG,CAAC,YAAY,WAAW,sBAAsB,oBAAoB,cAAc,WAAW,sBAAsB,aAAa,cAAc,CAAC;AAGhJ,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,KAAK;AAClD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAwB,IAAI;AAClE,QAAM,mBAAe,2BAAY,OAAO,WAA0B;AAEhE,QAAI,UAAU;AACZ,eAAS,MAAM;AACf;AAAA,IACF;AACA,kBAAc,IAAI;AAClB,mBAAe,IAAI;AACnB,QAAI;AAEF,UAAI,CAAC,mBAAmB,CAAC,gBAAgB;AACvC,cAAM,OAAO,OAAO,OAAO,IAAI,OAAO,IAAI,KAAK;AAC/C,cAAM,aAAa,IAAI,YAAY,EAAE,SAAS,UAAU,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC;AAC9E,2BAAmB,UAAU;AAC7B,cAAM,WAAW,QAAQ,MAAM;AAC/B,YAAI,OAAO,YAAY,OAAO,SAAU,mBAAkB,IAAI;AAC9D;AAAA,MACF;AACA,YAAM,QAAQ,MAAM;AACpB,UAAI,OAAO,YAAY,OAAO,SAAU,mBAAkB,IAAI;AAAA,IAChE,SAAS,KAAK;AACZ,qBAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC/D,oBAAc,KAAK;AAAA,IACrB;AAAA,EAGF,GAAG,CAAC,SAAS,UAAU,iBAAiB,cAAc,CAAC;AAGvD,+BAAU,MAAM;AACd,QAAI,cAAc,YAAY,QAAS,eAAc,KAAK;AAAA,EAC5D,GAAG,CAAC,YAAY,YAAY,OAAO,CAAC;AAGpC,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,eAAe,KAAK;AACzE,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAS,KAAK;AAExD,+BAAU,MAAM;AACd,QAAI,CAAC,eAAgB;AAGrB,UAAM,gBAAgB,oBAAoB,SACtC,kBACA,CAAC,CAAC,YAAY;AAClB,QAAI,eAAe;AACjB,uBAAiB,IAAI;AACrB,wBAAkB,KAAK;AACvB,YAAM,QAAQ,WAAW,MAAM,iBAAiB,KAAK,GAAG,GAAG;AAC3D,aAAO,MAAM,aAAa,KAAK;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,YAAY,SAAS,gBAAgB,eAAe,CAAC;AAGzD,QAAM,oBAAoB;AAG1B,+BAAU,MAAM;AACd,QAAI,CAAC,qBAAqB,CAAC,UAAU;AACnC,UAAI;AACF,YAAI,aAAa,QAAQ,iBAAiB,MAAM,QAAQ;AACtD,uBAAa,IAAI;AAAA,QACnB;AAAA,MACF,QAAQ;AAAA,MAAiC;AAAA,IAC3C;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,+BAAU,MAAM;AACd,QAAI,kBAAmB;AACvB,QAAI;AAAE,mBAAa,QAAQ,mBAAmB,OAAO,SAAS,CAAC;AAAA,IAAG,QAAQ;AAAA,IAAa;AAAA,EACzF,GAAG,CAAC,WAAW,iBAAiB,CAAC;AAGjC,+BAAU,MAAM;AACd,QAAI,UAAW,UAAS,SAAS,MAAM;AAAA,EACzC,GAAG,CAAC,SAAS,CAAC;AAGd,QAAM,oBAAgB,sBAAO,KAAK;AAClC,+BAAU,MAAM;AACd,QAAI,YAAY,WAAW,CAAC,cAAc,WAAW,CAAC,qBAAqB,CAAC,UAAU;AACpF,oBAAc,UAAU;AACxB,mBAAa,IAAI;AAAA,IACnB;AACA,QAAI,CAAC,YAAY,QAAS,eAAc,UAAU;AAAA,EACpD,GAAG,CAAC,YAAY,SAAS,mBAAmB,QAAQ,CAAC;AAErD,+BAAU,MAAM;AACd,UAAM,qBAAqB,CAAC,UAAsB;AAChD,UAAI,YAAY,WAAW,CAAC,YAAY,QAAQ,SAAS,MAAM,MAAc,EAAG,cAAa,KAAK;AAAA,IACpG;AACA,QAAI,UAAW,UAAS,iBAAiB,aAAa,kBAAkB;AACxE,WAAO,MAAM,SAAS,oBAAoB,aAAa,kBAAkB;AAAA,EAC3E,GAAG,CAAC,SAAS,CAAC;AAEd,+BAAU,MAAM;AACd,QAAI,YAAY,WAAW;AAAE,mBAAa,KAAK;AAAG,eAAS,SAAS,KAAK;AAAA,IAAG;AAAA,EAC9E,GAAG,CAAC,UAAU,SAAS,CAAC;AAExB,QAAM,uBAAmB,sBAAuB,IAAI;AACpD,QAAM,mBAAe,sBAAe,CAAC;AAErC,QAAM,0BAAsB,2BAAY,CAAC,MAAwC;AAC/E,QAAI,SAAU;AACd,iBAAa,IAAI;AACjB,aAAS,SAAS,MAAM;AAGxB,UAAM,YAAY,iBAAiB;AACnC,QAAI,CAAC,aAAa,CAAC,YAAY,OAAQ;AAGvC,QAAI,CAAC,aAAa,SAAS;AACzB,YAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,WAAK,MAAM,UAAU;AACrB,WAAK,cAAc;AACnB,gBAAU,YAAY,IAAI;AAC1B,mBAAa,UAAU,KAAK,sBAAsB,EAAE;AACpD,gBAAU,YAAY,IAAI;AAAA,IAC5B;AAEA,UAAM,OAAO,UAAU,sBAAsB;AAC7C,UAAM,IAAI,EAAE,UAAU,KAAK;AAC3B,UAAM,IAAI,EAAE,UAAU,KAAK;AAC3B,UAAM,aAAa;AACnB,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,UAAW;AAEhB,UAAM,aAAa,KAAK,MAAM,IAAI,UAAU;AAC5C,UAAM,aAAa,KAAK,MAAM,IAAI,SAAS;AAE3C,QAAI,aAAa,KAAK,eAAe,WAAW,QAAQ,OACpD,aAAa,KAAK,eAAe,WAAW,QAAQ,IAAK;AAG7D,oBAAgB,EAAE,KAAK,YAAY,KAAK,WAAW,CAAC;AACpD,YAAQ,YAAY,YAAY,UAAU,EAAE,KAAK,OAAK;AACpD,UAAI,GAAG,eAAe,QAAW;AAC/B,wBAAgB,EAAE,KAAK,EAAE,YAAY,KAAK,EAAE,WAAY,CAAC;AAAA,MAC3D;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,YAAY,OAAO,CAAC;AAGlC,QAAM,sBAAkB,2BAAY,MAAM;AACxC,UAAM,SAAS,YAAY,UAAU,CAAC;AACtC,UAAM,YAAY,cAAc,OAAO,YAAY,cAAc;AACjE,UAAM,YAAY,cAAc,OAAO,YAAY,cAAc;AACjE,eAAW,SAAS,QAAQ;AAC1B,UAAI,MAAM,YAAY,MAAM,QAAQ,aAAa,aAAa,MAAM,OAAO,YAAY,MAAM,MAAM,MAAM,OAAQ,QAAO;AAAA,IAC1H;AACA,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,YAAY,CAAC;AAM7B,QAAM,gBAAgB,OAAO,MAA2B;AACtD,QAAI,UAAU;AAAE,QAAE,eAAe;AAAG;AAAA,IAAQ;AAE5C,QAAI,EAAE,QAAQ,UAAU;AAAE,QAAE,eAAe;AAAG,mBAAa,KAAK;AAAG,eAAS,SAAS,KAAK;AAAG;AAAA,IAAQ;AAGrG,QAAI,EAAE,WAAW,EAAE,QAAQ,KAAK;AAC9B,QAAE,eAAe;AACjB,YAAM,KAAK,MAAM,QAAQ,OAAO;AAChC,UAAI,GAAG,eAAe,OAAW,iBAAgB,EAAE,KAAK,GAAG,YAAY,KAAK,GAAG,WAAY,CAAC;AAC5F;AAAA,IACF;AAGA,QAAI,EAAE,WAAW,EAAE,QAAQ,SAAS;AAClC,QAAE,eAAe;AACjB,YAAM,KAAK,MAAM,QAAQ,YAAY;AACrC,UAAI,GAAG,eAAe,OAAW,iBAAgB,EAAE,KAAK,GAAG,YAAY,KAAK,GAAG,WAAY,CAAC;AAC5F;AAAA,IACF;AAEA,UAAM,SAAiC;AAAA,MACrC,OAAO;AAAA,MAAS,KAAK;AAAA,MAAO,WAAW;AAAA,MAAa,QAAQ;AAAA,MAC5D,SAAS;AAAA,MAAM,WAAW;AAAA,MAAQ,WAAW;AAAA,MAAQ,YAAY;AAAA,MACjE,QAAQ;AAAA,MAAU,UAAU;AAAA,MAAY,MAAM;AAAA,MAAQ,KAAK;AAAA,MAAO,QAAQ;AAAA,IAC5E;AAGA,QAAI,EAAE,IAAI,WAAW,GAAG,KAAK,EAAE,IAAI,UAAU,GAAG;AAC9C,QAAE,eAAe;AACjB,YAAM,OAAO,EAAE,IAAI,YAAY;AAC/B,UAAI,2BAA2B,KAAK,IAAI,GAAG;AACzC,cAAM,KAAK,MAAM,QAAQ,IAAI;AAC7B,YAAI,GAAG,eAAe,OAAW,iBAAgB,EAAE,KAAK,GAAG,YAAY,KAAK,GAAG,WAAY,CAAC;AAC5F;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,EAAE,GAAG,GAAG;AACjB,QAAE,eAAe;AACjB,YAAM,KAAK,MAAM,QAAQ,OAAO,EAAE,GAAG,CAAC;AACtC,UAAI,GAAG,eAAe,OAAW,iBAAgB,EAAE,KAAK,GAAG,YAAY,KAAK,GAAG,WAAY,CAAC;AAAA,IAC9F;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,MAA2C;AACpE,QAAI,UAAU;AAAE,QAAE,OAAO,QAAQ;AAAI;AAAA,IAAQ;AAC7C,UAAM,UAAU,EAAE,OAAO;AACzB,QAAI,QAAQ,SAAS,UAAU,QAAQ;AACrC,YAAM,WAAW,QAAQ,UAAU,UAAU,MAAM;AAEnD,YAAM,SAAS,cAAc,OAAO,YAAY,cAAc;AAC9D,YAAM,SAAS,cAAc,OAAO,YAAY,cAAc;AAC9D,YAAM,QAAyD,CAAC;AAChE,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,cAAM,KAAK,EAAE,KAAK,QAAQ,KAAK,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC;AAAA,MAC9D;AACA,yBAAmB,UAAQ,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC;AAC9C,sBAAgB,EAAE,KAAK,QAAQ,KAAK,SAAS,SAAS,OAAO,CAAC;AAE9D,eAAS,QAAQ,EAAE,KAAK,OAAK;AAC3B,YAAI,EAAE,eAAe,OAAW,iBAAgB,EAAE,KAAK,EAAE,YAAY,KAAK,EAAE,WAAY,CAAC;AAAA,MAC3F,CAAC;AAAA,IACH;AACA,iBAAa,EAAE;AACf,MAAE,OAAO,QAAQ;AAAA,EACnB;AAGA,QAAM,WAAW,YAAY,QAAQ,QAAQ;AAC7C,QAAM,eAAe,MAAM;AACzB,QAAI,kBAAmB,QAAO;AAC9B,QAAI,YAAY,cAAc,OAAO,YAAY,cAAc;AAC/D,QAAI,YAAY,cAAc,OAAO,YAAY,cAAc;AAC/D,WAAO,aAAa,UAAU;AAAE,mBAAa;AAAU,mBAAa;AAAA,IAAG;AACvE,WAAO,EAAE,KAAK,WAAW,KAAK,UAAU;AAAA,EAC1C;AAGA,QAAM,+BAA2B,2BAAY,CAAC,MAAc,cAAuC;AACjG,UAAM,kBAAkB;AACxB,UAAM,WAA8B,CAAC;AACrC,QAAI,YAAY;AAChB,QAAI;AACJ,QAAI,eAAe;AACnB,YAAQ,QAAQ,gBAAgB,KAAK,IAAI,OAAO,MAAM;AACpD,UAAI,MAAM,QAAQ,UAAW,UAAS,KAAK,6CAAC,UAA6C,eAAK,UAAU,WAAW,MAAM,KAAK,KAAxE,GAAG,SAAS,MAAM,YAAY,EAA4C,CAAO;AACvI,YAAM,QAAQ,MAAM,CAAC,EAAE;AACvB,eAAS,KAAK,6CAAC,UAA4C,OAAO,EAAE,cAAc,sCAAsC,SAAS,gBAAgB,OAAO,GAAG,KAAK,KAAK,GAAI,cAAI,OAAO,KAAK,KAAhK,GAAG,SAAS,MAAM,YAAY,EAAoI,CAAO;AAClM,kBAAY,MAAM,QAAQ,MAAM,CAAC,EAAE;AACnC;AAAA,IACF;AACA,QAAI,YAAY,KAAK,OAAQ,UAAS,KAAK,6CAAC,UAA6B,eAAK,UAAU,SAAS,KAA3C,GAAG,SAAS,IAAiC,CAAO;AAC1G,WAAO,SAAS,SAAS,IAAI,6EAAG,oBAAS,IAAM,6EAAG,gBAAK;AAAA,EACzD,GAAG,CAAC,CAAC;AAEL,QAAM,0BAAsB,2BAAY,CAAC,MAAc,UAAkB,WAAqC;AAC5G,UAAM,cAAc,OAAO,OAAO,OAAK,EAAE,QAAQ,YAAY,EAAE,QAAQ;AACvE,UAAM,oBAAoB,OAAO,OAAO,OAAK,EAAE,QAAQ,YAAY,EAAE,gBAAgB,EAAE,cAAc;AACrG,UAAM,gBAAgB,OAAO,OAAO,OAAK,EAAE,QAAQ,YAAY,EAAE,gBAAgB,EAAE,UAAU;AAC7F,UAAM,cAAc,OAAO,OAAO,OAAK,EAAE,QAAQ,YAAY,EAAE,gBAAiB,EAAU,SAAS,CAAC,EAAE,kBAAkB,CAAC,EAAE,UAAU;AACrI,UAAM,eAAe,CAAC,GAAG,aAAa,GAAG,mBAAmB,GAAG,eAAe,GAAG,WAAW;AAE5F,QAAI,aAAa,WAAW,EAAG,QAAO,6CAAC,UAAM,gBAAK;AAElD,UAAM,SAAS,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;AAC7D,UAAM,OAA0B,CAAC;AACjC,QAAI,UAAU;AACd,UAAM,OAAO,YAAY,QAAQ,QAAQ;AAEzC,WAAO,QAAQ,CAAC,OAAO,QAAQ;AAC7B,YAAM,KAAK,MAAM;AACjB,YAAM,KAAK,KAAK,IAAI,MAAM,MAAM,MAAM,QAAQ,IAAI;AAClD,UAAI,KAAK,QAAS,MAAK,KAAK,6CAAC,UAAsB,eAAK,UAAU,SAAS,EAAE,KAAtC,IAAI,GAAG,EAAiC,CAAO;AACtF,YAAM,KAAK,KAAK,UAAU,IAAI,EAAE;AAGhC,YAAM,WAAY,MAAc,QAC5B,YAAa,MAAc,KAAK,uBAChC;AAEJ,UAAI,MAAM,UAAU;AAClB,cAAM,aAAa,KAAK,IAAI,MAAM,QAAQ,OAAO,EAAE;AACnD,cAAM,aAAa,iBAAiB,uBAAwB,MAAM,iBAAiB,mBAAmB;AACtG,aAAK,KAAK,6CAAC,UAAqB,WAAW,cAAc,QAAW,OAAO,EAAE,SAAS,gBAAgB,OAAO,GAAG,UAAU,MAAM,UAAU,UAAU,OAAO,SAAS,GAAI,gBAAnJ,IAAI,GAAG,EAA+I,CAAO;AAAA,MACpL,WAAW,MAAM,YAAY;AAC3B,aAAK,KAAK,6CAAC,UAAqB,OAAO,EAAE,OAAO,YAAY,0BAA0B,YAAY,OAAO,GAAI,gBAAxF,IAAI,GAAG,EAAoF,CAAO;AAAA,MACzH,WAAW,UAAU;AACnB,aAAK,KAAK,6CAAC,UAAqB,OAAO,EAAE,OAAO,SAAS,GAAI,gBAAxC,IAAI,GAAG,EAAoC,CAAO;AAAA,MACzE,WAAW,MAAM,gBAAgB;AAC/B,aAAK,KAAK,6CAAC,UAAqB,OAAO,EAAE,OAAO,2BAA2B,GAAI,gBAA1D,IAAI,GAAG,EAAsD,CAAO;AAAA,MAC3F,OAAO;AACL,aAAK,KAAK,6CAAC,UAAsB,gBAAZ,IAAI,GAAG,EAAQ,CAAO;AAAA,MAC7C;AACA,gBAAU;AAAA,IACZ,CAAC;AACD,QAAI,UAAU,KAAK,OAAQ,MAAK,KAAK,6CAAC,UAAe,eAAK,UAAU,OAAO,KAA5B,IAA8B,CAAO;AACpF,WAAO,6EAAG,gBAAK;AAAA,EACjB,GAAG,CAAC,0BAA0B,YAAY,MAAM,QAAQ,aAAa,cAAc,CAAC;AAGpF,QAAM,eAAe,MAAM;AACzB,QAAI,kBAAkB,CAAC,YAAY,SAAS;AAC1C,UAAI,eAAe,MAAO,QAAO;AACjC,UAAI,WAAY,QAAO,6EAAG,sBAAW;AACrC,aAAO,6CAAC,sBAAkB,WAAW,QAAQ,UAAU;AAAA,IACzD;AACA,QAAI,iBAAiB,YAAY,QAAS,QAAO,6CAAC,SAAI,WAAU,cAAc,8BAAoB,GAAE;AACpG,QAAI,CAAC,YAAY,SAAS;AACxB,UAAI,gBAAgB,CAAC,YAAY,WAAW;AAC1C,eACE,6CAAC,SAAI,OAAO,EAAE,OAAO,QAAQ,QAAQ,IAAI,YAAY,QAAQ,QAAQ,eAAe,EAAE,MAAM,SAAS,QAAQ,YAAY,UAAU,gBAAgB,SAAS,GAC1J,uDAAC,gBAAa,iBAAiB,yBAAyB,YAAY,UAAU,SAAS,cAAc,cAAc,OAAO,eAAe,cAAc,WAAW,cAAc,GAClL;AAAA,MAEJ;AACA,aACE,6CAAC,SAAI,OAAO,EAAE,OAAO,GAAG,YAAY,QAAQ,QAAQ,WAAW,MAAM,QAAQ,IAAI,YAAY,QAAQ,QAAQ,eAAe,EAAE,MAAM,SAAS,QAAQ,YAAY,UAAU,gBAAgB,SAAS,GAClM,wDAAC,SAAI,OAAO,EAAE,WAAW,SAAS,GAChC;AAAA,qDAAC,SAAI,OAAO,EAAE,OAAO,WAAW,cAAc,OAAO,GAAG,uDAAC,gBAAa,MAAM,IAAI,GAAE;AAAA,QAClF,6CAAC,OAAE,OAAO,EAAE,YAAY,kBAAkB,UAAU,QAAQ,OAAO,YAAY,WAAW,eAAe,YAAY,YAAY,WAAW,YAAY,YAAY,UAAU,GAC3K,sBAAY,YAAY,+BAA+B,YAAY,WAAW,eAAe,kBAAkB,YAAY,WAAW,YAAY,eAAe,iBACpK;AAAA,QACC,CAAC,YAAY,aAAa,yBACzB,8CAAC,OAAE,OAAO,EAAE,YAAY,kBAAkB,UAAU,QAAQ,OAAO,WAAW,WAAW,MAAM,GAAG;AAAA;AAAA,UAC/E,6CAAC,UAAK,OAAO,EAAE,OAAO,UAAU,GAAG,2CAA6B;AAAA,WACnF;AAAA,SAEJ,GACF;AAAA,IAEJ;AACA,WAAO,oBAAoB;AAAA,EAC7B;AAEA,QAAM,sBAAsB,MAAM;AAChC,QAAI,CAAC,YAAY,QAAS,QAAO;AACjC,UAAM,WAAW,WAAW,QAAQ,QAAQ;AAC5C,UAAM,OAAO,WAAW,QAAQ,QAAQ;AACxC,UAAM,QAAQ,WAAW,QAAQ,MAAM,IAAI;AAC3C,UAAM,OAAiB,CAAC;AACxB,aAAS,IAAI,GAAG,IAAI,UAAU,IAAK,MAAK,MAAM,MAAM,CAAC,KAAK,IAAI,OAAO,MAAM,GAAG,CAAC;AAE/E,UAAM,SAAS,WAAW,UAAU,CAAC;AACrC,UAAM,aAAa;AACnB,UAAM,SAAS,aAAa;AAC5B,UAAM,YAAY,WAAW,eAAe,UAAa,WAAW,eAAe;AAEnF,UAAM,qBAAqB,aAAa,OAAO;AAAA,MAAK,OAClD,EAAE,YAAY,CAAE,EAAU,kBAC1B,EAAE,QAAQ,OAAO,OACjB,OAAO,OAAO,EAAE,OAAO,OAAO,MAAM,EAAE,MAAM,EAAE;AAAA,IAChD;AAEA,WACE,8CAAC,SAAI,OAAO,EAAE,YAAY,kBAAkB,UAAU,QAAQ,UAAU,YAAY,OAAO,GAAG,IAAI,KAAK,GACpG;AAAA,WAAK,IAAI,CAAC,MAAM,UAAU;AAEzB,YAAI,cAAc;AAClB,cAAM,WAAW,gBAAgB,OAAO,OAAK,EAAE,QAAQ,KAAK;AAC5D,YAAI,SAAS,SAAS,GAAG;AACvB,gBAAM,QAAQ,YAAY,MAAM,EAAE;AAClC,qBAAW,QAAQ,UAAU;AAC3B,gBAAI,KAAK,OAAO,KAAK,KAAK,MAAM,MAAM,OAAQ,OAAM,KAAK,GAAG,IAAI,KAAK;AAAA,UACvE;AACA,wBAAc,MAAM,KAAK,EAAE;AAAA,QAC7B;AACA,cAAM,iBAAiB,UAAU,IAAI,QAAQ,OAAO,eAAe,WAAW,IAAI;AAClF,eACE,8CAAC,SAAgB,WAAW,iBAAiB,KAAK,QAAQ,OAAO,iBAAiB,OAAO,aAAa,QAAQ,GAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,MAAM,YAAY,GAAG,UAAU,MAAM,YAAY,OAAO,UAAU,WAAW,GACzN;AAAA,2BACG,eAAe,IAAI,CAAC,KAAK,MAAM,6CAAC,UAAa,WAAW,IAAI,YAAa,cAAI,QAAnC,CAAwC,CAAO,IACzF,oBAAoB,aAAa,OAAO,MAAM;AAAA,UACjD,sBAAsB,CAAC,kBAAkB,UAAU,OAAO,OACzD,6CAAC,UAAK,WAAU,aAAY,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,OAAO,GAAG,MAAM,OAAO,OAAO,QAAQ,GAAG,UAAU,MAAM,KAAK,GAAG,eAAe,OAAO,GAAG;AAAA,aALxJ,KAOV;AAAA,MAEJ,CAAC;AAAA,MACA,kBACC,6CAAC,SAAI,WAAU,kBAAiB,sDAEhC;AAAA,MAED,WAAW,eAAe,UAAa,WAAW,eAAe,UAChE,8CAAC,UAAK,OAAO,EAAE,UAAU,YAAY,QAAQ,GAAG,OAAO,GAAG,YAAY,kBAAkB,UAAU,QAAQ,OAAO,4BAA4B,eAAe,QAAQ,SAAS,IAAI,GAC9K;AAAA,eAAO,WAAW,aAAa,CAAC,EAAE,SAAS,GAAG,GAAG;AAAA,QAAE;AAAA,QAAE,OAAO,WAAW,aAAa,CAAC,EAAE,SAAS,GAAG,GAAG;AAAA,SACzG;AAAA,OAEJ;AAAA,EAEJ;AAEA,QAAM,kBAAkB,YAAY;AAClC,4BAAwB,CAAC;AACzB,0BAAsB,KAAK;AAC3B,QAAI,oBAAoB,SAAS;AAAE,mBAAa,oBAAoB,OAAO;AAAG,0BAAoB,UAAU;AAAA,IAAM;AAClH,UAAM,UAAU;AAAA,EAClB;AAEA,QAAM,iBAAiB,CAAC,WAAoB;AAC1C,YAAQ,QAAQ;AAAA,MACd,KAAK;AAAiB,eAAO;AAAA,MAC7B,KAAK;AAAa,eAAO;AAAA,MACzB,KAAK;AAAc,eAAO;AAAA,MAC1B,KAAK;AAAS,eAAO;AAAA,MACrB;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAEA,SACE,8CAAC,SAAI,WAAW,eAAe,YAAY,wBAAwB,EAAE,IAAI,aAAa,EAAE,IAAI,OACzF;AAAA,kBACC,6CAAC,SAAI,WAAU,aACZ,qBACC,8EACE;AAAA,oDAAC,UAAK,WAAU,kBACd;AAAA,qDAAC,gBAAa,MAAM,IAAI;AAAA,QACxB,6CAAC,UAAK,sBAAQ;AAAA,QACb,aAAa,6CAAC,UAAK,WAAU,oBAAmB,qBAAO;AAAA,QACvD,YAAY,aAAa,6CAAC,UAAK,WAAU,gBAAgB,cAAI,KAAK,WAAW,SAAS,EAAE,mBAAmB,GAAE;AAAA,QAC9G,6CAAC,UAAK,WAAU,WAAW,qBAAW,cAAc,YAAY,sBAAsB,oBAAmB;AAAA,QACxG,YAAY,mBAAmB,6CAAC,UAAK,WAAU,iBAAgB,kBAAI;AAAA,QACnE,YAAY,eAAe,6CAAC,UAAK,WAAU,gBAAe,iBAAG;AAAA,SAChE;AAAA,MACA,8CAAC,SAAI,WAAU,mBACZ;AAAA,oBAAY,UAAU,WAAW,WAAW,aAAa,6CAAC,WAAQ,MAAM,IAAI,OAAO,EAAE,OAAO,eAAe,WAAW,MAAM,EAAE,GAAG;AAAA,QACjI,cAAc,WAAW,WAAW,cAAc,WAAW,YAC1D,6CAAC,YAAS,MAAM,IAAI,OAAO,EAAE,OAAO,2BAA2B,GAAG,IAClE,6CAAC,eAAY,MAAM,IAAI,OAAO,EAAE,OAAO,UAAU,GAAG;AAAA,QACvD;AAAA,QACA,cAAc,6CAAC,YAAO,SAAS,CAAC,MAAM;AAAE,YAAE,gBAAgB;AAAG,qBAAW;AAAA,QAAG,GAAG,WAAU,eAAc,OAAM,qBAAoB,uDAAC,gBAAa,GAAE;AAAA,QACjJ,6CAAC,YAAO,SAAS,CAAC,MAAM;AAAE,YAAE,gBAAgB;AAAG,2BAAiB,OAAK,CAAC,CAAC;AAAA,QAAG,GAAG,WAAU,eAAc,OAAM,sBAAqB,uDAAC,YAAS,MAAM,IAAI,GAAE;AAAA,QACrJ;AAAA,SACH;AAAA,OACF,IAEA,8EACE;AAAA,oDAAC,UAAK,WAAU,kBACd;AAAA,qDAAC,gBAAa,MAAM,IAAI;AAAA,QACxB,6CAAC,UAAM,kBAAQ,aAAY;AAAA,QAC1B,aAAa,6CAAC,UAAK,WAAU,oBAAmB,qBAAO;AAAA,QACvD,YAAY,aAAa,6CAAC,UAAK,WAAU,gBAAgB,cAAI,KAAK,WAAW,SAAS,EAAE,mBAAmB,GAAE;AAAA,QAC9G,6CAAC,UAAK,WAAU,WAAW,qBAAW,mBAAmB,YAAY,sBAAsB,6BAA4B;AAAA,QACtH,YAAY,mBAAmB,6CAAC,UAAK,WAAU,iBAAgB,kBAAI;AAAA,QACnE,YAAY,eAAe,6CAAC,UAAK,WAAU,gBAAe,iBAAG;AAAA,SAChE;AAAA,MACA,8CAAC,SAAI,WAAU,mBACZ;AAAA,sBAAc,WAAW,WAAW,aACnC,6CAAC,SAAI,WAAU,mBACZ,qBAAW,YACV,8EACE;AAAA,uDAAC,YAAS,MAAM,IAAI,OAAO,EAAE,OAAO,2BAA2B,GAAG;AAAA,UAClE,6CAAC,UAAK,WAAU,WAAW,qBAAW,MAAK;AAAA,WAC7C,IAEA,8EACE;AAAA,uDAAC,eAAY,MAAM,IAAI,OAAO,EAAE,OAAO,UAAU,GAAG;AAAA,UACpD,6CAAC,UAAK,WAAU,wBACb,gCAAsB,eACnB,eAAe,uBAAuB,IAAI,KAAK,oBAAoB,IAAI,WAAW,MAAM,KAAK,KAC7F,wBAAwB,cAAc,wCAAwC,gBACpF;AAAA,UACA,6CAAC,YAAO,SAAS,iBAAiB,UAAU,gBAAgB,oBAAoB,WAAU,eAAc,OAAM,aAC5G,uDAAC,eAAY,MAAM,IAAI,WAAW,gBAAgB,qBAAqB,YAAY,IAAI,GACzF;AAAA,WACF,GAEJ;AAAA,QAED,YAAY,UACX,8CAAC,SAAI,WAAU,mBACb;AAAA,uDAAC,WAAQ,MAAM,IAAI,OAAO,EAAE,OAAO,eAAe,WAAW,MAAM,EAAE,GAAG;AAAA,UACvE,WAAW,YAAY,6CAAC,UAAK,WAAU,WAAW,qBAAW,UAAS;AAAA,WACzE;AAAA,QAED;AAAA,QACD,6CAAC,YAAO,SAAS,CAAC,MAAM;AAAE,YAAE,gBAAgB;AAAG,2BAAiB,OAAK,CAAC,CAAC;AAAA,QAAG,GAAG,WAAU,eAAc,OAAM,sBAAqB,uDAAC,YAAS,MAAM,IAAI,GAAE;AAAA,QACrJ;AAAA,SACH;AAAA,OACF,GAEJ;AAAA,IAGF,6CAAC,SAAI,WAAU,WACb;AAAA,MAAC;AAAA;AAAA,QAAI,KAAK;AAAA,QAAa,SAAS;AAAA,QAAqB,WAAW,aAAa,WAAW,uBAAuB,EAAE;AAAA,QAC/G,OAAO,CAAC,WAAW,EAAE,OAAO,QAAQ,YAAY,QAAQ,QAAQ,WAAW,cAAc,WAAW,YAAY,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,YAAY,iBAAiB,IAAI;AAAA,QACrM;AAAA,yBAAe,QACd,8CAAC,SAAI,WAAU,mBACb;AAAA,yDAAC,qBAAkB,MAAM,IAAI;AAAA,YAC7B,6CAAC,UAAM,iBAAO,WAAW,GAAE;AAAA,aAC7B;AAAA,UAEF,6CAAC,SAAI,KAAK,kBAAkB,WAAU,qBAAqB,uBAAa,GAAE;AAAA,UACzE;AAAA,UACA,iBACC,8CAAC,SAAI,WAAU,sBACb;AAAA,0DAAC,SAAI,WAAU,uBACb;AAAA,2DAAC,UAAK,gCAAkB;AAAA,cACxB,6CAAC,YAAO,WAAU,eAAc,SAAS,MAAM,iBAAiB,KAAK,GAAG,OAAO,EAAE,eAAe,OAAO,GAAG,kBAAO;AAAA,eACnH;AAAA,YACA,6CAAC,WAAM,WAAU,sBACf,wDAAC,WACC;AAAA,4DAAC,QAAG;AAAA,6DAAC,QAAG,WAAU,mBAAkB,wBAAU;AAAA,gBAAK,6CAAC,QAAG,wBAAU;AAAA,iBAAK;AAAA,cACtE,8CAAC,QAAG;AAAA,6DAAC,QAAG,WAAU,mBAAkB,oBAAM;AAAA,gBAAK,6CAAC,QAAG,mBAAK;AAAA,iBAAK;AAAA,cAC7D,8CAAC,QAAG;AAAA,6DAAC,QAAG,WAAU,mBAAkB,oBAAM;AAAA,gBAAK,6CAAC,QAAG,gCAAkB;AAAA,iBAAK;AAAA,cAC1E,8CAAC,QAAG;AAAA,6DAAC,QAAG,WAAU,mBAAkB,qBAAO;AAAA,gBAAK,6CAAC,QAAG,uBAAS;AAAA,iBAAK;AAAA,cAClE,8CAAC,QAAG;AAAA,6DAAC,QAAG,WAAU,mBAAkB,uBAAS;AAAA,gBAAK,6CAAC,QAAG,qBAAO;AAAA,iBAAK;AAAA,cAClE,8CAAC,QAAG;AAAA,6DAAC,QAAG,WAAU,mBAAkB,mBAAK;AAAA,gBAAK,6CAAC,QAAG,qCAAuB;AAAA,iBAAK;AAAA,cAC9E,8CAAC,QAAG;AAAA,6DAAC,QAAG,WAAU,mBAAkB,oBAAM;AAAA,gBAAK,6CAAC,QAAG,6BAAe;AAAA,iBAAK;AAAA,eACzE,GACF;AAAA,aACF;AAAA,UAED,cAAc,CAAC,WAAW,aAAa,cACtC,8CAAC,SAAI,WAAU,cACb;AAAA,yDAAC,eAAY,MAAM,IAAI;AAAA,YACvB,6CAAC,UAAM,gCAAsB,eAAe,oBAAoB,YAAY,WAAW,eAAe,kBAAkB,gBAAe;AAAA,YACtI,WAAW,SAAS,CAAC,sBAAsB,CAAC,gBAC3C,6CAAC,UAAK,OAAO,EAAE,UAAU,UAAU,SAAS,KAAK,UAAU,OAAO,WAAW,UAAU,WAAW,aAAa,GAAI,qBAAW,OAAM;AAAA,aAExI;AAAA,UAEF;AAAA,YAAC;AAAA;AAAA,cAAM,KAAK;AAAA,cAAU,MAAK;AAAA,cAAO,OAAO;AAAA,cAAW,UAAU;AAAA,cAAa,WAAW;AAAA,cACpF,OAAO,EAAE,UAAU,YAAY,SAAS,GAAG,eAAe,QAAQ,UAAU,QAAQ,YAAY,QAAQ,YAAY,kBAAkB,SAAS,GAAG,QAAQ,QAAQ,QAAQ,OAAO;AAAA,cACjL,cAAa;AAAA,cAAM,aAAY;AAAA,cAAM,gBAAe;AAAA,cAAM,YAAY;AAAA;AAAA,UAAO;AAAA;AAAA;AAAA,IACjF,GACF;AAAA,KACF;AAEJ;;;AcjyBO,SAAS,iBAAiB,UAAkB,YAA4B;AAC7E,SAAO,mBAAmB,QAAQ,EAAE,OAAO,iBAAiB,UAAU,YAAY,EAAE;AACtF;AAQO,SAAS,eAAe,MAA6D;AAC1F,SAAO,mBAAmB,QAAQ,EAAE,OAAO,eAAe,IAAI;AAChE;","names":["import_react","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/GreenScreenTerminal.tsx","../src/adapters/RestAdapter.ts","../src/adapters/WebSocketAdapter.ts","../src/hooks/useTerminal.ts","../src/hooks/useTypingAnimation.ts","../src/utils/grid.ts","../src/protocols/tn5250.ts","../src/protocols/tn3270.ts","../src/protocols/vt.ts","../src/protocols/hp6530.ts","../src/protocols/registry.ts","../src/components/TerminalBootLoader.tsx","../src/components/Icons.tsx","../src/components/InlineSignIn.tsx","../src/utils/attribute.ts","../src/utils/validation.ts","../src/utils/rendering.ts"],"sourcesContent":["// Components\nexport { GreenScreenTerminal } from './components/GreenScreenTerminal';\nexport type { GreenScreenTerminalProps } from './components/GreenScreenTerminal';\nexport { TerminalBootLoader } from './components/TerminalBootLoader';\nexport type { TerminalBootLoaderProps } from './components/TerminalBootLoader';\nexport { InlineSignIn } from './components/InlineSignIn';\nexport type { InlineSignInProps } from './components/InlineSignIn';\n\n// Icons\nexport { TerminalIcon, WifiIcon, WifiOffIcon, AlertTriangleIcon, RefreshIcon, KeyIcon, MinimizeIcon } from './components/Icons';\n\n// Adapters\nexport { RestAdapter } from './adapters/RestAdapter';\nexport type { RestAdapterOptions } from './adapters/RestAdapter';\nexport { WebSocketAdapter } from './adapters/WebSocketAdapter';\nexport type { WebSocketAdapterOptions } from './adapters/WebSocketAdapter';\nexport type {\n TerminalAdapter,\n TerminalProtocol,\n ProtocolProfile,\n ProtocolColorProfile,\n ScreenData,\n ConnectionStatus,\n SendResult,\n ConnectConfig,\n Field,\n FieldValue,\n} from './adapters/types';\n\n// Hooks\nexport { useTypingAnimation } from './hooks/useTypingAnimation';\nexport {\n useTerminalConnection,\n useTerminalScreen,\n useTerminalInput,\n} from './hooks/useTerminal';\n\n// Protocols\nexport { getProtocolProfile } from './protocols/registry';\nexport { tn5250Profile } from './protocols/tn5250';\nexport { tn3270Profile } from './protocols/tn3270';\nexport { vtProfile } from './protocols/vt';\nexport { hp6530Profile } from './protocols/hp6530';\n\n// Utilities\nexport { positionToRowCol, isFieldEntry } from './utils/grid';\nexport { getRowColorClass, parseHeaderRow } from './utils/rendering';\n","import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport type { TerminalAdapter, ScreenData, ConnectionStatus, Field, TerminalProtocol, ProtocolProfile, ConnectConfig } from '../adapters/types';\nimport { RestAdapter } from '../adapters/RestAdapter';\nimport { WebSocketAdapter } from '../adapters/WebSocketAdapter';\nimport { useTerminalScreen, useTerminalInput, useTerminalConnection } from '../hooks/useTerminal';\nimport { useTypingAnimation } from '../hooks/useTypingAnimation';\nimport { getProtocolProfile } from '../protocols/registry';\nimport { TerminalBootLoader as DefaultBootLoader } from './TerminalBootLoader';\nimport { TerminalIcon, WifiIcon, WifiOffIcon, AlertTriangleIcon, RefreshIcon, KeyIcon, MinimizeIcon, KeyboardIcon } from './Icons';\nimport { InlineSignIn } from './InlineSignIn';\nimport { decodeAttrByte, decodeExtColor, decodeExtHighlight, cssVarForColor, mergeExtAttr, extColorIsReverse } from '../utils/attribute';\nimport { validateMod10, validateMod11, filterFieldInput } from '../utils/validation';\n\n/**\n * Map a 5250 AID byte (e.g. from a pointer-AID FCW) back to the key-name\n * token that `sendKey` understands. Covers Enter, F1-F24, Page Up/Down,\n * Clear, Help, and Print. Returns null for unknown/unsupported AIDs.\n */\nfunction aidByteToKeyName(aid: number): string | null {\n if (aid === 0xF1) return 'ENTER';\n if (aid === 0xF3) return 'HELP';\n if (aid === 0xF4) return 'PAGEUP';\n if (aid === 0xF5) return 'PAGEDOWN';\n if (aid === 0xF6) return 'PRINT';\n if (aid === 0xBD) return 'CLEAR';\n // F1..F12 → 0x31..0x3C\n if (aid >= 0x31 && aid <= 0x3C) return `F${aid - 0x30}`;\n // F13..F24 → 0xB1..0xBC\n if (aid >= 0xB1 && aid <= 0xBC) return `F${aid - 0xB0 + 12}`;\n return null;\n}\n\n/* ── No-op adapter (placeholder before connection) ───────────────── */\n\nconst noopResult = { success: false, error: 'No adapter configured' };\nconst noopAdapter: TerminalAdapter = {\n getScreen: async () => null,\n getStatus: async () => ({ connected: false, status: 'disconnected' }),\n sendText: async () => noopResult,\n sendKey: async () => noopResult,\n setCursor: async () => noopResult,\n connect: async () => noopResult,\n disconnect: async () => noopResult,\n reconnect: async () => noopResult,\n};\n\n/* ── Component Props ──────────────────────────────────────────────── */\n\nexport interface GreenScreenTerminalProps {\n /** Adapter for communicating with the terminal backend (optional — auto-created from sign-in form or baseUrl) */\n adapter?: TerminalAdapter;\n /** Base URL for the terminal API — convenience shorthand that auto-creates a RestAdapter */\n baseUrl?: string;\n /** Worker/proxy WebSocket URL — convenience shorthand that auto-creates a WebSocketAdapter */\n workerUrl?: string;\n /** Terminal protocol (determines color conventions, header label, etc.) */\n protocol?: TerminalProtocol;\n /** Custom protocol profile (overrides protocol param) */\n protocolProfile?: ProtocolProfile;\n /** Direct screen data injection (bypasses polling) */\n screenData?: ScreenData | null;\n /** Direct connection status injection */\n connectionStatus?: ConnectionStatus | null;\n\n /** Whether the terminal is read-only (no keyboard input) */\n readOnly?: boolean;\n /** Polling interval in ms (0 to disable polling; default 2000) */\n pollInterval?: number;\n /** Whether to auto-reconnect on disconnect (default true) */\n autoReconnect?: boolean;\n /** Max auto-reconnect attempts (default 5) */\n maxReconnectAttempts?: number;\n\n /** Compact embedded mode */\n embedded?: boolean;\n /** Show the header bar (default true) */\n showHeader?: boolean;\n /** Enable typing animation (default false) */\n typingAnimation?: boolean;\n /** Typing animation budget in ms (default 60) */\n typingBudgetMs?: number;\n\n /** Show inline sign-in form when disconnected (default true) */\n inlineSignIn?: boolean;\n /** Default protocol for the sign-in form dropdown (default 'tn5250') */\n defaultProtocol?: TerminalProtocol;\n /** Callback when sign-in form is submitted */\n onSignIn?: (config: ConnectConfig) => void;\n /** Disable auto-focus on the terminal after connecting (default false) */\n autoFocusDisabled?: boolean;\n\n /** Custom boot loader element, or false to disable */\n bootLoader?: React.ReactNode | false;\n /** When true, dismiss the boot loader. If provided, overrides the default\n * \"dismiss when screen data arrives\" behavior. Use to keep the boot loader\n * visible during sign-in, startup command execution, etc. */\n bootLoaderReady?: boolean;\n /** Content for the right side of the header */\n headerRight?: React.ReactNode;\n /** Content rendered after the connection status groups (WiFi+host, Key+username) */\n statusActions?: React.ReactNode;\n /** Overlay content (e.g. \"Extracting...\" state) */\n overlay?: React.ReactNode;\n /** Callback for notifications (replaces toast) */\n onNotification?: (message: string, type: 'info' | 'error') => void;\n /** Callback when screen content changes */\n onScreenChange?: (screen: ScreenData) => void;\n /** Callback for minimize action (embedded mode) */\n onMinimize?: () => void;\n /** Show the keyboard-shortcuts button in the header (default true) */\n showShortcutsButton?: boolean;\n\n /** Additional CSS class name */\n className?: string;\n /** Inline styles */\n style?: React.CSSProperties;\n}\n\n/**\n * GreenScreenTerminal — Multi-protocol legacy terminal emulator component.\n *\n * Renders a terminal screen with:\n * - Green-on-black terminal aesthetic with protocol-specific color conventions\n * - Connection status indicator\n * - Keyboard input support (text, function keys, tab)\n * - Auto-reconnect with exponential backoff\n * - Typing animation for field entries\n * - Focus lock mode for keyboard capture\n *\n * Supports: TN5250 (IBM i), TN3270 (z/OS), VT (OpenVMS/Pick), HP 6530 (NonStop)\n */\nexport function GreenScreenTerminal({\n adapter: externalAdapter,\n baseUrl,\n workerUrl,\n protocol,\n protocolProfile: customProfile,\n screenData: externalScreenData,\n connectionStatus: externalStatus,\n readOnly = false,\n pollInterval = 2000,\n autoReconnect: autoReconnectEnabled = true,\n maxReconnectAttempts: maxAttempts = 5,\n embedded = false,\n showHeader = true,\n typingAnimation = false,\n typingBudgetMs = 60,\n inlineSignIn = true,\n defaultProtocol: signInDefaultProtocol,\n onSignIn,\n autoFocusDisabled = false,\n bootLoader,\n bootLoaderReady,\n headerRight,\n statusActions,\n overlay,\n onNotification,\n onScreenChange,\n onMinimize,\n showShortcutsButton = true,\n className,\n style,\n}: GreenScreenTerminalProps) {\n const profile = customProfile ?? getProtocolProfile(protocol);\n\n // --- Resolve adapter: explicit > baseUrl > workerUrl > internal (from sign-in) > default WebSocket > noop ---\n const [internalAdapter, setInternalAdapter] = useState<TerminalAdapter | null>(null);\n const baseUrlAdapter = useMemo(\n () => baseUrl ? new RestAdapter({ baseUrl }) : null,\n [baseUrl],\n );\n const workerUrlAdapter = useMemo(\n () => workerUrl ? new WebSocketAdapter({ workerUrl }) : null,\n [workerUrl],\n );\n // Default WebSocketAdapter (auto-detects env vars, falls back to localhost:3001) when no adapter is configured\n const defaultWsAdapter = useMemo(\n () => (!externalAdapter && !baseUrl && !workerUrl) ? new WebSocketAdapter() : null,\n [externalAdapter, baseUrl, workerUrl],\n );\n const adapter = externalAdapter ?? baseUrlAdapter ?? workerUrlAdapter ?? internalAdapter ?? defaultWsAdapter ?? noopAdapter;\n const isUsingDefaultAdapter = adapter === defaultWsAdapter;\n\n // --- Data sources ---\n const shouldPoll = pollInterval > 0 && !externalScreenData;\n const { data: polledScreenData, error: screenError } = useTerminalScreen(adapter, pollInterval, shouldPoll);\n const { sendText: _sendText, sendKey: _sendKey } = useTerminalInput(adapter);\n const { connect, reconnect, loading: reconnecting, error: connectError } = useTerminalConnection(adapter);\n\n const rawScreenData = externalScreenData ?? polledScreenData;\n\n const connStatus = externalStatus ?? (rawScreenData ? { connected: true, status: 'authenticated' as const } : { connected: false, status: 'disconnected' as const });\n\n // Typing animation\n const { displayedContent, animatedCursorPos } = useTypingAnimation(\n rawScreenData?.content,\n typingAnimation,\n typingBudgetMs,\n );\n\n const screenData = useMemo(() => {\n if (!rawScreenData) return null;\n return { ...rawScreenData, content: displayedContent };\n }, [rawScreenData, displayedContent]);\n\n // Notify parent on screen changes\n const prevScreenSigRef = useRef<string | undefined>(undefined);\n useEffect(() => {\n if (screenData && onScreenChange && screenData.screen_signature !== prevScreenSigRef.current) {\n prevScreenSigRef.current = screenData.screen_signature;\n onScreenChange(screenData);\n }\n }, [screenData, onScreenChange]);\n\n const sendText = useCallback(async (text: string) => _sendText(text), [_sendText]);\n const sendKey = useCallback(async (key: string) => _sendKey(key), [_sendKey]);\n\n // --- Optimistic edits ---\n // Characters typed by the user are applied optimistically to the displayed\n // content before the proxy responds. Cleared on full screen updates.\n const [optimisticEdits, setOptimisticEdits] = useState<Array<{ row: number; col: number; ch: string }>>([]);\n const prevScreenContentForEdits = useRef<string | undefined>(undefined);\n useEffect(() => {\n // Clear optimistic edits whenever the screen content changes (not just signature).\n // This prevents stale keystrokes from persisting across screen transitions when\n // the adapter talks to the proxy directly and the WS broadcast hasn't caught up.\n const content = rawScreenData?.content;\n if (content && content !== prevScreenContentForEdits.current) {\n prevScreenContentForEdits.current = content;\n setOptimisticEdits([]);\n }\n }, [rawScreenData?.content]);\n\n // --- UI State ---\n const [inputText, setInputText] = useState('');\n const [isFocused, setIsFocused] = useState(false);\n const [showShortcuts, setShowShortcuts] = useState(false);\n const terminalRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const [syncedCursor, setSyncedCursor] = useState<{ row: number; col: number } | null>(null);\n const prevRawContentRef = useRef('');\n\n useEffect(() => {\n const newContent = rawScreenData?.content || '';\n if (prevRawContentRef.current && newContent && newContent !== prevRawContentRef.current) {\n setSyncedCursor(null);\n setInputText('');\n }\n prevRawContentRef.current = newContent;\n }, [rawScreenData?.content]);\n\n // --- Auto-reconnect ---\n const [autoReconnectAttempt, setAutoReconnectAttempt] = useState(0);\n const [isAutoReconnecting, setIsAutoReconnecting] = useState(false);\n const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const wasConnectedRef = useRef(false);\n const isConnectedRef = useRef(false);\n\n useEffect(() => { isConnectedRef.current = connStatus?.connected ?? false; }, [connStatus?.connected]);\n\n useEffect(() => {\n if (!autoReconnectEnabled) return;\n const isConnected = connStatus?.connected;\n\n if (isConnected) {\n wasConnectedRef.current = true;\n if (reconnectTimeoutRef.current) { clearTimeout(reconnectTimeoutRef.current); reconnectTimeoutRef.current = null; }\n setAutoReconnectAttempt(0);\n setIsAutoReconnecting(false);\n } else if (wasConnectedRef.current && !isConnected && !isAutoReconnecting && !reconnecting) {\n if (autoReconnectAttempt < maxAttempts) {\n setIsAutoReconnecting(true);\n const delay = Math.pow(2, autoReconnectAttempt) * 1000;\n reconnectTimeoutRef.current = setTimeout(async () => {\n if (isConnectedRef.current) { setIsAutoReconnecting(false); return; }\n onNotification?.(`Auto-reconnect attempt ${autoReconnectAttempt + 1}/${maxAttempts}`, 'info');\n try {\n const result = await reconnect();\n if (!result?.success) setAutoReconnectAttempt(prev => prev + 1);\n } catch {\n onNotification?.('Auto-reconnect failed', 'error');\n setAutoReconnectAttempt(prev => prev + 1);\n }\n setIsAutoReconnecting(false);\n }, delay);\n }\n }\n return () => { if (reconnectTimeoutRef.current) clearTimeout(reconnectTimeoutRef.current); };\n }, [connStatus?.connected, autoReconnectAttempt, isAutoReconnecting, reconnecting, reconnect, autoReconnectEnabled, maxAttempts, onNotification]);\n\n // --- Inline sign-in ---\n const [connecting, setConnecting] = useState(false);\n const [signInError, setSignInError] = useState<string | null>(null);\n const handleSignIn = useCallback(async (config: ConnectConfig) => {\n // If the caller provided onSignIn, let them handle connection setup\n if (onSignIn) {\n onSignIn(config);\n return;\n }\n setConnecting(true);\n setSignInError(null);\n try {\n // Auto-create adapter from sign-in config when no external adapter is provided\n if (!externalAdapter && !baseUrlAdapter) {\n const port = config.port ? `:${config.port}` : '';\n const newAdapter = new RestAdapter({ baseUrl: `http://${config.host}${port}` });\n setInternalAdapter(newAdapter);\n await newAdapter.connect(config);\n return;\n }\n await connect(config);\n } catch (err) {\n setSignInError(err instanceof Error ? err.message : String(err));\n setConnecting(false);\n }\n // Note: connecting is cleared by the screenData effect below, not here —\n // the connect() promise may resolve before the screen is actually ready.\n }, [connect, onSignIn, externalAdapter, baseUrlAdapter]);\n\n // Clear connecting state when screen data arrives or connection is confirmed\n useEffect(() => {\n if (connecting && screenData?.content) setConnecting(false);\n }, [connecting, screenData?.content]);\n\n // --- Boot loader ---\n const [showBootLoader, setShowBootLoader] = useState(bootLoader !== false);\n const [bootFadingOut, setBootFadingOut] = useState(false);\n\n useEffect(() => {\n if (!showBootLoader) return;\n // If bootLoaderReady is provided, only dismiss when it becomes true.\n // Otherwise fall back to dismissing when screen data arrives.\n const shouldDismiss = bootLoaderReady !== undefined\n ? bootLoaderReady\n : !!screenData?.content;\n if (shouldDismiss) {\n setBootFadingOut(true);\n setShowBootLoader(false);\n const timer = setTimeout(() => setBootFadingOut(false), 400);\n return () => clearTimeout(timer);\n }\n }, [screenData?.content, showBootLoader, bootLoaderReady]);\n\n // --- Focus management ---\n const FOCUS_STORAGE_KEY = 'gs-terminal-focused';\n\n // Restore focus from localStorage on mount (if auto-focus enabled)\n useEffect(() => {\n if (!autoFocusDisabled && !readOnly) {\n try {\n if (localStorage.getItem(FOCUS_STORAGE_KEY) === 'true') {\n setIsFocused(true);\n }\n } catch { /* localStorage unavailable */ }\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Persist focus state to localStorage\n useEffect(() => {\n if (autoFocusDisabled) return;\n try { localStorage.setItem(FOCUS_STORAGE_KEY, String(isFocused)); } catch { /* noop */ }\n }, [isFocused, autoFocusDisabled]);\n\n // Sync DOM focus with isFocused state\n useEffect(() => {\n if (isFocused) inputRef.current?.focus();\n }, [isFocused]);\n\n // Auto-focus terminal when screen data arrives (i.e. connected)\n const hadScreenData = useRef(false);\n useEffect(() => {\n if (screenData?.content && !hadScreenData.current && !autoFocusDisabled && !readOnly) {\n hadScreenData.current = true;\n setIsFocused(true);\n }\n if (!screenData?.content) hadScreenData.current = false;\n }, [screenData?.content, autoFocusDisabled, readOnly]);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (terminalRef.current && !terminalRef.current.contains(event.target as Node)) setIsFocused(false);\n };\n if (isFocused) document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [isFocused]);\n\n useEffect(() => {\n if (readOnly && isFocused) { setIsFocused(false); inputRef.current?.blur(); }\n }, [readOnly, isFocused]);\n\n const screenContentRef = useRef<HTMLDivElement>(null);\n const charWidthRef = useRef<number>(0);\n\n const handleTerminalClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n if (readOnly) return;\n setIsFocused(true);\n inputRef.current?.focus();\n\n // Click-to-cursor: calculate which row/col was clicked\n const contentEl = screenContentRef.current;\n if (!contentEl || !screenData?.fields) return;\n\n // Measure 1ch width in current font\n if (!charWidthRef.current) {\n const span = document.createElement('span');\n span.style.cssText = 'position:absolute;visibility:hidden;font:inherit;white-space:pre';\n span.textContent = 'X';\n contentEl.appendChild(span);\n charWidthRef.current = span.getBoundingClientRect().width;\n contentEl.removeChild(span);\n }\n\n const rect = contentEl.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n const ROW_HEIGHT = 21;\n const charWidth = charWidthRef.current;\n if (!charWidth) return;\n\n const clickedRow = Math.floor(y / ROW_HEIGHT);\n const clickedCol = Math.floor(x / charWidth);\n\n if (clickedRow < 0 || clickedRow >= (screenData.rows || 24) ||\n clickedCol < 0 || clickedCol >= (screenData.cols || 80)) return;\n\n // Pointer AID (FCW 0x8Axx): if the clicked field declares a pointer AID,\n // send it as a key press and skip the normal cursor-move. Per IBM 5250\n // Functions Reference this is the defined \"mouse click on field\" behavior.\n const clickedField = screenData.fields.find(f =>\n f.row === clickedRow && clickedCol >= f.col && clickedCol < f.col + f.length,\n );\n const ptrAid = clickedField && (clickedField as any).pointer_aid as number | undefined;\n if (ptrAid) {\n // Map AID byte back to a key name. Common cases: 0xF1 ENTER, 0x31-0x3C F1-F12.\n const keyName = aidByteToKeyName(ptrAid);\n if (keyName) {\n // First move the cursor into the field so the host sees the click location\n setSyncedCursor({ row: clickedRow, col: clickedCol });\n adapter.setCursor?.(clickedRow, clickedCol).then(() => sendKey(keyName));\n return;\n }\n }\n\n // Send cursor position to proxy (async, fire-and-forget for responsiveness)\n setSyncedCursor({ row: clickedRow, col: clickedCol });\n adapter.setCursor?.(clickedRow, clickedCol).then(r => {\n if (r?.cursor_row !== undefined) {\n setSyncedCursor({ row: r.cursor_row, col: r.cursor_col! });\n }\n });\n }, [readOnly, screenData, adapter, sendKey]);\n\n // --- Field helpers ---\n const getCurrentField = useCallback(() => {\n const fields = screenData?.fields || [];\n const cursorRow = syncedCursor?.row ?? screenData?.cursor_row ?? 0;\n const cursorCol = syncedCursor?.col ?? screenData?.cursor_col ?? 0;\n for (const field of fields) {\n if (field.is_input && field.row === cursorRow && cursorCol >= field.col && cursorCol < field.col + field.length) return field;\n }\n return null;\n }, [screenData, syncedCursor]);\n\n /**\n * Extract the text content of a field from the current screen display.\n * Reads from `content` using row/col so it reflects both server-committed\n * data and optimistic edits rendered on the current frame.\n */\n const readFieldValue = useCallback((field: Field): string => {\n if (!screenData?.content) return '';\n const lines = screenData.content.split('\\n');\n const line = lines[field.row] || '';\n return line.substring(field.col, field.col + field.length).replace(/\\s+$/, '');\n }, [screenData?.content]);\n\n /** Client-side self-check validation for fields declaring MOD10/MOD11 FCWs. */\n const [validationError, setValidationError] = useState<string | null>(null);\n const runSelfCheck = useCallback((): boolean => {\n const fields = screenData?.fields || [];\n for (const f of fields) {\n if (!f.is_input) continue;\n const val = readFieldValue(f);\n if (!val) continue;\n if ((f as any).self_check_mod10 && !validateMod10(val)) {\n setValidationError(`Invalid check digit (MOD10) in field at row ${f.row + 1}, col ${f.col + 1}`);\n return false;\n }\n if ((f as any).self_check_mod11 && !validateMod11(val)) {\n setValidationError(`Invalid check digit (MOD11) in field at row ${f.row + 1}, col ${f.col + 1}`);\n return false;\n }\n }\n setValidationError(null);\n return true;\n }, [screenData?.fields, readFieldValue]);\n\n // --- Keyboard handling ---\n // Characters are sent immediately to the proxy (no client-side buffering).\n // This keeps the proxy screen buffer in sync so arrow keys, backspace,\n // delete, and insert mode all work correctly at any cursor position.\n const handleKeyDown = async (e: React.KeyboardEvent) => {\n if (readOnly) { e.preventDefault(); return; }\n\n if (e.key === 'Escape') { e.preventDefault(); setIsFocused(false); inputRef.current?.blur(); return; }\n\n // Ctrl+R: Reset (clear keyboard lock and error line)\n if (e.ctrlKey && e.key === 'r') {\n e.preventDefault();\n const kr = await sendKey('RESET');\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n return;\n }\n\n // Ctrl+Enter: Field Exit (right-adjust and advance)\n if (e.ctrlKey && e.key === 'Enter') {\n e.preventDefault();\n const kr = await sendKey('FIELD_EXIT');\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n return;\n }\n\n const keyMap: Record<string, string> = {\n Enter: 'ENTER', Tab: 'TAB', Backspace: 'BACKSPACE', Delete: 'DELETE',\n ArrowUp: 'UP', ArrowDown: 'DOWN', ArrowLeft: 'LEFT', ArrowRight: 'RIGHT',\n PageUp: 'PAGEUP', PageDown: 'PAGEDOWN', Home: 'HOME', End: 'END', Insert: 'INSERT',\n };\n\n // F-keys. Match the *full* key name against the F1..F24 regex — if we\n // only tested startsWith('F'), a bare 'F' character would be swallowed\n // by preventDefault() without ever being sent as text, because the\n // inner regex would reject it and the handler would fall through with\n // nothing to dispatch. Making the regex the outer guard lets real\n // letter keys ('F', 'f', 'F1xyz', etc.) fall through to the text path.\n if (/^F([1-9]|1[0-9]|2[0-4])$/.test(e.key)) {\n e.preventDefault();\n // Self-check any declared MOD10/MOD11 fields before submitting\n if (!runSelfCheck()) return;\n const kr = await sendKey(e.key);\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n return;\n }\n\n // Action/navigation keys — self-check on submit-type keys (Enter, PageUp/Down)\n if (keyMap[e.key]) {\n e.preventDefault();\n const k = keyMap[e.key];\n const isSubmit = k === 'ENTER' || k === 'PAGEUP' || k === 'PAGEDOWN';\n if (isSubmit && !runSelfCheck()) return;\n const kr = await sendKey(k);\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n }\n };\n\n const handleInput = async (e: React.ChangeEvent<HTMLInputElement>) => {\n if (readOnly) { e.target.value = ''; return; }\n const newText = e.target.value;\n if (newText.length > inputText.length) {\n let newChars = newText.substring(inputText.length);\n\n // 5250 shift-type filtering + monocase auto-uppercase.\n // If the cursor is inside an input field, apply the field's\n // character constraints (digits/alpha/numeric/katakana/signed-num)\n // and uppercase rule before sending to the host. Rejected chars\n // trigger a short visual bell via setValidationError.\n const curField = getCurrentField();\n if (curField && (curField.shift_type || curField.monocase)) {\n const curColAbs = syncedCursor?.col ?? screenData?.cursor_col ?? 0;\n const startOffset = Math.max(0, curColAbs - curField.col);\n const { out, rejected } = filterFieldInput(curField, newChars, startOffset);\n if (rejected) {\n const what = curField.shift_type === 'digits_only' || curField.shift_type === 'numeric_only' || curField.shift_type === 'signed_num'\n ? 'digits only'\n : curField.shift_type === 'alpha_only'\n ? 'letters only'\n : curField.shift_type === 'katakana'\n ? 'katakana only'\n : 'character not allowed';\n setValidationError(`Field accepts ${what}`);\n setTimeout(() => setValidationError(null), 1500);\n }\n newChars = out;\n }\n\n if (newChars.length > 0) {\n // Optimistic: show character immediately at cursor position\n const curRow = syncedCursor?.row ?? screenData?.cursor_row ?? 0;\n const curCol = syncedCursor?.col ?? screenData?.cursor_col ?? 0;\n const edits: Array<{ row: number; col: number; ch: string }> = [];\n for (let i = 0; i < newChars.length; i++) {\n edits.push({ row: curRow, col: curCol + i, ch: newChars[i] });\n }\n setOptimisticEdits(prev => [...prev, ...edits]);\n setSyncedCursor({ row: curRow, col: curCol + newChars.length });\n // Send to proxy in background (cursor-only response)\n sendText(newChars).then(r => {\n if (r.cursor_row !== undefined) setSyncedCursor({ row: r.cursor_row, col: r.cursor_col! });\n });\n }\n }\n setInputText('');\n e.target.value = '';\n };\n\n // --- Cursor ---\n const termCols = screenData?.cols || profile.defaultCols;\n const getCursorPos = () => {\n if (animatedCursorPos) return animatedCursorPos;\n let cursorRow = syncedCursor?.row ?? screenData?.cursor_row ?? 0;\n let cursorCol = syncedCursor?.col ?? screenData?.cursor_col ?? 0;\n while (cursorCol >= termCols) { cursorCol -= termCols; cursorRow += 1; }\n return { row: cursorRow, col: cursorCol };\n };\n\n // --- Rendering helpers ---\n const renderTextWithUnderlines = useCallback((text: string, keyPrefix: string): React.ReactNode => {\n const underscoreRegex = /_{2,}/g;\n const segments: React.ReactNode[] = [];\n let lastIndex = 0;\n let match;\n let segmentIndex = 0;\n while ((match = underscoreRegex.exec(text)) !== null) {\n if (match.index > lastIndex) segments.push(<span key={`${keyPrefix}-t-${segmentIndex}`}>{text.substring(lastIndex, match.index)}</span>);\n const count = match[0].length;\n segments.push(<span key={`${keyPrefix}-u-${segmentIndex}`} style={{ borderBottom: '1px solid var(--gs-green, #10b981)', display: 'inline-block', width: `${count}ch` }}>{' '.repeat(count)}</span>);\n lastIndex = match.index + match[0].length;\n segmentIndex++;\n }\n if (lastIndex < text.length) segments.push(<span key={`${keyPrefix}-e`}>{text.substring(lastIndex)}</span>);\n return segments.length > 0 ? <>{segments}</> : <>{text}</>;\n }, []);\n\n const renderRowWithFields = useCallback((\n line: string,\n rowIndex: number,\n fields: Field[],\n cursorRow: number,\n cursorCol: number,\n ): React.ReactNode => {\n const inputFields = fields.filter(f => f.row === rowIndex && f.is_input);\n const highlightedFields = fields.filter(f => f.row === rowIndex && f.is_protected && f.is_highlighted);\n const reverseFields = fields.filter(f => f.row === rowIndex && f.is_protected && f.is_reverse);\n const colorFields = fields.filter(f => f.row === rowIndex && f.is_protected && (f as any).color && !f.is_highlighted && !f.is_reverse);\n const allRowFields = [...inputFields, ...highlightedFields, ...reverseFields, ...colorFields];\n\n const cols = screenData?.cols || profile.defaultCols;\n const extAttrs = (screenData as any)?.ext_attrs as Record<number, { color?: number; highlight?: number; char_set?: number }> | undefined;\n const dbcsCont = (screenData as any)?.dbcs_cont as number[] | undefined;\n const dbcsContSet = dbcsCont && dbcsCont.length > 0 ? new Set(dbcsCont) : null;\n\n // Has any extended attribute affecting this row?\n const hasExtOnRow = !!extAttrs && (() => {\n for (let c = 0; c < cols; c++) {\n if (extAttrs[rowIndex * cols + c]) return true;\n }\n return false;\n })();\n const hasDbcsOnRow = !!dbcsContSet && (() => {\n for (let c = 0; c < cols; c++) {\n if (dbcsContSet.has(rowIndex * cols + c)) return true;\n }\n return false;\n })();\n\n if (allRowFields.length === 0 && !hasExtOnRow && !hasDbcsOnRow) return <span>{line}</span>;\n\n const sorted = [...allRowFields].sort((a, b) => a.col - b.col);\n const segs: React.ReactNode[] = [];\n let lastEnd = 0;\n\n // Render a run of plain text while respecting ext_attrs and DBCS\n // continuation cells. Splits into per-cell spans only when necessary.\n const renderPlainRun = (runStart: number, runEnd: number, keyPrefix: string) => {\n if (runStart >= runEnd) return;\n if (!hasExtOnRow && !hasDbcsOnRow) {\n segs.push(<span key={keyPrefix}>{line.substring(runStart, runEnd)}</span>);\n return;\n }\n // Split into runs of cells that share visual state\n let pos = runStart;\n while (pos < runEnd) {\n const addr = rowIndex * cols + pos;\n const ext = extAttrs?.[addr];\n const isContCell = dbcsContSet?.has(addr);\n\n if (isContCell) {\n // DBCS continuation: the previous cell holds the glyph; this cell\n // is an empty string in the source but must occupy 1ch to keep\n // layout. Render as a zero-content full-width spacer.\n segs.push(\n <span\n key={`${keyPrefix}-dc${pos}`}\n style={{ display: 'inline-block', width: '1ch' }}\n aria-hidden=\"true\"\n />,\n );\n pos++;\n continue;\n }\n\n if (ext) {\n const color = ext.color !== undefined ? decodeExtColor(ext.color) : undefined;\n const colorReverse = ext.color !== undefined && extColorIsReverse(ext.color);\n const hl = ext.highlight !== undefined ? decodeExtHighlight(ext.highlight) : undefined;\n const style: React.CSSProperties = {};\n if (color) style.color = cssVarForColor(color);\n // Color-byte reverse (0x08..0x0E) swaps fg/bg like highlight reverse\n if (colorReverse) {\n style.background = cssVarForColor(color);\n style.color = '#000';\n }\n if (hl?.reverse) { style.background = 'currentColor'; style.color = '#000'; }\n if (hl?.underscore) style.textDecoration = 'underline';\n if (hl?.blink) (style as any).animation = 'gs-blink 1s steps(2, start) infinite';\n segs.push(\n <span key={`${keyPrefix}-x${pos}`} style={style}>\n {line[pos]}\n </span>,\n );\n pos++;\n continue;\n }\n\n // Coalesce plain cells until the next ext/cont boundary\n let runEndPlain = pos + 1;\n while (runEndPlain < runEnd) {\n const a = rowIndex * cols + runEndPlain;\n if (extAttrs?.[a] || dbcsContSet?.has(a)) break;\n runEndPlain++;\n }\n segs.push(\n <span key={`${keyPrefix}-p${pos}`}>{line.substring(pos, runEndPlain)}</span>,\n );\n pos = runEndPlain;\n }\n };\n\n sorted.forEach((field, idx) => {\n const fs = field.col;\n const fe = Math.min(field.col + field.length, cols);\n if (fs > lastEnd) renderPlainRun(lastEnd, fs, `t${idx}`);\n const fc = line.substring(fs, fe);\n\n // Highlight-on-entry: if the cursor is inside this field AND the host\n // declared a replacement attribute (FCW 0x89), override the base color\n // and highlight for this render pass.\n const cursorInField = cursorRow === field.row && cursorCol >= fs && cursorCol < field.col + field.length;\n const entryAttr = cursorInField && (field as any).highlight_entry_attr !== undefined\n ? decodeAttrByte((field as any).highlight_entry_attr)\n : null;\n\n // Base color from field's 5250 color attribute (or the entry override)\n const baseColor = entryAttr?.color ?? ((field as any).color as any);\n const colorVar = baseColor ? cssVarForColor(baseColor) : undefined;\n\n // Compose inline style, combining base + entry override\n const fieldStyle: React.CSSProperties = {};\n if (colorVar) fieldStyle.color = colorVar;\n if (entryAttr?.reverse) { fieldStyle.background = 'currentColor'; fieldStyle.color = '#000'; }\n if (entryAttr?.underscore) fieldStyle.textDecoration = 'underline';\n if (entryAttr?.highIntensity) fieldStyle.fontWeight = 'bold';\n\n // Non-display (password) fields: render as blank space, not asterisks.\n // Real 5250 terminals (ACS, Mocha, native) never echo password\n // characters — the underscore/field attribute shows the input zone,\n // typed chars stay invisible. Asterisks are an HTML <input\n // type=password> convention that doesn't belong here.\n const isPassword = (field as any).is_non_display;\n const displayText = isPassword ? ' '.repeat(fc.length) : fc;\n\n if (field.is_input) {\n const fieldWidth = Math.min(field.length, cols - fs);\n const fieldClass = field.is_underscored ? 'gs-input-field' : undefined;\n const extra: string[] = [];\n if ((field as any).is_dbcs) extra.push('gs-dbcs-field');\n if (cursorInField) extra.push('gs-field-active');\n const composedClass = [fieldClass, ...extra].filter(Boolean).join(' ') || undefined;\n segs.push(\n <span\n key={`f${idx}`}\n className={composedClass}\n style={{\n display: 'inline-block',\n width: `${fieldWidth}ch`,\n overflow: 'hidden',\n ...fieldStyle,\n }}\n >\n {displayText}\n </span>,\n );\n } else if (field.is_reverse) {\n segs.push(\n <span\n key={`v${idx}`}\n style={{ color: colorVar || 'var(--gs-red, #FF5555)', fontWeight: 'bold', ...fieldStyle }}\n >\n {displayText}\n </span>,\n );\n } else if (colorVar || entryAttr) {\n segs.push(<span key={`h${idx}`} style={fieldStyle}>{displayText}</span>);\n } else if (field.is_highlighted) {\n segs.push(<span key={`h${idx}`} style={{ color: 'var(--gs-white, #FFFFFF)' }}>{displayText}</span>);\n } else {\n segs.push(<span key={`h${idx}`}>{displayText}</span>);\n }\n lastEnd = fe;\n });\n if (lastEnd < line.length) renderPlainRun(lastEnd, line.length, 'te');\n return <>{segs}</>;\n }, [renderTextWithUnderlines, screenData, profile.defaultCols]);\n\n // --- Screen rendering ---\n const renderScreen = () => {\n if (showBootLoader && !screenData?.content) {\n if (bootLoader === false) return null;\n if (bootLoader) return <>{bootLoader}</>;\n return <DefaultBootLoader brandText={profile.bootText} />;\n }\n if (bootFadingOut && screenData?.content) return <div className=\"gs-fade-in\">{renderScreenContent()}</div>;\n if (!screenData?.content) {\n if (inlineSignIn && !connStatus?.connected) {\n return (\n <div style={{ width: '100%', height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <InlineSignIn defaultProtocol={signInDefaultProtocol || protocol || 'tn5250'} loading={connecting || reconnecting} error={signInError || connectError} onConnect={handleSignIn} />\n </div>\n );\n }\n return (\n <div style={{ width: `${screenData?.cols || profile.defaultCols}ch`, height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <div style={{ textAlign: 'center' }}>\n <div style={{ color: '#808080', marginBottom: '12px' }}><TerminalIcon size={40} /></div>\n <p style={{ fontFamily: 'var(--gs-font)', fontSize: '12px', color: connStatus?.status === 'connecting' ? '#f59e0b' : connStatus?.status === 'loading' ? '#94a3b8' : '#808080' }}>\n {connStatus?.connected ? 'Waiting for screen data...' : connStatus?.status === 'connecting' ? 'Connecting...' : connStatus?.status === 'loading' ? 'Loading...' : 'Not connected'}\n </p>\n {!connStatus?.connected && isUsingDefaultAdapter && (\n <p style={{ fontFamily: 'var(--gs-font)', fontSize: '11px', color: '#606060', marginTop: '8px' }}>\n Start the proxy: <code style={{ color: '#10b981' }}>npx green-screen-proxy</code>\n </p>\n )}\n </div>\n </div>\n );\n }\n return renderScreenContent();\n };\n\n const renderScreenContent = () => {\n if (!screenData?.content) return null;\n const termRows = screenData.rows || profile.defaultRows;\n const cols = screenData.cols || profile.defaultCols;\n const lines = screenData.content.split('\\n');\n const rows: string[] = [];\n for (let i = 0; i < termRows; i++) rows.push((lines[i] || '').padEnd(cols, ' '));\n\n const fields = screenData.fields || [];\n const ROW_HEIGHT = 21;\n const cursor = getCursorPos();\n const hasCursor = screenData.cursor_row !== undefined && screenData.cursor_col !== undefined;\n // Only show cursor when it's inside a visible input field (not non-display/password)\n const cursorInInputField = hasCursor && fields.some(f =>\n f.is_input && !(f as any).is_non_display &&\n f.row === cursor.row &&\n cursor.col >= f.col && cursor.col < f.col + f.length\n );\n\n return (\n <div style={{ fontFamily: 'var(--gs-font)', fontSize: '13px', position: 'relative', width: `${cols}ch` }}>\n {rows.map((line, index) => {\n // Apply optimistic edits to this row\n let displayLine = line;\n const rowEdits = optimisticEdits.filter(e => e.row === index);\n if (rowEdits.length > 0) {\n const chars = displayLine.split('');\n for (const edit of rowEdits) {\n if (edit.col >= 0 && edit.col < chars.length) chars[edit.col] = edit.ch;\n }\n displayLine = chars.join('');\n }\n const headerSegments = index === 0 ? profile.colors.parseHeaderRow(displayLine) : null;\n return (\n <div key={index} className={headerSegments ? '' : profile.colors.getRowColorClass(index, displayLine, termRows)} style={{ height: `${ROW_HEIGHT}px`, lineHeight: `${ROW_HEIGHT}px`, whiteSpace: 'pre', position: 'relative' }}>\n {headerSegments\n ? headerSegments.map((seg, i) => <span key={i} className={seg.colorClass}>{seg.text}</span>)\n : renderRowWithFields(displayLine, index, fields, cursor.row, cursor.col)}\n {cursorInInputField && index === cursor.row && (\n <span className=\"gs-cursor\" style={{ position: 'absolute', left: `${cursor.col}ch`, width: '1ch', height: `${ROW_HEIGHT}px`, top: 0, pointerEvents: 'none' }} />\n )}\n </div>\n );\n })}\n {validationError && (\n <div\n role=\"alert\"\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: 0,\n padding: '2px 6px',\n background: 'var(--gs-red, #FF5555)',\n color: '#000',\n fontFamily: 'var(--gs-font)',\n fontSize: '12px',\n zIndex: 10,\n }}\n onClick={() => setValidationError(null)}\n >\n {validationError} — click to dismiss\n </div>\n )}\n {screenData.cursor_row !== undefined && screenData.cursor_col !== undefined && (\n <span style={{ position: 'absolute', bottom: 0, right: 0, fontFamily: 'var(--gs-font)', fontSize: '10px', color: 'var(--gs-green, #10b981)', pointerEvents: 'none', opacity: 0.6 }}>\n {String(screenData.cursor_row + 1).padStart(2, '0')}/{String(screenData.cursor_col + 1).padStart(3, '0')}\n </span>\n )}\n </div>\n );\n };\n\n const handleReconnect = async () => {\n setAutoReconnectAttempt(0);\n setIsAutoReconnecting(false);\n if (reconnectTimeoutRef.current) { clearTimeout(reconnectTimeoutRef.current); reconnectTimeoutRef.current = null; }\n await reconnect();\n };\n\n const getStatusColor = (status?: string) => {\n switch (status) {\n case 'authenticated': return 'var(--gs-green, #10b981)';\n case 'connected': return '#F59E0B';\n case 'connecting': return '#64748b';\n case 'error': return '#EF4444';\n default: return '#64748b';\n }\n };\n\n // Send a key from the shortcuts panel. Mirrors the submit-key self-check\n // behaviour in handleKeyDown so clicked shortcuts behave like keystrokes.\n const handleShortcutSend = useCallback(async (key: string) => {\n if (readOnly) return;\n const isSubmit = key === 'ENTER' || key === 'PAGEUP' || key === 'PAGEDOWN' || /^F([1-9]|1[0-9]|2[0-4])$/.test(key);\n if (isSubmit && !runSelfCheck()) return;\n setIsFocused(true);\n inputRef.current?.focus();\n const kr = await sendKey(key);\n if (kr.cursor_row !== undefined) setSyncedCursor({ row: kr.cursor_row, col: kr.cursor_col! });\n }, [readOnly, runSelfCheck, sendKey]);\n\n return (\n <div className={`gs-terminal ${isFocused ? 'gs-terminal-focused' : ''} ${className || ''}`} style={style}>\n {showHeader && (\n <div className=\"gs-header\">\n {embedded ? (\n <>\n <span className=\"gs-header-left\">\n <TerminalIcon size={14} />\n <span>TERMINAL</span>\n {isFocused && <span className=\"gs-badge-focused\">FOCUSED</span>}\n {screenData?.timestamp && <span className=\"gs-timestamp\">{new Date(screenData.timestamp).toLocaleTimeString()}</span>}\n <span className=\"gs-hint\">{readOnly ? 'Read-only' : isFocused ? 'ESC to exit focus' : 'Click to control'}</span>\n {screenData?.keyboard_locked && <span className=\"gs-badge-lock\">X II</span>}\n {screenData?.insert_mode && <span className=\"gs-badge-ins\">INS</span>}\n </span>\n <div className=\"gs-header-right\">\n {connStatus?.status && connStatus.status !== 'loading' && <KeyIcon size={12} style={{ color: getStatusColor(connStatus.status) }} />}\n {connStatus && connStatus.status !== 'loading' && (connStatus.connected\n ? <WifiIcon size={12} style={{ color: 'var(--gs-green, #10b981)' }} />\n : <WifiOffIcon size={12} style={{ color: '#FF6B00' }} />)}\n {statusActions}\n {onMinimize && <button onClick={(e) => { e.stopPropagation(); onMinimize(); }} className=\"gs-btn-icon\" title=\"Minimize terminal\"><MinimizeIcon /></button>}\n {showShortcutsButton && <button onClick={(e) => { e.stopPropagation(); setShowShortcuts(s => !s); }} className=\"gs-btn-icon\" title=\"Keyboard shortcuts\"><KeyboardIcon size={12} /></button>}\n {headerRight}\n </div>\n </>\n ) : (\n <>\n <span className=\"gs-header-left\">\n <TerminalIcon size={14} />\n <span>{profile.headerLabel}</span>\n {isFocused && <span className=\"gs-badge-focused\">FOCUSED</span>}\n {screenData?.timestamp && <span className=\"gs-timestamp\">{new Date(screenData.timestamp).toLocaleTimeString()}</span>}\n <span className=\"gs-hint\">{readOnly ? 'Read-only mode' : isFocused ? 'ESC to exit focus' : 'Click terminal to control'}</span>\n {screenData?.keyboard_locked && <span className=\"gs-badge-lock\">X II</span>}\n {screenData?.insert_mode && <span className=\"gs-badge-ins\">INS</span>}\n </span>\n <div className=\"gs-header-right\">\n {connStatus && connStatus.status !== 'loading' && (\n <div className=\"gs-status-group\">\n {connStatus.connected ? (\n <>\n <WifiIcon size={12} style={{ color: 'var(--gs-green, #10b981)' }} />\n <span className=\"gs-host\">{connStatus.host}</span>\n </>\n ) : (\n <>\n <WifiOffIcon size={12} style={{ color: '#FF6B00' }} />\n <span className=\"gs-disconnected-text\">\n {isAutoReconnecting || reconnecting\n ? `RECONNECTING${autoReconnectAttempt > 0 ? ` (${autoReconnectAttempt}/${maxAttempts})` : '...'}`\n : autoReconnectAttempt >= maxAttempts ? 'DISCONNECTED (auto-retry exhausted)' : 'DISCONNECTED'}\n </span>\n <button onClick={handleReconnect} disabled={reconnecting || isAutoReconnecting} className=\"gs-btn-icon\" title=\"Reconnect\">\n <RefreshIcon size={12} className={reconnecting || isAutoReconnecting ? 'gs-spin' : ''} />\n </button>\n </>\n )}\n </div>\n )}\n {connStatus?.status && (\n <div className=\"gs-status-group\">\n <KeyIcon size={12} style={{ color: getStatusColor(connStatus.status) }} />\n {connStatus.username && <span className=\"gs-host\">{connStatus.username}</span>}\n </div>\n )}\n {statusActions}\n {showShortcutsButton && <button onClick={(e) => { e.stopPropagation(); setShowShortcuts(s => !s); }} className=\"gs-btn-icon\" title=\"Keyboard shortcuts\"><KeyboardIcon size={12} /></button>}\n {headerRight}\n </div>\n </>\n )}\n </div>\n )}\n\n <div className=\"gs-body\">\n <div ref={terminalRef} onClick={handleTerminalClick} className={`gs-screen ${embedded ? 'gs-screen-embedded' : ''}`}\n style={!embedded ? { width: `calc(${screenData?.cols || profile.defaultCols}ch + 24px)`, fontSize: (screenData?.cols ?? profile.defaultCols) > 80 ? '11px' : '13px', fontFamily: 'var(--gs-font)' } : undefined}>\n {screenError != null && (\n <div className=\"gs-error-banner\">\n <AlertTriangleIcon size={14} />\n <span>{String(screenError)}</span>\n </div>\n )}\n <div ref={screenContentRef} className=\"gs-screen-content\">{renderScreen()}</div>\n {overlay}\n {showShortcuts && (\n <div className=\"gs-shortcuts-panel\">\n <div className=\"gs-shortcuts-header\">\n <span>Keyboard Shortcuts</span>\n <button className=\"gs-btn-icon\" onClick={() => setShowShortcuts(false)}>&times;</button>\n </div>\n <div className=\"gs-shortcuts-section-title\">Actions</div>\n <table className=\"gs-shortcuts-table\">\n <tbody>\n {([\n ['Enter', 'Submit', 'ENTER'],\n ['Tab', 'Next field', 'TAB'],\n ['Backspace', 'Backspace', 'BACKSPACE'],\n ['Delete', 'Delete', 'DELETE'],\n ['Insert', 'Insert / Overwrite', 'INSERT'],\n ['Home', 'Home', 'HOME'],\n ['End', 'End', 'END'],\n ['Page Up', 'Roll Down', 'PAGEUP'],\n ['Page Down', 'Roll Up', 'PAGEDOWN'],\n ['Ctrl+Enter', 'Field Exit', 'FIELD_EXIT'],\n ['Ctrl+R', 'Reset', 'RESET'],\n ['—', 'Help', 'HELP'],\n ['—', 'Clear', 'CLEAR'],\n ['—', 'Print', 'PRINT'],\n ] as const).map(([label, desc, key]) => (\n <tr key={key} className=\"gs-shortcut-row\" onClick={(e) => { e.stopPropagation(); handleShortcutSend(key); }}>\n <td className=\"gs-shortcut-key\">{label}</td>\n <td>{desc}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <div className=\"gs-shortcuts-section-title\">Function keys</div>\n <div className=\"gs-shortcuts-fkeys\">\n {Array.from({ length: 24 }, (_, i) => `F${i + 1}`).map(fk => (\n <button\n key={fk}\n className=\"gs-shortcut-fkey\"\n onClick={(e) => { e.stopPropagation(); handleShortcutSend(fk); }}\n title={`Send ${fk}`}\n >{fk}</button>\n ))}\n </div>\n <div className=\"gs-shortcuts-section-title\">Info</div>\n <table className=\"gs-shortcuts-table\">\n <tbody>\n <tr><td className=\"gs-shortcut-key\">Click</td><td>Focus / Position cursor</td></tr>\n <tr><td className=\"gs-shortcut-key\">Escape</td><td>Exit focus mode</td></tr>\n </tbody>\n </table>\n </div>\n )}\n {connStatus && !connStatus.connected && screenData && (\n <div className=\"gs-overlay\">\n <WifiOffIcon size={28} />\n <span>{isAutoReconnecting || reconnecting ? 'Reconnecting...' : connStatus?.status === 'connecting' ? 'Connecting...' : 'Disconnected'}</span>\n {connStatus.error && !isAutoReconnecting && !reconnecting && (\n <span style={{ fontSize: '0.75em', opacity: 0.7, maxWidth: '80%', textAlign: 'center', wordBreak: 'break-word' }}>{connStatus.error}</span>\n )}\n </div>\n )}\n <input\n ref={inputRef}\n type=\"text\"\n value={inputText}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n style={{ position: 'absolute', opacity: 0, pointerEvents: 'none', fontSize: '13px', lineHeight: '21px', fontFamily: 'var(--gs-font)', padding: 0, border: 'none', height: '21px' }}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n spellCheck={false}\n // Hint IME / mobile keyboard mode from current field metadata.\n // DBCS fields on Japanese hosts should open the kana/kanji IME\n // so the user can compose full-width text directly.\n lang={(() => {\n const f = getCurrentField();\n if (!f) return undefined;\n if ((f as any).is_dbcs || (f as any).is_dbcs_either) return 'ja';\n return undefined;\n })()}\n inputMode={(() => {\n const f = getCurrentField();\n if (!f) return undefined;\n if ((f as any).is_dbcs) return 'text';\n // Numeric-only shift types (SHIFT_NUMERIC_ONLY 0x03, DIGITS_ONLY 0x05, SIGNED_NUM 0x07)\n // are not exposed on Field today — but the browser mode hint is just an optimization.\n return 'text';\n })()}\n />\n </div>\n </div>\n </div>\n );\n}\n","import type { TerminalAdapter, ScreenData, ConnectionStatus, SendResult, ConnectConfig, FieldValue } from './types';\n\nexport interface RestAdapterOptions {\n /** Base URL for the terminal API (e.g. \"https://myhost.com/api/terminal\") */\n baseUrl: string;\n /** Optional headers to include with every request (e.g. Authorization) */\n headers?: Record<string, string>;\n /** Optional function that returns headers (called per-request, useful for dynamic tokens) */\n getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n}\n\n/**\n * REST API adapter for terminal communication.\n *\n * Expects a backend that exposes these endpoints relative to `baseUrl`:\n * - GET /screen → ScreenData\n * - GET /status → ConnectionStatus\n * - POST /send-text → SendResult (body: { text })\n * - POST /send-key → SendResult (body: { key })\n * - POST /connect → SendResult\n * - POST /disconnect → SendResult\n * - POST /reconnect → SendResult\n */\nexport class RestAdapter implements TerminalAdapter {\n private baseUrl: string;\n private staticHeaders: Record<string, string>;\n private getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n\n constructor(options: RestAdapterOptions) {\n // Remove trailing slash\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.staticHeaders = options.headers || {};\n this.getHeaders = options.getHeaders;\n }\n\n private async buildHeaders(): Promise<Record<string, string>> {\n const dynamic = this.getHeaders ? await this.getHeaders() : {};\n return {\n 'Content-Type': 'application/json',\n ...this.staticHeaders,\n ...dynamic,\n };\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers = await this.buildHeaders();\n const response = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const detail = await response.json().catch(() => ({}));\n throw new Error(detail?.detail || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n async getScreen(): Promise<ScreenData | null> {\n try {\n return await this.request<ScreenData>('GET', '/screen');\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n // 503/404 expected when no active connection\n if (message.includes('503') || message.includes('404')) {\n return null;\n }\n throw e;\n }\n }\n\n async getStatus(): Promise<ConnectionStatus> {\n return this.request<ConnectionStatus>('GET', '/status');\n }\n\n async sendText(text: string): Promise<SendResult> {\n return this.request<SendResult>('POST', '/send-text', { text });\n }\n\n async sendKey(key: string): Promise<SendResult> {\n return this.request<SendResult>('POST', '/send-key', { key });\n }\n\n async setCursor(row: number, col: number): Promise<SendResult> {\n return this.request<SendResult>('POST', '/set-cursor', { row, col });\n }\n\n async readMdt(modifiedOnly: boolean = true): Promise<FieldValue[]> {\n const qs = modifiedOnly ? '' : '?includeUnmodified=1';\n const resp = await this.request<{ success: boolean; fields: FieldValue[] }>(\n 'GET',\n `/read-mdt${qs}`,\n );\n return resp?.fields ?? [];\n }\n\n async connect(config?: ConnectConfig): Promise<SendResult> {\n return this.request<SendResult>('POST', '/connect', config);\n }\n\n async disconnect(): Promise<SendResult> {\n return this.request<SendResult>('POST', '/disconnect');\n }\n\n async reconnect(): Promise<SendResult> {\n return this.request<SendResult>('POST', '/reconnect');\n }\n}\n","import type { TerminalAdapter, ScreenData, ConnectionStatus, SendResult, ConnectConfig, FieldValue } from './types';\n\nexport interface WebSocketAdapterOptions {\n /** URL of the green-screen proxy or worker. Auto-detected from env vars, defaults to http://localhost:3001 */\n workerUrl?: string;\n}\n\n/**\n * WebSocket adapter that connects to a green-screen proxy or Cloudflare Worker.\n * The backend holds the TCP connection to the legacy host and relays protocol data.\n *\n * Unlike RestAdapter (which polls over HTTP), this adapter receives real-time\n * screen updates via WebSocket push.\n *\n * workerUrl resolution order:\n * 1. Explicit `workerUrl` option\n * 2. VITE_GREEN_SCREEN_URL / VITE_WORKER_URL (Vite)\n * 3. NEXT_PUBLIC_GREEN_SCREEN_URL (Next.js)\n * 4. REACT_APP_GREEN_SCREEN_URL (CRA)\n * 5. http://localhost:3001\n */\nexport class WebSocketAdapter implements TerminalAdapter {\n private workerUrl: string;\n private ws: WebSocket | null = null;\n private screen: ScreenData | null = null;\n private status: ConnectionStatus = { connected: false, status: 'disconnected' };\n private pendingScreenResolver: ((value: ScreenData | null) => void) | null = null;\n private pendingConnectResolver: ((result: SendResult) => void) | null = null;\n private pendingMdtResolver: ((fields: FieldValue[]) => void) | null = null;\n private connectingPromise: Promise<void> | null = null;\n private screenListeners: Set<(screen: ScreenData) => void> = new Set();\n private statusListeners: Set<(status: ConnectionStatus) => void> = new Set();\n private sessionLostListeners: Set<(sessionId: string, status: ConnectionStatus) => void> = new Set();\n private sessionResumedListeners: Set<(sessionId: string) => void> = new Set();\n private _sessionId: string | null = null;\n\n constructor(options: WebSocketAdapterOptions = {}) {\n this.workerUrl = (\n options.workerUrl\n || WebSocketAdapter.detectEnvUrl()\n || 'http://localhost:3001'\n ).replace(/\\/+$/, '');\n }\n\n private static detectEnvUrl(): string | undefined {\n try {\n if (typeof import.meta !== 'undefined' && (import.meta as any).env) {\n const env = (import.meta as any).env;\n return env.VITE_GREEN_SCREEN_URL || env.VITE_WORKER_URL || undefined;\n }\n } catch { /* import.meta not available */ }\n try {\n // Use indirect eval to avoid static analysis picking up 'process' as a Node global\n const p = typeof globalThis !== 'undefined' && (globalThis as any).process;\n if (p && p.env) {\n return p.env.NEXT_PUBLIC_GREEN_SCREEN_URL\n || p.env.REACT_APP_GREEN_SCREEN_URL\n || undefined;\n }\n } catch { /* process not available */ }\n return undefined;\n }\n\n /** The proxy-side session ID (available after connect or reattach) */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /** Subscribe to real-time screen updates */\n onScreen(listener: (screen: ScreenData) => void): () => void {\n this.screenListeners.add(listener);\n return () => this.screenListeners.delete(listener);\n }\n\n /** Subscribe to status changes */\n onStatus(listener: (status: ConnectionStatus) => void): () => void {\n this.statusListeners.add(listener);\n return () => this.statusListeners.delete(listener);\n }\n\n /**\n * Subscribe to session-lost notifications. Fires when the proxy detects\n * that the server-side session has terminated (host TCP drop, idle\n * timeout, explicit destroy). Integrators use this to prompt a reconnect\n * or swap to a \"session expired\" UI without relying on error-string\n * matching.\n */\n onSessionLost(listener: (sessionId: string, status: ConnectionStatus) => void): () => void {\n this.sessionLostListeners.add(listener);\n return () => this.sessionLostListeners.delete(listener);\n }\n\n /** Subscribe to session-resumed notifications (fires after a successful `reattach`). */\n onSessionResumed(listener: (sessionId: string) => void): () => void {\n this.sessionResumedListeners.add(listener);\n return () => this.sessionResumedListeners.delete(listener);\n }\n\n async getScreen(): Promise<ScreenData | null> {\n return this.screen;\n }\n\n async getStatus(): Promise<ConnectionStatus> {\n return this.status;\n }\n\n async sendText(text: string): Promise<SendResult> {\n return this.sendAndWaitForScreen({ type: 'text', text });\n }\n\n async sendKey(key: string): Promise<SendResult> {\n return this.sendAndWaitForScreen({ type: 'key', key });\n }\n\n async setCursor(row: number, col: number): Promise<SendResult> {\n return this.sendAndWaitForScreen({ type: 'setCursor', row, col });\n }\n\n async readMdt(modifiedOnly: boolean = true): Promise<FieldValue[]> {\n await this.ensureWebSocket();\n return new Promise((resolve) => {\n // Only one in-flight MDT read at a time — flush any prior resolver\n if (this.pendingMdtResolver) {\n const old = this.pendingMdtResolver;\n this.pendingMdtResolver = null;\n old([]);\n }\n const timeout = setTimeout(() => {\n this.pendingMdtResolver = null;\n resolve([]);\n }, 5000);\n this.pendingMdtResolver = (fields) => {\n clearTimeout(timeout);\n resolve(fields);\n };\n this.wsSend({ type: 'readMdt', modifiedOnly });\n });\n }\n\n async connect(config?: ConnectConfig): Promise<SendResult> {\n await this.ensureWebSocket();\n\n if (!config) {\n return { success: false, error: 'ConnectConfig required' };\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.pendingConnectResolver = null;\n resolve({ success: false, error: 'Connection timeout' });\n }, 30000);\n\n this.pendingConnectResolver = (result: SendResult) => {\n clearTimeout(timeout);\n resolve(result);\n };\n\n this.wsSend({\n type: 'connect',\n host: config.host,\n port: config.port,\n protocol: config.protocol,\n username: config.username,\n password: config.password,\n terminalType: config.terminalType,\n });\n });\n }\n\n /**\n * Reattach to an existing proxy session (e.g. after page reload).\n * The proxy keeps the TCP connection alive; this just reconnects the\n * WebSocket and receives the current screen.\n */\n async reattach(sessionId: string): Promise<SendResult> {\n await this.ensureWebSocket();\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n this.pendingConnectResolver = null;\n resolve({ success: false, error: 'Reattach timeout' });\n }, 10000);\n\n this.pendingConnectResolver = (result: SendResult) => {\n clearTimeout(timeout);\n resolve(result);\n };\n\n this.wsSend({ type: 'reattach', sessionId });\n });\n }\n\n async disconnect(): Promise<SendResult> {\n this.wsSend({ type: 'disconnect' });\n this.status = { connected: false, status: 'disconnected' };\n this._sessionId = null;\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n return { success: true };\n }\n\n async reconnect(): Promise<SendResult> {\n return { success: false, error: 'Use disconnect() then connect() instead' };\n }\n\n /** Close the WebSocket without sending disconnect (session stays alive on proxy) */\n dispose(): void {\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n\n private async ensureWebSocket(): Promise<void> {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) return;\n if (this.connectingPromise) return this.connectingPromise;\n\n this.connectingPromise = new Promise<void>((resolve, reject) => {\n const wsUrl = this.workerUrl.replace(/^http/, 'ws') + '/ws';\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => resolve();\n this.ws.onerror = () => reject(new Error('WebSocket connection failed'));\n\n this.ws.onmessage = (event) => {\n try {\n const msg = JSON.parse(event.data);\n this.handleMessage(msg);\n } catch { /* ignore non-JSON messages */ }\n };\n\n this.ws.onclose = () => {\n this.status = { connected: false, status: 'disconnected' };\n for (const listener of this.statusListeners) listener(this.status);\n };\n }).finally(() => {\n this.connectingPromise = null;\n });\n\n return this.connectingPromise;\n }\n\n private handleMessage(msg: any): void {\n switch (msg.type) {\n case 'screen': {\n this.screen = msg.data;\n for (const listener of this.screenListeners) listener(msg.data);\n if (this.pendingScreenResolver) {\n const resolver = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n resolver(msg.data);\n }\n break;\n }\n\n case 'cursor': {\n // Lightweight cursor-only response for local operations (arrows, Tab)\n // Resolve pending promise with just cursor position, no screen update\n if (this.pendingScreenResolver) {\n const resolver = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n resolver({\n cursor_row: msg.data.cursor_row,\n cursor_col: msg.data.cursor_col,\n content: this.screen?.content ?? '',\n screen_signature: this.screen?.screen_signature ?? '',\n } as any);\n }\n break;\n }\n\n case 'mdt': {\n if (this.pendingMdtResolver) {\n const resolver = this.pendingMdtResolver;\n this.pendingMdtResolver = null;\n resolver(msg.data?.fields ?? []);\n }\n break;\n }\n\n case 'session.lost': {\n for (const listener of this.sessionLostListeners) listener(msg.sessionId, msg.status);\n break;\n }\n\n case 'session.resumed': {\n for (const listener of this.sessionResumedListeners) listener(msg.sessionId);\n break;\n }\n\n case 'status':\n this.status = msg.data;\n for (const listener of this.statusListeners) listener(msg.data);\n break;\n\n case 'connected':\n this._sessionId = msg.sessionId ?? null;\n if (this.pendingConnectResolver) {\n const resolver = this.pendingConnectResolver;\n this.pendingConnectResolver = null;\n resolver({ success: true });\n }\n break;\n\n case 'error': {\n if (this.pendingConnectResolver) {\n const resolver = this.pendingConnectResolver;\n this.pendingConnectResolver = null;\n resolver({ success: false, error: msg.message });\n } else if (this.pendingScreenResolver) {\n const resolver = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n resolver(null);\n }\n break;\n }\n }\n }\n\n private sendAndWaitForScreen(msg: object): Promise<SendResult> {\n return new Promise((resolve) => {\n // Flush any existing pending resolver with current screen data\n if (this.pendingScreenResolver) {\n const old = this.pendingScreenResolver;\n this.pendingScreenResolver = null;\n old(this.screen);\n }\n\n const timeout = setTimeout(() => {\n this.pendingScreenResolver = null;\n resolve({ success: true, ...this.screenToResult() });\n }, 5000);\n\n this.pendingScreenResolver = (screen: ScreenData | null) => {\n clearTimeout(timeout);\n if (screen) {\n resolve({\n success: true,\n cursor_row: screen.cursor_row,\n cursor_col: screen.cursor_col,\n content: screen.content,\n screen_signature: screen.screen_signature,\n });\n } else {\n resolve({ success: false, error: 'No screen data received' });\n }\n };\n\n this.wsSend(msg);\n });\n }\n\n private screenToResult(): Partial<SendResult> {\n if (!this.screen) return {};\n return {\n cursor_row: this.screen.cursor_row,\n cursor_col: this.screen.cursor_col,\n content: this.screen.content,\n screen_signature: this.screen.screen_signature,\n };\n }\n\n private wsSend(data: object): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(data));\n }\n }\n}\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport type { TerminalAdapter, ScreenData, ConnectionStatus, SendResult, ConnectConfig } from '../adapters/types';\n\n/**\n * Hook for terminal connection management via adapter.\n */\nexport function useTerminalConnection(adapter: TerminalAdapter) {\n const [status, setStatus] = useState<ConnectionStatus | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const fetchStatus = useCallback(async () => {\n try {\n const result = await adapter.getStatus();\n setStatus(result);\n return result;\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return null;\n }\n }, [adapter]);\n\n const connect = useCallback(async (config?: ConnectConfig) => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.connect(config);\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n const disconnect = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n await adapter.disconnect();\n setStatus(prev => prev ? { ...prev, connected: false, status: 'disconnected' } : null);\n return { success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n const reconnect = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.reconnect();\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n return { status, loading, error, fetchStatus, connect, disconnect, reconnect };\n}\n\n/**\n * Hook for terminal screen content with polling.\n */\nexport function useTerminalScreen(\n adapter: TerminalAdapter,\n interval: number = 2000,\n enabled: boolean = true,\n) {\n const [data, setData] = useState<ScreenData | null>(null);\n const [error, setError] = useState<unknown>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n useEffect(() => {\n if (!enabled) {\n if (intervalRef.current) clearInterval(intervalRef.current);\n return;\n }\n\n const poll = async () => {\n try {\n const screen = await adapter.getScreen();\n if (screen) setData(screen);\n setError(null);\n } catch (err) {\n setError(err);\n }\n };\n\n poll(); // Initial fetch\n intervalRef.current = setInterval(poll, interval);\n\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, [adapter, interval, enabled]);\n\n return { data, error };\n}\n\n/**\n * Hook for terminal operations (sendText, sendKey).\n */\nexport function useTerminalInput(adapter: TerminalAdapter) {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const sendText = useCallback(async (text: string): Promise<SendResult> => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.sendText(text);\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n const sendKey = useCallback(async (key: string): Promise<SendResult> => {\n setLoading(true);\n setError(null);\n try {\n const result = await adapter.sendKey(key);\n return { ...result, success: true };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n return { success: false, error: message };\n } finally {\n setLoading(false);\n }\n }, [adapter]);\n\n return { loading, error, sendText, sendKey };\n}\n","import { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { positionToRowCol, isFieldEntry } from '../utils/grid';\n\n/**\n * Hook for typing animation effect on terminal screen content.\n * Reveals characters progressively when screen content changes.\n * Also provides animated cursor position that follows the typing.\n *\n * Uses a queue-based model: incoming content updates are queued when an\n * animation is in progress, then played sequentially. This prevents\n * blinks (no mid-animation cancellation) and skips (every field entry\n * gets its own animation). Queue depth is capped to avoid falling\n * behind real-time.\n *\n * Screen transitions (large changes) always display SYNCHRONOUSLY.\n */\nexport function useTypingAnimation(\n content: string | null | undefined,\n enabled: boolean = true,\n typingBudgetMs: number = 100,\n) {\n const FRAME_DELAY = 16; // ~60fps\n\n const previousContentRef = useRef('');\n const targetContentRef = useRef('');\n const contentQueueRef = useRef<string[]>([]);\n const isAnimatingRef = useRef(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rafRef = useRef<number | null>(null);\n\n const [animatedContent, setAnimatedContent] = useState('');\n const [isAnimating, setIsAnimating] = useState(false);\n const [animatedCursorPos, setAnimatedCursorPos] = useState<{ row: number; col: number } | null>(null);\n\n const cancelAnimation = () => {\n if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; }\n if (rafRef.current) { cancelAnimationFrame(rafRef.current); rafRef.current = null; }\n };\n\n const showInstant = useCallback((c: string) => {\n cancelAnimation();\n setAnimatedContent(c);\n setAnimatedCursorPos(null);\n setIsAnimating(false);\n isAnimatingRef.current = false;\n previousContentRef.current = c;\n targetContentRef.current = '';\n }, []);\n\n const processNextRef = useRef<(() => void) | null>(null);\n\n const startFieldAnimation = useCallback((fromContent: string, toContent: string) => {\n let diffStart = -1;\n let diffEnd = 0;\n const maxLen = Math.max(fromContent.length, toContent.length);\n for (let i = 0; i < maxLen; i++) {\n if ((fromContent[i] || ' ') !== (toContent[i] || ' ')) {\n if (diffStart === -1) diffStart = i;\n diffEnd = i;\n }\n }\n if (diffStart === -1) { showInstant(toContent); return; }\n\n setIsAnimating(true);\n isAnimatingRef.current = true;\n targetContentRef.current = toContent;\n\n const diffLength = diffEnd - diffStart + 1;\n\n const oldRegion = fromContent.substring(diffStart, diffEnd + 1);\n const isCorrection = oldRegion.replace(/[_\\s\\n]/g, '').length > 0;\n\n const finishAnimation = () => {\n setAnimatedContent(toContent);\n setIsAnimating(false);\n isAnimatingRef.current = false;\n setAnimatedCursorPos(null);\n previousContentRef.current = toContent;\n targetContentRef.current = '';\n timeoutRef.current = null;\n rafRef.current = null;\n if (processNextRef.current) processNextRef.current();\n };\n\n if (isCorrection) {\n const CORRECTION_BUDGET = 400;\n const removalBudget = Math.floor(CORRECTION_BUDGET * 0.4);\n const typingBudget = CORRECTION_BUDGET - removalBudget;\n const removalFrames = Math.max(2, Math.floor(removalBudget / FRAME_DELAY));\n const typingFrames = Math.max(2, Math.floor(typingBudget / FRAME_DELAY));\n const removalCPF = Math.max(1, Math.ceil(diffLength / removalFrames));\n const typingCPF = Math.max(1, Math.ceil(diffLength / typingFrames));\n\n let removePos = diffEnd + 1;\n let typePos = diffStart;\n\n const buildRemovalContent = (erasedFrom: number) => {\n const before = fromContent.substring(0, diffStart);\n const remaining = fromContent.substring(diffStart, erasedFrom);\n const erased = ' '.repeat(Math.max(0, diffEnd + 1 - erasedFrom));\n const after = toContent.substring(diffEnd + 1);\n return before + remaining + erased + after;\n };\n\n const buildTypingContent = (revealedUpTo: number) => {\n const before = toContent.substring(0, diffStart);\n const revealed = toContent.substring(diffStart, revealedUpTo);\n const hidden = toContent.substring(revealedUpTo, diffEnd + 1).replace(/[^\\n]/g, ' ');\n const after = toContent.substring(diffEnd + 1);\n return before + revealed + hidden + after;\n };\n\n const animateTyping = () => {\n typePos += typingCPF;\n if (typePos >= diffEnd + 1) {\n finishAnimation();\n } else {\n setAnimatedContent(buildTypingContent(typePos));\n setAnimatedCursorPos(positionToRowCol(toContent, typePos));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateTyping);\n }, FRAME_DELAY);\n }\n };\n\n const animateRemoval = () => {\n removePos -= removalCPF;\n if (removePos <= diffStart) {\n setAnimatedContent(buildTypingContent(diffStart));\n setAnimatedCursorPos(positionToRowCol(toContent, diffStart));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateTyping);\n }, FRAME_DELAY);\n } else {\n setAnimatedContent(buildRemovalContent(removePos));\n setAnimatedCursorPos(positionToRowCol(fromContent, removePos));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateRemoval);\n }, FRAME_DELAY);\n }\n };\n\n setAnimatedCursorPos(positionToRowCol(fromContent, diffEnd));\n setAnimatedContent(buildRemovalContent(diffEnd + 1));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animateRemoval);\n }, FRAME_DELAY);\n } else {\n let currentPos = diffStart;\n const totalFrames = Math.max(1, Math.floor(typingBudgetMs / FRAME_DELAY));\n const charsPerFrame = Math.max(1, Math.ceil(diffLength / totalFrames));\n\n setAnimatedCursorPos(positionToRowCol(toContent, diffStart));\n\n const buildDisplayContent = (revealedUpTo: number) => {\n const before = toContent.substring(0, diffStart);\n const revealed = toContent.substring(diffStart, revealedUpTo);\n const hidden = toContent.substring(revealedUpTo, diffEnd + 1).replace(/[^\\n]/g, ' ');\n const after = toContent.substring(diffEnd + 1);\n return before + revealed + hidden + after;\n };\n\n const animate = () => {\n currentPos += charsPerFrame;\n if (currentPos >= diffEnd + 1) {\n finishAnimation();\n } else {\n setAnimatedContent(buildDisplayContent(currentPos));\n setAnimatedCursorPos(positionToRowCol(toContent, currentPos));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animate);\n }, FRAME_DELAY);\n }\n };\n\n setAnimatedContent(buildDisplayContent(diffStart));\n timeoutRef.current = setTimeout(() => {\n rafRef.current = requestAnimationFrame(animate);\n }, FRAME_DELAY);\n }\n }, [showInstant, typingBudgetMs]);\n\n processNextRef.current = () => {\n const queue = contentQueueRef.current;\n if (queue.length === 0) return;\n\n while (queue.length > 2) queue.shift();\n\n const next = queue.shift()!;\n const base = previousContentRef.current;\n\n if (isFieldEntry(base, next)) {\n startFieldAnimation(base, next);\n } else {\n showInstant(next);\n if (queue.length > 0 && processNextRef.current) processNextRef.current();\n }\n };\n\n const shouldAnimate = enabled && content && isFieldEntry(previousContentRef.current, content);\n if (!shouldAnimate && !isAnimatingRef.current && content !== previousContentRef.current) {\n previousContentRef.current = content || '';\n }\n\n useEffect(() => {\n if (!enabled || !content) {\n cancelAnimation();\n contentQueueRef.current = [];\n showInstant(content || '');\n previousContentRef.current = content || '';\n return;\n }\n\n const currentTarget = targetContentRef.current || previousContentRef.current;\n if (content === currentTarget) return;\n\n if (isAnimatingRef.current) {\n if (!isFieldEntry(currentTarget, content)) {\n contentQueueRef.current = [];\n showInstant(content);\n } else {\n contentQueueRef.current.push(content);\n if (contentQueueRef.current.length > 3) {\n contentQueueRef.current = contentQueueRef.current.slice(-2);\n }\n }\n return;\n }\n\n const prev = previousContentRef.current;\n if (!isFieldEntry(prev, content)) {\n showInstant(content);\n return;\n }\n startFieldAnimation(prev, content);\n\n return cancelAnimation;\n }, [content, enabled, showInstant, startFieldAnimation]);\n\n const animationActive = isAnimatingRef.current;\n\n const displayedContent = useMemo(() => {\n if (!enabled || !content) return content || '';\n if (animationActive) return animatedContent;\n return content;\n }, [enabled, content, animationActive, animatedContent]);\n\n const effectiveCursorPos = animationActive ? animatedCursorPos : null;\n\n return { displayedContent, isAnimating, animatedCursorPos: effectiveCursorPos };\n}\n","/**\n * Convert a linear position in screen content to row/col coordinates.\n * Content is lines of characters separated by newlines.\n */\nexport function positionToRowCol(content: string, position: number): { row: number; col: number } {\n let row = 0;\n let col = 0;\n for (let i = 0; i < position && i < content.length; i++) {\n if (content[i] === '\\n') {\n row++;\n col = 0;\n } else {\n col++;\n }\n }\n return { row, col };\n}\n\n/**\n * Detect if a content change is a field entry (small, localized change)\n * vs a screen transition (large, distributed change).\n *\n * Field entries: < 50 changed characters within a span of < 100 positions.\n * Screen transitions: everything else.\n */\nexport function isFieldEntry(previousContent: string | null | undefined, content: string | null | undefined): boolean {\n if (!previousContent || !content) return false;\n\n let diffCount = 0;\n let diffStart = -1;\n let diffEnd = 0;\n const maxLen = Math.max(previousContent.length, content.length);\n\n for (let i = 0; i < maxLen; i++) {\n const oldChar = previousContent[i] || ' ';\n const newChar = content[i] || ' ';\n if (oldChar !== newChar) {\n diffCount++;\n if (diffStart === -1) diffStart = i;\n diffEnd = i;\n }\n }\n\n const diffSpan = diffEnd - diffStart + 1;\n // Field entry: small number of changes (< 50 chars), localized (span < 100)\n return diffCount > 2 && diffCount < 50 && diffSpan < 100;\n}\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const tn5250Profile: ProtocolProfile = {\n protocol: 'tn5250',\n displayName: 'IBM TN5250',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: 'TN5250 TERMINAL',\n bootText: 'TN5250',\n colors: {\n getRowColorClass(rowIndex: number, rowContent: string, totalRows: number): string {\n if (rowIndex === 0 && rowContent.trim().length > 0) return 'gs-row-title';\n if (rowIndex >= totalRows - 2) return 'gs-row-fkey';\n if (/F\\d{1,2}=/.test(rowContent)) return 'gs-row-fkey';\n if (/Select one of the following/i.test(rowContent)) return 'gs-row-subtitle';\n return 'gs-row-content';\n },\n parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n if (line.trim().length === 0) return null;\n const trimmed = line.trimStart();\n const leftMatch = trimmed.match(/^(\\S+)/);\n if (leftMatch) {\n const leftId = leftMatch[1];\n const leftEnd = line.indexOf(leftId) + leftId.length;\n const rightMatch = line.trimEnd().match(/(\\S+)$/);\n if (rightMatch && rightMatch[1] !== leftId) {\n const rightStart = line.lastIndexOf(rightMatch[1]);\n return [\n { text: line.substring(0, leftEnd), colorClass: 'gs-row-fkey' },\n { text: line.substring(leftEnd, rightStart), colorClass: 'gs-row-title' },\n { text: line.substring(rightStart), colorClass: 'gs-row-content' },\n ];\n }\n }\n return [{ text: line, colorClass: 'gs-row-title' }];\n },\n },\n};\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const tn3270Profile: ProtocolProfile = {\n protocol: 'tn3270',\n displayName: 'IBM TN3270',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: 'TN3270 TERMINAL',\n bootText: 'TN3270',\n colors: {\n getRowColorClass(rowIndex: number, rowContent: string, totalRows: number): string {\n // z/OS ISPF conventions: row 0 = title, last 2 rows = PF keys/command\n if (rowIndex === 0 && rowContent.trim().length > 0) return 'gs-row-title';\n if (rowIndex >= totalRows - 2) return 'gs-row-fkey';\n if (/PF\\d{1,2}[=/]/.test(rowContent) || /F\\d{1,2}=/.test(rowContent)) return 'gs-row-fkey';\n if (/COMMAND\\s*===>/i.test(rowContent) || /===>/.test(rowContent)) return 'gs-row-subtitle';\n if (/OPTION\\s*===>/i.test(rowContent)) return 'gs-row-subtitle';\n return 'gs-row-content';\n },\n parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n if (line.trim().length === 0) return null;\n // ISPF: typically \"Menu Utilities Compilers ...\" action bar or panel title\n const trimmed = line.trimStart();\n const leftMatch = trimmed.match(/^(\\S+)/);\n if (leftMatch) {\n const leftId = leftMatch[1];\n const leftEnd = line.indexOf(leftId) + leftId.length;\n const rightMatch = line.trimEnd().match(/(\\S+)$/);\n if (rightMatch && rightMatch[1] !== leftId) {\n const rightStart = line.lastIndexOf(rightMatch[1]);\n return [\n { text: line.substring(0, leftEnd), colorClass: 'gs-row-fkey' },\n { text: line.substring(leftEnd, rightStart), colorClass: 'gs-row-title' },\n { text: line.substring(rightStart), colorClass: 'gs-row-content' },\n ];\n }\n }\n return [{ text: line, colorClass: 'gs-row-title' }];\n },\n },\n};\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const vtProfile: ProtocolProfile = {\n protocol: 'vt',\n displayName: 'VT Terminal',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: 'VT TERMINAL',\n bootText: 'VT220',\n colors: {\n getRowColorClass(_rowIndex: number, _rowContent: string, _totalRows: number): string {\n // VT terminals use inline escape-sequence-driven colors, not row-based conventions.\n // All rows default to green; actual colors come from ANSI attributes in the data stream.\n return 'gs-row-content';\n },\n parseHeaderRow(_line: string): { text: string; colorClass: string }[] | null {\n // VT has no header row convention\n return null;\n },\n },\n};\n","import type { ProtocolProfile } from '../adapters/types';\n\nexport const hp6530Profile: ProtocolProfile = {\n protocol: 'hp6530',\n displayName: 'HP 6530',\n defaultRows: 24,\n defaultCols: 80,\n headerLabel: '6530 TERMINAL',\n bootText: 'HP6530',\n colors: {\n getRowColorClass(rowIndex: number, rowContent: string, totalRows: number): string {\n // HP NonStop 6530: row 0 = status/title, last row = function key labels\n if (rowIndex === 0 && rowContent.trim().length > 0) return 'gs-row-title';\n if (rowIndex >= totalRows - 1) return 'gs-row-fkey';\n if (/F\\d{1,2}[=\\-]/.test(rowContent) || /SF\\d{1,2}/.test(rowContent)) return 'gs-row-fkey';\n return 'gs-row-content';\n },\n parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n if (line.trim().length === 0) return null;\n return [{ text: line, colorClass: 'gs-row-title' }];\n },\n },\n};\n","import type { TerminalProtocol, ProtocolProfile } from '../adapters/types';\nimport { tn5250Profile } from './tn5250';\nimport { tn3270Profile } from './tn3270';\nimport { vtProfile } from './vt';\nimport { hp6530Profile } from './hp6530';\n\nconst profiles: Record<TerminalProtocol, ProtocolProfile> = {\n tn5250: tn5250Profile,\n tn3270: tn3270Profile,\n vt: vtProfile,\n hp6530: hp6530Profile,\n};\n\n/**\n * Get a protocol profile by type. Defaults to TN5250 for backward compatibility.\n */\nexport function getProtocolProfile(protocol?: TerminalProtocol): ProtocolProfile {\n return profiles[protocol || 'tn5250'];\n}\n","import React, { useState, useEffect, useRef } from 'react';\n\nexport interface TerminalBootLoaderProps {\n /** Text to display during boot animation */\n brandText?: string;\n /** Speed in ms per character */\n charSpeed?: number;\n /** Optional logo element to render alongside the text */\n logo?: React.ReactNode;\n /** Height of the boot loader container */\n height?: number | string;\n}\n\n/**\n * Animated boot loader for the terminal.\n * Shows a typewriter-style text reveal animation.\n */\nexport function TerminalBootLoader({\n brandText = 'TERMINAL',\n charSpeed = 80,\n logo,\n height = 504,\n}: TerminalBootLoaderProps) {\n const [charCount, setCharCount] = useState(0);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n useEffect(() => {\n intervalRef.current = setInterval(() => {\n setCharCount(prev => {\n if (prev >= brandText.length) {\n if (intervalRef.current) clearInterval(intervalRef.current);\n return prev;\n }\n return prev + 1;\n });\n }, charSpeed);\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, [brandText, charSpeed]);\n\n const displayed = brandText.substring(0, charCount);\n\n return (\n <div\n className=\"gs-boot-loader\"\n style={{\n height: typeof height === 'number' ? `${height}px` : height,\n backgroundColor: 'var(--gs-bg, #000)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontFamily: 'var(--gs-font)',\n fontSize: '13px',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>\n {logo}\n <h1\n style={{\n fontFamily: 'var(--gs-font)',\n fontSize: '1.5rem',\n letterSpacing: '0.1em',\n color: 'var(--gs-green, #10b981)',\n textShadow: '0 0 12px rgba(16, 185, 129, 0.4)',\n margin: 0,\n }}\n >\n {displayed}\n <span\n className=\"tn5250-cursor\"\n style={{\n display: 'inline-block',\n width: '0.6ch',\n height: '1.2em',\n verticalAlign: 'middle',\n marginLeft: '2px',\n }}\n />\n </h1>\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nexport const TerminalIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"4 17 10 11 4 5\" /><line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\" />\n </svg>\n);\n\nexport const WifiIcon = ({ size = 12, className, style: s }: { size?: number; className?: string; style?: React.CSSProperties }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} style={s}>\n <path d=\"M5 12.55a11 11 0 0 1 14.08 0\" /><path d=\"M1.42 9a16 16 0 0 1 21.16 0\" /><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\" /><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\" />\n </svg>\n);\n\nexport const WifiOffIcon = ({ size = 12, className, style: s }: { size?: number; className?: string; style?: React.CSSProperties }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} style={s}>\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" /><path d=\"M16.72 11.06A10.94 10.94 0 0 1 19 12.55\" /><path d=\"M5 12.55a10.94 10.94 0 0 1 5.17-2.39\" /><path d=\"M10.71 5.05A16 16 0 0 1 22.56 9\" /><path d=\"M1.42 9a15.91 15.91 0 0 1 4.7-2.88\" /><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\" /><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\" />\n </svg>\n);\n\nexport const AlertTriangleIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\" /><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" /><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n);\n\nexport const RefreshIcon = ({ size = 12, className }: { size?: number; className?: string }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}>\n <polyline points=\"23 4 23 10 17 10\" /><polyline points=\"1 20 1 14 7 14\" /><path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\" />\n </svg>\n);\n\nexport const KeyIcon = ({ size = 12, style: s }: { size?: number; style?: React.CSSProperties }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={s}>\n <path d=\"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4\" />\n </svg>\n);\n\nexport const HelpIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\" /><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n);\n\nexport const KeyboardIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\" ry=\"2\" />\n <line x1=\"6\" y1=\"10\" x2=\"6\" y2=\"10\" /><line x1=\"10\" y1=\"10\" x2=\"10\" y2=\"10\" />\n <line x1=\"14\" y1=\"10\" x2=\"14\" y2=\"10\" /><line x1=\"18\" y1=\"10\" x2=\"18\" y2=\"10\" />\n <line x1=\"6\" y1=\"14\" x2=\"6\" y2=\"14\" /><line x1=\"18\" y1=\"14\" x2=\"18\" y2=\"14\" />\n <line x1=\"10\" y1=\"14\" x2=\"14\" y2=\"14\" />\n </svg>\n);\n\nexport const MinimizeIcon = () => (\n <svg width={14} height={14} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M4 14h6v6M3 21l7-7M20 10h-6V4M21 3l-7 7\" />\n </svg>\n);\n","import React, { useState } from 'react';\nimport type { TerminalProtocol, ConnectConfig } from '../adapters/types';\nimport { TerminalIcon, AlertTriangleIcon, RefreshIcon } from './Icons';\n\nconst PROTOCOL_OPTIONS: { value: TerminalProtocol; label: string }[] = [\n { value: 'tn5250', label: 'TN5250 (IBM i)' },\n { value: 'tn3270', label: 'TN3270 (Mainframe)' },\n { value: 'vt', label: 'VT220' },\n { value: 'hp6530', label: 'HP 6530 (NonStop)' },\n];\n\n/** Terminal type options per protocol (only protocols with >1 option need a dropdown) */\nconst TERMINAL_TYPE_OPTIONS: Partial<Record<TerminalProtocol, { value: string; label: string }[]>> = {\n tn5250: [\n { value: 'IBM-3179-2', label: '24 × 80 (Standard)' },\n { value: 'IBM-3477-FC', label: '27 × 132 (Wide)' },\n ],\n tn3270: [\n { value: 'IBM-3278-2', label: '24 × 80 (Model 2)' },\n { value: 'IBM-3278-3', label: '32 × 80 (Model 3)' },\n { value: 'IBM-3278-4', label: '43 × 80 (Model 4)' },\n { value: 'IBM-3278-5', label: '27 × 132 (Model 5)' },\n ],\n};\n\nexport interface InlineSignInProps {\n defaultProtocol: TerminalProtocol;\n loading: boolean;\n error: string | null;\n onConnect: (config: ConnectConfig) => void;\n}\n\nexport function InlineSignIn({ defaultProtocol, loading: externalLoading, error, onConnect }: InlineSignInProps) {\n const [host, setHost] = useState('');\n const [port, setPort] = useState('');\n const [selectedProtocol, setSelectedProtocol] = useState<TerminalProtocol>(defaultProtocol);\n const [terminalType, setTerminalType] = useState('');\n const [username, setUsername] = useState('');\n const [password, setPassword] = useState('');\n\n const termTypeOptions = TERMINAL_TYPE_OPTIONS[selectedProtocol];\n const [submitted, setSubmitted] = useState(false);\n\n const loading = externalLoading || submitted;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setSubmitted(true);\n onConnect({\n host,\n port: port ? parseInt(port, 10) : 23,\n protocol: selectedProtocol,\n ...(username.trim() ? { username: username.trim() } : {}),\n ...(password ? { password } : {}),\n ...(terminalType ? { terminalType } : {}),\n });\n };\n\n const inputStyle: React.CSSProperties = {\n width: '100%',\n padding: '6px 8px',\n backgroundColor: 'rgba(16, 185, 129, 0.05)',\n border: '1px solid var(--gs-card-border, #1e293b)',\n color: 'var(--gs-green, #10b981)',\n fontFamily: 'var(--gs-font)',\n fontSize: '13px',\n outline: 'none',\n boxSizing: 'border-box',\n };\n\n const labelStyle: React.CSSProperties = {\n display: 'block',\n marginBottom: '4px',\n fontSize: '10px',\n letterSpacing: '0.1em',\n textTransform: 'uppercase',\n color: 'var(--gs-muted, #94a3b8)',\n fontFamily: 'var(--gs-font)',\n };\n\n if (loading) {\n return (\n <div className=\"gs-signin\" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '12px' }}>\n <RefreshIcon size={28} className=\"gs-spin\" />\n <div style={{ fontSize: '11px', letterSpacing: '0.15em', textTransform: 'uppercase', color: 'var(--gs-muted)', fontFamily: 'var(--gs-font)' }}>\n Connecting to {host || 'host'}...\n </div>\n </div>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"gs-signin\">\n <div style={{ textAlign: 'center', marginBottom: '16px' }}>\n <TerminalIcon size={28} />\n <div style={{ fontSize: '11px', letterSpacing: '0.15em', textTransform: 'uppercase', color: 'var(--gs-muted)', marginTop: '8px' }}>Connect to Host</div>\n </div>\n\n <div className=\"gs-signin-row\">\n <div style={{ flex: 1 }}>\n <label style={labelStyle}>Host <span style={{ color: '#ef4444' }}>*</span></label>\n <input style={inputStyle} value={host} onChange={e => setHost(e.target.value)} placeholder=\"192.168.1.100\" required autoFocus />\n </div>\n <div style={{ width: '72px' }}>\n <label style={labelStyle}>Port</label>\n <input style={inputStyle} value={port} onChange={e => setPort(e.target.value)} placeholder=\"23\" type=\"number\" min=\"1\" max=\"65535\" />\n </div>\n </div>\n\n <div>\n <label style={labelStyle}>Protocol <span style={{ color: '#ef4444' }}>*</span></label>\n <select style={{ ...inputStyle, appearance: 'none' }} value={selectedProtocol} onChange={e => { setSelectedProtocol(e.target.value as TerminalProtocol); setTerminalType(''); }}>\n {PROTOCOL_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}\n </select>\n </div>\n\n {termTypeOptions && termTypeOptions.length > 1 && (\n <div>\n <label style={labelStyle}>Screen Size</label>\n <select style={{ ...inputStyle, appearance: 'none' }} value={terminalType || termTypeOptions[0].value} onChange={e => setTerminalType(e.target.value)}>\n {termTypeOptions.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}\n </select>\n </div>\n )}\n\n <div>\n <label style={labelStyle}>Username</label>\n <input style={inputStyle} value={username} onChange={e => setUsername(e.target.value)} autoComplete=\"username\" />\n </div>\n\n <div>\n <label style={labelStyle}>Password</label>\n <input style={inputStyle} type=\"password\" value={password} onChange={e => setPassword(e.target.value)} autoComplete=\"current-password\" />\n </div>\n\n {error && (\n <div style={{ color: '#FF6B00', fontSize: '11px', fontFamily: 'var(--gs-font)', display: 'flex', alignItems: 'center', gap: '6px' }}>\n <AlertTriangleIcon size={12} />\n <span>{error}</span>\n </div>\n )}\n\n <button type=\"submit\" disabled={!host} className=\"gs-signin-btn\">\n Connect\n </button>\n </form>\n );\n}\n","/**\n * 5250 attribute byte decoding for the frontend.\n *\n * These helpers map raw attribute bytes from the host into CSS-friendly\n * color / decoration values. They are used for:\n *\n * - `Field.highlight_entry_attr` (FCW 0x89xx) — replacement attribute\n * applied when the cursor is inside the field.\n * - `ScreenData.ext_attrs[]` — per-cell extended attributes set via WEA\n * (Write Extended Attribute) orders.\n *\n * 5250 attribute byte layout (0x20–0x3F range):\n * Bit 5 (0x20) is always set (marker bit).\n * Bits 4-3 select the color group: 00=green, 01=red, 10=turq, 11=pink.\n * Bit 2 (0x04): column separators.\n * Bit 1 (0x02): intensity — HI shifts color group to its bright variant\n * (green→white, turq→yellow, pink→blue). Red stays red.\n * Bit 0 (0x01): blink / non-display select bit within the 0x07 subfield.\n *\n * Lower 3 bits encode display type:\n * 0 normal, 1 column-separator, 2 hi-intensity, 3 col-sep + HI,\n * 4 underscore, 5 underscore + reverse, 6 underscore + HI, 7 non-display.\n */\n\nimport type { FieldColor, CellExtAttr } from '../adapters/types';\n\n/** Decoded visual properties for a 5250 attribute byte. */\nexport interface DecodedAttr {\n color: FieldColor;\n highIntensity: boolean;\n underscore: boolean;\n reverse: boolean;\n blink: boolean;\n nonDisplay: boolean;\n columnSeparator: boolean;\n}\n\n/**\n * Decode a raw 5250 attribute byte (typically in 0x20–0x3F) into visual\n * properties usable for CSS rendering.\n */\nexport function decodeAttrByte(byte: number): DecodedAttr {\n const type = byte & 0x07;\n const colorGroup = byte & 0x18; // bits 4-3\n const highIntensity = (byte & 0x02) !== 0;\n\n // Color group → FieldColor\n let color: FieldColor = 'green';\n switch (colorGroup) {\n case 0x00: color = highIntensity ? 'white' : 'green'; break;\n case 0x08: color = 'red'; break; // red stays red at HI\n case 0x10: color = highIntensity ? 'yellow' : 'turquoise'; break;\n case 0x18: color = highIntensity ? 'blue' : 'pink'; break;\n }\n\n // Lower 3 bits encode display type\n const nonDisplay = type === 0x07;\n const underscore = type === 0x04 || type === 0x05 || type === 0x06;\n const reverse = type === 0x05; // underscore + reverse\n const columnSeparator = type === 0x01 || type === 0x03;\n const hiTypeBit = type === 0x02 || type === 0x03 || type === 0x06;\n\n return {\n color,\n highIntensity: highIntensity || hiTypeBit,\n underscore,\n reverse,\n blink: false, // 5250 has no base-attr blink; blink comes from WEA highlight\n nonDisplay,\n columnSeparator,\n };\n}\n\n/**\n * Decode a WEA \"extended color\" byte (WEA type 0x01) into a FieldColor.\n *\n * Per IBM 5250 Functions Reference the low nibble selects one of 8 base\n * colors; bit 3 (0x08) selects the \"reverse image\" pair (bright variant).\n *\n * 0x00 green 0x08 green (reverse)\n * 0x01 blue 0x09 blue (reverse)\n * 0x02 red 0x0A red (reverse)\n * 0x03 pink 0x0B pink (reverse)\n * 0x04 turquoise 0x0C turquoise (reverse)\n * 0x05 yellow 0x0D yellow (reverse)\n * 0x06 white 0x0E white (reverse)\n * 0x07 default/inherit (returns undefined)\n *\n * The \"reverse image\" variants are the host-specified bright/alternate\n * shades; we map them to distinct FieldColor values where available so\n * the CSS layer can theme them independently.\n */\nexport function decodeExtColor(byte: number): FieldColor | undefined {\n switch (byte & 0x0F) {\n case 0x00: return 'green';\n case 0x01: return 'blue';\n case 0x02: return 'red';\n case 0x03: return 'pink';\n case 0x04: return 'turquoise';\n case 0x05: return 'yellow';\n case 0x06: return 'white';\n case 0x07: return undefined; // default — inherit\n // Reverse-image pairs: distinct tokens so themes can override\n case 0x08: return 'green'; // reverse green → typically same color, background flip\n case 0x09: return 'blue';\n case 0x0A: return 'red';\n case 0x0B: return 'pink';\n case 0x0C: return 'turquoise';\n case 0x0D: return 'yellow';\n case 0x0E: return 'white';\n case 0x0F: return undefined;\n default: return undefined;\n }\n}\n\n/**\n * Return true if a WEA color byte uses the \"reverse image\" pair bit (0x08).\n * Callers can use this to apply a background swap in addition to `decodeExtColor`.\n */\nexport function extColorIsReverse(byte: number): boolean {\n const v = byte & 0x0F;\n return v >= 0x08 && v <= 0x0E;\n}\n\n/** Decoded extended-highlight properties from WEA type 0x02. */\nexport interface DecodedExtHighlight {\n underscore: boolean;\n reverse: boolean;\n blink: boolean;\n columnSeparator: boolean;\n}\n\n/**\n * Decode a WEA \"extended highlight\" byte (WEA type 0x02).\n * Bits are additive:\n * 0x01 underscore, 0x02 reverse, 0x04 blink, 0x08 column separators.\n */\nexport function decodeExtHighlight(byte: number): DecodedExtHighlight {\n return {\n underscore: (byte & 0x01) !== 0,\n reverse: (byte & 0x02) !== 0,\n blink: (byte & 0x04) !== 0,\n columnSeparator: (byte & 0x08) !== 0,\n };\n}\n\n/**\n * Merge a cell's extended attribute on top of a base field attribute,\n * producing the final visual properties for that specific cell.\n *\n * Absent fields in the extended attribute inherit from the base.\n */\nexport function mergeExtAttr(base: DecodedAttr, ext: CellExtAttr | undefined): DecodedAttr {\n if (!ext) return base;\n const out: DecodedAttr = { ...base };\n if (ext.color !== undefined) {\n const c = decodeExtColor(ext.color);\n if (c) out.color = c;\n }\n if (ext.highlight !== undefined) {\n const h = decodeExtHighlight(ext.highlight);\n if (h.underscore) out.underscore = true;\n if (h.reverse) out.reverse = true;\n if (h.blink) out.blink = true;\n if (h.columnSeparator) out.columnSeparator = true;\n }\n return out;\n}\n\n/**\n * Resolve a CSS color variable for a FieldColor using the `--gs-*` tokens.\n */\nexport function cssVarForColor(color: FieldColor | undefined): string {\n if (!color) return 'var(--gs-green, #10b981)';\n return `var(--gs-${color}, var(--gs-green, #10b981))`;\n}\n","/**\n * Client-side field validation helpers for 5250 input fields.\n *\n * These mirror the validation that a real 5250 display station performs\n * before letting the user Enter/submit. Running them in the browser avoids\n * a host round-trip for predictable errors.\n */\n\nimport type { Field } from '../adapters/types';\n\n/**\n * Filter a single typed character against a field's 5250 shift-type.\n * Returns the character (possibly transformed, e.g. uppercased) if it is\n * allowed, or null if it should be rejected.\n *\n * Per 5250 Functions Reference:\n * - alpha_only — A-Z a-z , - . space\n * - numeric_only — 0-9 + - , . space (and '+' is re-mapped by some hosts)\n * - digits_only — 0-9 only\n * - signed_num — 0-9 in all positions except the last, which accepts sign\n * - katakana — half-width katakana + ASCII digits (CP290 range)\n * - ideographic — DBCS characters only (handled separately via is_dbcs)\n * Other shift types accept anything.\n *\n * Monocase fields auto-uppercase ASCII letters.\n */\nexport function filterFieldChar(\n field: Field,\n ch: string,\n /** Is this character the last position in the field? (relevant for signed_num) */\n isLastPosition: boolean = false,\n): string | null {\n // Monocase: convert before shift-type check so case-insensitive rules apply\n let out = ch;\n if (field.monocase) {\n out = out.toUpperCase();\n }\n\n const cp = out.charCodeAt(0);\n const isAsciiLetter = (cp >= 0x41 && cp <= 0x5A) || (cp >= 0x61 && cp <= 0x7A);\n const isAsciiDigit = cp >= 0x30 && cp <= 0x39;\n\n switch (field.shift_type) {\n case 'alpha_only': {\n if (isAsciiLetter || out === ',' || out === '-' || out === '.' || out === ' ') return out;\n return null;\n }\n case 'numeric_only': {\n if (isAsciiDigit || out === '-' || out === '+' || out === ',' || out === '.' || out === ' ') return out;\n return null;\n }\n case 'digits_only': {\n if (isAsciiDigit) return out;\n return null;\n }\n case 'signed_num': {\n // Sign nibble allowed only at the last position, digits elsewhere.\n if (isAsciiDigit) return out;\n if (isLastPosition && (out === '-' || out === '+')) return out;\n return null;\n }\n case 'katakana': {\n // Accept half-width katakana (U+FF61–U+FF9F), space, and ASCII digits.\n if ((cp >= 0xFF61 && cp <= 0xFF9F) || isAsciiDigit || out === ' ') return out;\n return null;\n }\n case 'alpha':\n case 'numeric_shift':\n case 'io':\n case undefined:\n default:\n return out;\n }\n}\n\n/**\n * Filter an entire typed string against a field's shift-type.\n * Returns the transformed string (drops rejected characters) and whether\n * any characters were rejected (so the caller can ring a visual bell).\n */\nexport function filterFieldInput(\n field: Field,\n input: string,\n /** Current column inside the field (0-based from field.col). */\n startOffset: number,\n): { out: string; rejected: boolean } {\n let out = '';\n let rejected = false;\n for (let i = 0; i < input.length; i++) {\n const pos = startOffset + i;\n const isLast = pos === field.length - 1;\n const transformed = filterFieldChar(field, input[i], isLast);\n if (transformed === null) {\n rejected = true;\n } else {\n out += transformed;\n }\n }\n return { out, rejected };\n}\n\n/**\n * Validate a field value against the MOD10 (Luhn) self-check rule.\n * Used for credit-card numbers, account numbers, and similar fields.\n * The last digit of the value is the check digit.\n *\n * Returns true if valid or the value is empty/too short.\n */\nexport function validateMod10(value: string): boolean {\n const digits = value.replace(/\\D/g, '');\n if (digits.length < 2) return true;\n\n let sum = 0;\n let alt = false;\n for (let i = digits.length - 1; i >= 0; i--) {\n let d = digits.charCodeAt(i) - 48;\n if (alt) {\n d *= 2;\n if (d > 9) d -= 9;\n }\n sum += d;\n alt = !alt;\n }\n return sum % 10 === 0;\n}\n\n/**\n * Validate a field value against the MOD11 self-check rule.\n * Used for ISBN-like identifiers and some account-number schemes.\n * The last digit is the check digit (X = 10 is NOT used in 5250).\n *\n * Returns true if valid or the value is empty/too short.\n */\nexport function validateMod11(value: string): boolean {\n const digits = value.replace(/\\D/g, '');\n if (digits.length < 2) return true;\n\n const body = digits.slice(0, -1);\n const check = digits.charCodeAt(digits.length - 1) - 48;\n\n let sum = 0;\n let weight = 2;\n for (let i = body.length - 1; i >= 0; i--) {\n sum += (body.charCodeAt(i) - 48) * weight;\n weight++;\n if (weight > 7) weight = 2;\n }\n const remainder = sum % 11;\n const expected = remainder === 0 ? 0 : 11 - remainder;\n return expected === check;\n}\n\n/**\n * Return true if the code point is a DBCS (double-byte) character.\n * Covers CJK Unified Ideographs, Hiragana, Katakana (full-width),\n * Hangul, and common CJK punctuation / symbols.\n */\nexport function isDbcsChar(ch: string): boolean {\n const cp = ch.codePointAt(0);\n if (cp === undefined) return false;\n return (\n (cp >= 0x3000 && cp <= 0x303F) || // CJK Symbols and Punctuation\n (cp >= 0x3040 && cp <= 0x309F) || // Hiragana\n (cp >= 0x30A0 && cp <= 0x30FF) || // Katakana (full-width)\n (cp >= 0x3400 && cp <= 0x4DBF) || // CJK Unified Ideographs Ext A\n (cp >= 0x4E00 && cp <= 0x9FFF) || // CJK Unified Ideographs\n (cp >= 0xF900 && cp <= 0xFAFF) || // CJK Compatibility Ideographs\n (cp >= 0xFF00 && cp <= 0xFF60) || // Full-width ASCII\n (cp >= 0xFFE0 && cp <= 0xFFE6) || // Full-width signs\n cp >= 0x20000 // CJK Ext B+\n );\n}\n\n/** Return true if every character in the value is DBCS (all CJK). */\nexport function isAllDbcs(value: string): boolean {\n if (value.length === 0) return true;\n for (const ch of value) {\n if (ch === ' ') continue;\n if (!isDbcsChar(ch)) return false;\n }\n return true;\n}\n","import { getProtocolProfile } from '../protocols/registry';\n\n/**\n * Get the appropriate CSS class name for a row.\n * Delegates to the TN5250 protocol profile for backward compatibility.\n *\n * For protocol-aware rendering, use `getProtocolProfile(protocol).colors.getRowColorClass()`.\n */\nexport function getRowColorClass(rowIndex: number, rowContent: string): string {\n return getProtocolProfile('tn5250').colors.getRowColorClass(rowIndex, rowContent, 24);\n}\n\n/**\n * Parse the header row into colored segments.\n * Delegates to the TN5250 protocol profile for backward compatibility.\n *\n * For protocol-aware rendering, use `getProtocolProfile(protocol).colors.parseHeaderRow()`.\n */\nexport function parseHeaderRow(line: string): { text: string; colorClass: string }[] | null {\n return getProtocolProfile('tn5250').colors.parseHeaderRow(line);\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","style"]}