herm-tui 1.11.0-dev.7 → 1.11.0-dev.9

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.
Files changed (3) hide show
  1. package/db.worker.js +1 -1
  2. package/index.js +18 -18
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -3455,7 +3455,7 @@ ${end.comment}`:end.comment}this.doc.range[2]=end.offset;break}default:this.erro
3455
3455
  JOIN messages m ON m.id = messages_fts.rowid
3456
3456
  JOIN sessions s ON s.id = m.session_id
3457
3457
  WHERE messages_fts MATCH ?
3458
- ORDER BY rank LIMIT ?`)?.all(m2,limit*4)??[],seen=new Set;return raw.filter((r)=>!seen.has(r.session_id)&&(seen.add(r.session_id),!0)).slice(0,limit)}finally{end()}}function rename(sid,title){let db=new Database(conn.path);try{return db.run("UPDATE sessions SET title = ? WHERE id = ?",[title,sid]),db.query("SELECT changes() AS c").get().c>0}finally{db.close()}}function remove(sid){let db=new Database(conn.path);try{if(!db.query("SELECT 1 FROM sessions WHERE id = ?").get(sid))return!1;return db.run("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?",[sid]),db.run("DELETE FROM messages WHERE session_id = ?",[sid]),db.run("DELETE FROM sessions WHERE id = ?",[sid]),!0}finally{db.close()}}var HERMES,SRC,conn,setHome=(h2)=>{let next=`${h2}/state.db`;if(conn.path===next)return;conn.path=SRC.file=next,resetDb()},stateDb=()=>{if(conn.ro)return conn.ro;try{return conn.ro=new Database(conn.path,{readwrite:!0,create:!1})}catch{return null}},resetDb=()=>{for(let s of stmts.values())s.finalize();stmts.clear(),msgCols.clear(),conn.ro?.close(),conn.ro=null},stmts,msgCols,q2=(sql)=>{let db=stateDb();if(!db)return null;let s=stmts.get(sql);if(!s)stmts.set(sql,s=db.query(sql));return s},hasMsgCol=(name)=>{let hit=msgCols.get(name);if(hit!==void 0)return hit;let db=stateDb(),ok=db?db.query("PRAGMA table_info(messages)").all().some((r)=>r.name===name):!1;return msgCols.set(name,ok),ok},SUB=(c)=>`(p.ended_at IS NULL OR ${c}.started_at < p.ended_at)`,CONT=(c)=>`(p.end_reason = 'compression' AND ${c}.started_at >= p.ended_at)`,BR=(c)=>`(p.end_reason = 'branched' AND ${c}.started_at >= p.ended_at)`,kind=(parent2,child)=>{if(!parent2)return"root";if(parent2.ended_at==null||child.started_at<parent2.ended_at)return"subagent";if(parent2.end_reason==="compression")return"continuation";if(parent2.end_reason==="branched")return"branch";return"subagent"},COLS=`
3458
+ ORDER BY rank LIMIT ?`)?.all(m2,limit*4)??[],seen=new Set;return raw.filter((r)=>!seen.has(r.session_id)&&(seen.add(r.session_id),!0)).slice(0,limit)}finally{end()}}function rename(sid,title){let db=new Database(conn.path);try{return db.run("UPDATE sessions SET title = ? WHERE id = ?",[title,sid]),db.query("SELECT changes() AS c").get().c>0}finally{db.close()}}function remove(sid){let db=new Database(conn.path);try{return db.transaction((id)=>{if(!db.query("SELECT 1 FROM sessions WHERE id = ?").get(id))return!1;return db.run("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?",[id]),db.run("DELETE FROM messages WHERE session_id = ?",[id]),db.run("DELETE FROM sessions WHERE id = ?",[id]),!0})(sid)}finally{db.close()}}var HERMES,SRC,conn,setHome=(h2)=>{let next=`${h2}/state.db`;if(conn.path===next)return;conn.path=SRC.file=next,resetDb()},stateDb=()=>{if(conn.ro)return conn.ro;try{return conn.ro=new Database(conn.path,{readwrite:!0,create:!1})}catch{return null}},resetDb=()=>{for(let s of stmts.values())s.finalize();stmts.clear(),msgCols.clear(),conn.ro?.close(),conn.ro=null},stmts,msgCols,q2=(sql)=>{let db=stateDb();if(!db)return null;let s=stmts.get(sql);if(!s)stmts.set(sql,s=db.query(sql));return s},hasMsgCol=(name)=>{let hit=msgCols.get(name);if(hit!==void 0)return hit;let db=stateDb(),ok=db?db.query("PRAGMA table_info(messages)").all().some((r)=>r.name===name):!1;return msgCols.set(name,ok),ok},SUB=(c)=>`(p.ended_at IS NULL OR ${c}.started_at < p.ended_at)`,CONT=(c)=>`(p.end_reason = 'compression' AND ${c}.started_at >= p.ended_at)`,BR=(c)=>`(p.end_reason = 'branched' AND ${c}.started_at >= p.ended_at)`,kind=(parent2,child)=>{if(!parent2)return"root";if(parent2.ended_at==null||child.started_at<parent2.ended_at)return"subagent";if(parent2.end_reason==="compression")return"continuation";if(parent2.end_reason==="branched")return"branch";return"subagent"},COLS=`
3459
3459
  s.id, s.source, s.model, s.billing_provider, s.started_at, s.ended_at, s.end_reason,
3460
3460
  s.message_count, s.tool_call_count,
3461
3461
  s.input_tokens, s.output_tokens,
@@ -3507,8 +3507,8 @@ ${end.comment}`:end.comment}this.doc.range[2]=end.offset;break}default:this.erro
3507
3507
  s.title
3508
3508
  FROM messages m LEFT JOIN sessions s ON m.session_id = s.id
3509
3509
  WHERE m.role = 'assistant' AND m.tool_calls IS NOT NULL
3510
- ORDER BY m.id DESC LIMIT ?`).all(scan),out=[];for(let r of rows2)for(let a of extract2(r))if(out.push(a),out.length>=limit)return out;return out}var WRITE,READ,MEMORY_TOOLS,trunc4=(s,n=80)=>{let t2=String(s??"").replace(/\s+/g," ").trim();return t2.length>n?t2.slice(0,n-1)+"\u2026":t2},stripPrefix=(name)=>name.replace(/^(mem0|honcho|hindsight|viking|retaindb|supermemory|brv|fact)_/,""),describe=(name,args)=>{if(name==="memory"){let action=String(args.action??""),target=String(args.target??""),body=action==="remove"?args.old_text:args.content??args.old_text;return{verb:action,summary:`${target}: ${trunc4(body)}`}}let verb=stripPrefix(name);for(let k2 of["conclusion","content","query","text","fact","question","note","path"])if(k2 in args)return{verb,summary:trunc4(args[k2])};let first=Object.values(args).find((v2)=>typeof v2==="string");return{verb,summary:trunc4(first??"")}},extract2=(r)=>{let calls;try{calls=JSON.parse(r.tool_calls)}catch{return[]}if(!Array.isArray(calls))return[];let out=[];for(let c of calls){let name=c.function?.name;if(!name||!(name in MEMORY_TOOLS))continue;let args={};try{args=JSON.parse(c.function?.arguments??"{}")}catch{}let{verb,summary}=describe(name,args);out.push({ts:r.ts,provider:MEMORY_TOOLS[name],tool:name,op:name in WRITE?"write":"read",verb,summary,sessionId:r.session_id,sessionTitle:r.title??r.session_id})}return out};var init_memory_activity=__esm(()=>{init_sessions_db();WRITE={memory:"builtin",mem0_conclude:"mem0",honcho_conclude:"honcho",hindsight_retain:"hindsight",hindsight_reflect:"hindsight",fact_store:"holographic",fact_feedback:"holographic",viking_remember:"openviking",viking_add_resource:"openviking",retaindb_remember:"retaindb",retaindb_forget:"retaindb",supermemory_store:"supermemory",supermemory_forget:"supermemory",brv_curate:"byterover"},READ={mem0_search:"mem0",mem0_profile:"mem0",honcho_search:"honcho",honcho_profile:"honcho",honcho_reasoning:"honcho",honcho_context:"honcho",hindsight_recall:"hindsight",viking_search:"openviking",viking_read:"openviking",viking_browse:"openviking",retaindb_search:"retaindb",retaindb_profile:"retaindb",retaindb_context:"retaindb",supermemory_search:"supermemory",supermemory_profile:"supermemory",brv_query:"byterover",brv_status:"byterover"},MEMORY_TOOLS={...WRITE,...READ}});var exports_fns={};__export(exports_fns,{FNS:()=>FNS});var FNS;var init_fns=__esm(()=>{init_sessions_db();init_hermes_analytics();init_memory_activity();FNS={roots:exports_sessions_db.roots,children:exports_sessions_db.children,lineage:exports_sessions_db.lineage,peek:exports_sessions_db.peek,search:exports_sessions_db.search,systemPrompt:exports_sessions_db.systemPrompt,goalState:exports_sessions_db.goalState,analytics,memoryActivity:readMemoryActivity}});var SCHEMA,SCHEMA_KEYS;var init_schema=__esm(()=>{SCHEMA={"agent.api_max_retries":{type:"int",default:3,doc:"Max app-level retry attempts for API errors (connection drops, provider timeouts, 5xx, etc.) before the agent surfaces the failure. The OpenAI SDK already does its own low-level retries (max_retries=2 default) for transient network errors; this is the Hermes-level retry loop that wraps the whole call. Lower this to 1 if you use fallback providers and want fast failover on flaky primaries; raise it if you prefer to tolerate longer provider hiccups on a single provider.",group:"agent",effect:"session"},"agent.clarify_timeout":{type:"int",default:3600,doc:`Maximum time (seconds) the gateway will block an agent waiting for a clarify-tool response from the user. Hit this and the agent unblocks with "[user did not respond within Xm]" so it can adapt rather than pinning the running-agent guard forever. CLI clarify blocks indefinitely (input() is synchronous) and ignores this. Default 3600 (1h): real users step away (meetings, AFK) and the old 600s default evicted the entry mid-think, so a later button tap landed on a dead entry (#32762). Tradeoff: a higher value holds the gateway's running-agent guard longer for a genuinely abandoned prompt \u2014 lower it if a single session must free up the guard sooner.`,group:"agent",effect:"session"},"agent.coding_context":{type:"str",default:"auto",doc:`Coding posture \u2014 on interactive coding surfaces (CLI, TUI, desktop app, ACP) in a code workspace, Hermes adds a coding operating brief + a live git/workspace snapshot to the system prompt. See agent/coding_context.py. "auto" (default) \u2014 prompt-only posture when the surface is interactive AND cwd is a code workspace. Toolsets are never touched; messaging platforms unaffected. "focus" \u2014 auto + collapse the toolset to the lean coding set (+ enabled MCP servers) + demote non-coding skill categories to names-only in the prompt's skill index. Explicit opt-in. "on" \u2014 force the prompt posture everywhere. "off" \u2014 disable entirely.`,group:"agent",effect:"session"},"agent.coding_instructions":{type:"str",default:"",doc:`Standing operator instructions for the coding posture. A string (or list of strings) appended to the coding brief as an extra stable system block \u2014 pin project-wide workflow rules here instead of editing the shipped brief, e.g. "For UI work, don't run tsc/lint until I approve. Clean the diff before you commit and push." Cache-safe: takes effect next session. Empty by default.`,group:"agent",effect:"session"},"agent.disabled_toolsets":{type:"list",default:[],doc:"",group:"agent",effect:"session"},"agent.environment_hint":{type:"str",default:"",doc:"Embedder-supplied environment description appended to the system prompt's environment-hints block. Lets a host that wraps Hermes (sandbox runner, managed platform) explain the runtime environment \u2014 proxy, credential handling, mount layout \u2014 without editing the identity slot (SOUL.md). Empty by default. The HERMES_ENVIRONMENT_HINT env var overrides this (build-time/container mechanism).",group:"agent",effect:"session"},"agent.environment_probe":{type:"bool",default:!0,doc:"Local-environment toolchain probe \u2014 surfaces Python/pip/uv/PEP-668 state in the system prompt when something non-default is detected (e.g. python3 has no pip module, pip\u2192python version mismatch, PEP 668 enforcement without uv). Costs zero tokens when the env is clean (probe emits nothing). Skipped for remote terminal backends (docker/modal/ssh \u2014 they have their own probe). Set False to disable entirely.",group:"agent",effect:"session"},"agent.gateway_auto_continue_freshness":{type:"int",default:3600,doc:`Freshness window for the gateway auto-continue note (seconds). After a gateway crash/restart/SIGTERM mid-run, the next user message gets a "[System note: your previous turn was interrupted \u2014 process the unfinished tool result(s) first]" prepended so the model picks up where it left off. That's the right behaviour while the interruption is fresh, but stale markers (transcript last touched hours or days ago) can revive an unrelated old task when the user's next message starts new work. This window is the max age of the last persisted transcript row for which we still inject the continue note. Default 3600s comfortably covers a long turn (gateway_timeout default is 1800s) plus runtime slack. Set to 0 to disable the gate and restore pre-fix behaviour (always inject).`,group:"agent",effect:"session"},"agent.gateway_notify_interval":{type:"int",default:180,doc:`Periodic "still working" notification interval (seconds). Sends a status message every N seconds so the user knows the agent hasn't died during long tasks. 0 = disable notifications. Lower values mean faster feedback on slow tasks but more chat noise; 180s is a compromise that catches spinning weak-model runs (60+ tool iterations with tiny output) before users assume the bot is dead and /restart.`,group:"agent",effect:"session"},"agent.gateway_timeout":{type:"int",default:1800,doc:"Inactivity timeout for gateway agent execution (seconds). The agent can run indefinitely as long as it's actively calling tools or receiving API responses. Only fires when the agent has been completely idle for this duration. 0 = unlimited.",group:"agent",effect:"session"},"agent.gateway_timeout_warning":{type:"int",default:900,doc:"Staged inactivity warning: send a warning to the user at this threshold before escalating to a full timeout. The warning fires once per run and does not interrupt the agent. 0 = disable warning.",group:"agent",effect:"session"},"agent.image_input_mode":{type:"str",default:"auto",doc:`How user-attached images are presented to the main model on each turn. "auto" \u2014 attach natively when the active model reports supports_vision=True AND the user hasn't explicitly configured auxiliary.vision.provider. Otherwise fall back to text (vision_analyze pre-analysis). "native" \u2014 always attach natively; non-vision models will either error at the provider or get a last-chance text fallback (see run_agent._prepare_messages_for_api). "text" \u2014 always pre-analyze with vision_analyze and prepend the description as text; the main model never sees pixels. Affects gateway platforms, the TUI, and CLI /attach. vision_analyze remains available as a tool regardless of this setting \u2014 the routing only controls how inbound user images are presented.`,group:"agent",effect:"session"},"agent.intent_ack_continuation":{type:"str",default:"auto",doc:`Intent-ack continuation: when the model opens a turn by narrating an action it will take ("I'll go check the logs...") but emits no tool call, intercept the turn-end, inject a "continue now, execute the tools" nudge, and loop instead of ending the turn (capped at 2 nudges per turn). This is the corrective sibling of tool_use_enforcement (the preventive prompt-side guard). Values: "auto" (default \u2014 fires only on the codex_responses api_mode, the historical behavior), true (all api_modes \u2014 fixes the Gemini/Claude "stops after stating intent" case), false (never), or a list of model-name substrings to match.`,group:"agent",effect:"session"},"agent.max_turns":{type:"int",default:90,doc:"",group:"agent",effect:"session"},"agent.max_verify_nudges":{type:"int",default:3,doc:'Upper bound on consecutive `pre_verify` "continue" nudges in a single turn, so a user/plugin hook can never trap the loop.',group:"agent",effect:"session"},"agent.parallel_tool_call_guidance":{type:"bool",default:!0,doc:"Universal parallel-tool-call guidance \u2014 short prompt block applied to all models that tells the model to batch independent tool calls (reads, searches, web fetches, read-only commands) into one turn instead of one call per turn. The runtime already runs independent calls concurrently, so this just steers the model to produce the batch \u2014 cutting round-trips and the resent-context cost that compounds over a long conversation. Costs ~70 tokens in the cached system prompt. Set False to disable globally.",group:"agent",effect:"session"},"agent.reasoning_effort":{type:"str",default:"",doc:"Reasoning effort for the main agent: none | minimal | low | medium | high | xhigh.",group:"agent",effect:"live"},"agent.restart_drain_timeout":{type:"int",default:0,doc:`Graceful drain timeout for gateway stop/restart (seconds). The gateway stops accepting new work, waits for running agents to finish, then interrupts any remaining runs after the timeout. 0 = no drain, interrupt immediately (the default). Contract: if you restart the gateway, in-flight work stops. We do not hold the restart open for a grace window \u2014 a drain timeout large enough to "save" a long agent turn would have to outlast an unbounded task (some runs take days), which is impossible, and a drain timeout shorter than systemd's TimeoutStopSec invites a SIGKILL-mid-cleanup race that leaves a stale lock and crash-loops the service. 0 sidesteps both: interrupt now, clean up, exit fast. Set a positive value in config.yaml only if you explicitly want a grace window on /restart (and keep it well under TimeoutStopSec).`,group:"agent",effect:"session"},"agent.service_tier":{type:"str",default:"",doc:"",group:"agent",effect:"live"},"agent.system_prompt":{type:"str",default:"",doc:"System-prompt override applied by the active personality.",group:"agent",effect:"session"},"agent.task_completion_guidance":{type:"bool",default:!0,doc:'Universal "finish the job" guidance \u2014 short prompt block applied to all models that targets two cross-family failure modes: (1) stopping after a stub instead of finishing the artifact, (2) fabricating plausible-looking output when a real path is blocked. Costs ~80 tokens in the cached system prompt. Set False to disable globally.',group:"agent",effect:"session"},"agent.tool_use_enforcement":{type:"str",default:"auto",doc:'Tool-use enforcement: injects system prompt guidance that tells the model to actually call tools instead of describing intended actions. Values: "auto" (default \u2014 applies to gpt/codex models), true/false (force on/off for all models), or a list of model-name substrings to match (e.g. ["gpt", "codex", "gemini", "qwen"]).',group:"agent",effect:"session"},"agent.verify_guidance":{type:"bool",default:!0,doc:"When verify-on-stop finds edited code without fresh verification evidence, append guidance for creative UI work (avoid broad tsc/lint/test before visual approval) and clean-diff expectations. Set false to keep the evidence nudge terse.",group:"agent",effect:"session"},"agent.verify_on_stop":{type:"str",default:"auto",doc:'Verification closure: after the agent edits files in a code workspace, do not accept a final answer until fresh verification evidence exists or the agent explains why it cannot run checks. The loop is bounded and uses the passive verification ledger. Default is "auto" \u2014 surface-aware: on for interactive coding surfaces (CLI, TUI, desktop) and programmatic callers, off for conversational messaging surfaces (Telegram, Discord, etc.) where the verification narrative would reach a human as chat noise. Doc/markdown/skill-only edits never fire it. Set true to force on everywhere, or false to disable.',group:"agent",effect:"session"},"approvals.cron_mode":{type:"str",default:"deny",doc:"",group:"approvals",effect:"live"},"approvals.deny":{type:"list",default:[],doc:'User-defined deny rules: fnmatch globs matched against terminal commands. A match blocks the command unconditionally \u2014 BEFORE the --yolo / /yolo / mode=off bypass \u2014 making this the user-editable counterpart to the code-shipped hardline blocklist. Patterns are case-insensitive and must be quoted in YAML when they start with * or contain {}/!/: sequences. Example: deny: - "git push --force*" - "*curl*|*sh*"',group:"approvals",effect:"live"},"approvals.destructive_slash_confirm":{type:"bool",default:!0,doc:'When true, destructive session slash commands (/clear, /new, /reset, /undo) ask the user to confirm before discarding conversation state. Three-option prompt (Approve Once / Always Approve / Cancel) routed through tools.slash_confirm \u2014 native yes/no buttons on Telegram, Discord, and Slack; text fallback elsewhere. Users click "Always Approve" to silence the prompt permanently; that flips this key to false. TUI has its own modal overlay (HERMES_TUI_NO_CONFIRM=1 to opt out there).',group:"approvals",effect:"live"},"approvals.mcp_reload_confirm":{type:"bool",default:!0,doc:'When true, /reload-mcp asks the user to confirm before rebuilding the MCP tool set for the active session. Reloading invalidates the provider prompt cache (tool schemas are baked into the system prompt), so the next message re-sends full input tokens \u2014 this can be expensive on long-context or high-reasoning models. Users click "Always Approve" to silence the prompt permanently; that flips this key to false.',group:"approvals",effect:"live"},"approvals.mode":{type:"str",default:"manual",doc:"",group:"approvals",effect:"live"},"approvals.timeout":{type:"int",default:60,doc:"",group:"approvals",effect:"live"},"auxiliary.approval.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.model":{type:"str",default:"",doc:"fast/cheap model recommended (e.g. gemini-flash, haiku)",group:"auxiliary",effect:"session"},"auxiliary.approval.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.timeout":{type:"int",default:120,doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.timeout":{type:"int",default:120,doc:"seconds \u2014 compression summarises large contexts; increase for local models",group:"auxiliary",effect:"session"},"auxiliary.curator.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.timeout":{type:"int",default:600,doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.timeout":{type:"int",default:180,doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.timeout":{type:"int",default:900,doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.timeout":{type:"int",default:900,doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.timeout":{type:"int",default:60,doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.timeout":{type:"int",default:60,doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.language":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.transient_retries":{type:"int",default:2,doc:"Same-provider retries for a transient transport blip (connection reset / timeout / 5xx / 408) on ANY auxiliary call before falling back. Default 2 (\u2192 3 total attempts), clamped [0,6]. Matters most for pinned calls like MoA reference advisors, where provider fallback is not a meaningful recovery, so an unretried blip silently loses the call.",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.timeout":{type:"int",default:120,doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.vision.api_key":{type:"str",default:"",doc:"API key for base_url (falls back to OPENAI_API_KEY)",group:"auxiliary",effect:"session"},"auxiliary.vision.base_url":{type:"str",default:"",doc:"direct OpenAI-compatible endpoint (takes precedence over provider)",group:"auxiliary",effect:"session"},"auxiliary.vision.download_timeout":{type:"int",default:30,doc:"seconds \u2014 image HTTP download timeout; increase for slow connections",group:"auxiliary",effect:"session"},"auxiliary.vision.extra_body":{type:"dict",default:{},doc:"OpenAI-compatible provider-specific request fields",group:"auxiliary",effect:"session"},"auxiliary.vision.model":{type:"str",default:"",doc:'e.g. "google/gemini-2.5-flash", "gpt-4o"',group:"auxiliary",effect:"session"},"auxiliary.vision.provider":{type:"str",default:"auto",doc:"auto | openrouter | nous | codex | custom",group:"auxiliary",effect:"session"},"auxiliary.vision.timeout":{type:"int",default:120,doc:"seconds \u2014 LLM API call timeout; vision payloads need generous timeout",group:"auxiliary",effect:"session"},"auxiliary.web_extract.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.timeout":{type:"int",default:360,doc:"seconds (6min) \u2014 per-attempt LLM summarization timeout; increase for slow local models",group:"auxiliary",effect:"session"},"bedrock.discovery.enabled":{type:"bool",default:!0,doc:"Auto-discover models via ListFoundationModels",group:"bedrock",effect:"live"},"bedrock.discovery.provider_filter":{type:"list",default:[],doc:'Only show models from these providers (e.g. ["anthropic", "amazon"])',group:"bedrock",effect:"live"},"bedrock.discovery.refresh_interval":{type:"int",default:3600,doc:"Cache discovery results for this many seconds",group:"bedrock",effect:"live"},"bedrock.guardrail.guardrail_identifier":{type:"str",default:"",doc:"Amazon Bedrock Guardrails \u2014 content filtering and safety policies. Create a guardrail in the Bedrock console, then set the ID and version here. See: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html",group:"bedrock",effect:"live"},"bedrock.guardrail.guardrail_version":{type:"str",default:"",doc:'e.g. "1" or "DRAFT"',group:"bedrock",effect:"live"},"bedrock.guardrail.stream_processing_mode":{type:"str",default:"async",doc:'"sync" or "async"',group:"bedrock",effect:"live"},"bedrock.guardrail.trace":{type:"str",default:"disabled",doc:'"enabled", "disabled", or "enabled_full"',group:"bedrock",effect:"live"},"bedrock.region":{type:"str",default:"",doc:"AWS region for Bedrock API calls (empty = AWS_REGION env var \u2192 us-east-1)",group:"bedrock",effect:"live"},"browser.allow_private_urls":{type:"bool",default:!1,doc:"Allow navigating to private/internal IPs (localhost, 192.168.x.x, etc.)",group:"browser",effect:"live"},"browser.allow_unsafe_evaluate":{type:"bool",default:!1,doc:"Allow browser_console(expression=...) to use sensitive JS primitives (cookies/storage/clipboard/network/form values)",group:"browser",effect:"live"},"browser.auto_local_for_private_urls":{type:"bool",default:!0,doc:"When a cloud provider is set, auto-spawn local Chromium for LAN/localhost URLs instead of sending them to the cloud",group:"browser",effect:"live"},"browser.camofox.adopt_existing_tab":{type:"bool",default:!1,doc:"Rehydrate tab_id from Camofox before creating a new tab.",group:"browser",effect:"live"},"browser.camofox.loopback_host_alias":{type:"str",default:"host.docker.internal",doc:"",group:"browser",effect:"live"},"browser.camofox.managed_persistence":{type:"bool",default:!1,doc:"When true, Hermes sends a stable profile-scoped userId to Camofox so the server maps it to a persistent Firefox profile automatically. When false (default), each session gets a random userId (ephemeral).",group:"browser",effect:"live"},"browser.camofox.rewrite_loopback_urls":{type:"bool",default:!1,doc:"Docker Camofox opens page URLs from inside the container. Enable this to rewrite loopback page URLs (localhost/127.0.0.1/::1) to a host alias while leaving CAMOFOX_URL itself unchanged.",group:"browser",effect:"live"},"browser.camofox.session_key":{type:"str",default:"",doc:"",group:"browser",effect:"live"},"browser.camofox.user_id":{type:"str",default:"",doc:"Optional externally managed Camofox identity. Useful when another app owns the visible browser and Hermes should operate in it.",group:"browser",effect:"live"},"browser.cdp_url":{type:"str",default:"",doc:"Optional persistent CDP endpoint for attaching to an existing Chromium/Chrome",group:"browser",effect:"live"},"browser.command_timeout":{type:"int",default:30,doc:"Timeout for browser commands in seconds (screenshot, navigate, etc.)",group:"browser",effect:"live"},"browser.dialog_policy":{type:"str",default:"must_respond",doc:"CDP supervisor \u2014 dialog + frame detection via a persistent WebSocket. Active only when a CDP-capable backend is attached (Browserbase or local Chrome via /browser connect). See website/docs/developer-guide/browser-supervisor.md.",group:"browser",effect:"live"},"browser.dialog_timeout_s":{type:"int",default:300,doc:"Safety auto-dismiss after N seconds under must_respond",group:"browser",effect:"live"},"browser.engine":{type:"str",default:"auto",doc:'Browser engine for local mode. Passed as ``--engine <value>`` to agent-browser v0.25.3+. "auto" \u2014 use Chrome (default, don\'t pass --engine at all) "lightpanda" \u2014 use Lightpanda (1.3-5.8x faster navigation, no screenshots) "chrome" \u2014 explicitly request Chrome Also settable via AGENT_BROWSER_ENGINE env var.',group:"browser",effect:"live"},"browser.inactivity_timeout":{type:"int",default:120,doc:"",group:"browser",effect:"live"},"browser.record_sessions":{type:"bool",default:!1,doc:"Auto-record browser sessions as WebM videos",group:"browser",effect:"live"},"checkpoints.auto_prune":{type:"bool",default:!0,doc:"Auto-maintenance: hermes sweeps the checkpoint base at startup (at most once per ``min_interval_hours``) and: * deletes project entries whose workdir no longer exists (orphan) * deletes project entries whose last_touch is older than ``retention_days`` * GCs the single shared store to reclaim unreachable objects * enforces ``max_total_size_mb`` across remaining projects * deletes ``legacy-*`` archives older than ``retention_days``",group:"checkpoints",effect:"live"},"checkpoints.delete_orphans":{type:"bool",default:!0,doc:"",group:"checkpoints",effect:"live"},"checkpoints.enabled":{type:"bool",default:!1,doc:"",group:"checkpoints",effect:"live"},"checkpoints.max_file_size_mb":{type:"int",default:10,doc:"Skip any single file larger than this when staging a checkpoint. Prevents accidental snapshotting of datasets, model weights, and other large generated assets. 0 disables the filter.",group:"checkpoints",effect:"live"},"checkpoints.max_snapshots":{type:"int",default:20,doc:"Max checkpoints to keep per working directory. Pre-v2 this only limited the `/rollback` listing; v2 actually rewrites the ref and garbage-collects older commits.",group:"checkpoints",effect:"live"},"checkpoints.max_total_size_mb":{type:"int",default:500,doc:"Hard ceiling on total ``~/.hermes/checkpoints/`` size (MB). When exceeded, the oldest checkpoint per project is dropped in a round-robin pass until total size falls under the cap. 0 disables the size cap.",group:"checkpoints",effect:"live"},"checkpoints.min_interval_hours":{type:"int",default:24,doc:"",group:"checkpoints",effect:"live"},"checkpoints.retention_days":{type:"int",default:7,doc:"",group:"checkpoints",effect:"live"},"code_execution.mode":{type:"str",default:"project",doc:"Execution mode: project (default) \u2014 scripts run in the session's working directory with the active virtualenv/conda env's python, so project deps (pandas, torch, project packages) and relative paths resolve. strict \u2014 scripts run in an isolated temp directory with hermes-agent's own python (sys.executable). Maximum isolation and reproducibility; project deps and relative paths won't work. Env scrubbing (strips *_API_KEY, *_TOKEN, *_SECRET, ...) and the tool whitelist apply identically in both modes.",group:"code_execution",effect:"live"},command_allowlist:{type:"list",default:[],doc:'Permanently allowed dangerous command patterns (added via "always" approval)',group:"general",effect:"live"},"compression.abort_on_summary_failure":{type:"bool",default:!1,doc:`When True, auto-compression that fails to generate a summary (aux LLM errored / returned non-JSON / timed out) aborts entirely instead of dropping the middle window with a static "summary unavailable" placeholder. Messages are preserved unchanged and the session "freezes" at its current size until the user runs /compress (which bypasses the failure cooldown) or /new. Default False matches historical behavior; set to True if you'd rather pause than silently lose context turns when your aux model is flaky.`,group:"compression",effect:"live"},"compression.codex_gpt55_autoraise":{type:"bool",default:!0,doc:"Historical key name kept for compatibility. When True, gpt-5.4 / gpt-5.5 on the ChatGPT Codex OAuth route raise their compaction trigger to 85% (vs the global `threshold` above). Codex hard-caps both families at a 272K window, so the default 50% would compact at ~136K and waste half the usable context. Set to False to opt back down to the global threshold (e.g. 0.50) for those Codex sessions. Only this exact route is affected \u2014 gpt-5.4 / 5.5 on OpenAI's direct API, OpenRouter, and Copilot keep the global threshold regardless.",group:"compression",effect:"live"},"compression.codex_gpt55_autoraise_notice":{type:"bool",default:!0,doc:"Display the one-time Codex gpt-5.4/5.5 autoraise banner. Set False to keep the 85% threshold autoraise but suppress the user-facing notice in CLI/gateway output.",group:"compression",effect:"live"},"compression.enabled":{type:"bool",default:!0,doc:"",group:"compression",effect:"live"},"compression.hygiene_hard_message_limit":{type:"int",default:5000,doc:"gateway session-hygiene force-compress threshold by message count",group:"compression",effect:"live"},"compression.in_place":{type:"bool",default:!0,doc:"When True, compaction rewrites the message list and rebuilds the system prompt WITHOUT rotating the session id \u2014 the conversation keeps one durable id for its whole life (no parent_session_id chain, no `name #N` renumbering). Eliminates the session-rotation bug cluster (#33618 /goal loss, #14238 lost response, #33907 orphans, #45117 search gaps, #42228 null cwd) \u2014 see #38763. Non-destructive: the live context is compacted (lossy for what the model reloads), but the pre-compaction turns are soft-archived under the same id (active=0, compacted=1) \u2014 still searchable via session_search and recoverable, not deleted. Default False during rollout; will flip on after live validation.",group:"compression",effect:"live"},"compression.protect_first_n":{type:"int",default:3,doc:"non-system head messages always preserved verbatim, in ADDITION to the system prompt (which is always implicitly protected). Set to 0 for long-running rolling-compaction sessions where you want nothing pinned except the system prompt + rolling summary + recent tail.",group:"compression",effect:"live"},"compression.protect_last_n":{type:"int",default:20,doc:"minimum recent messages to keep uncompressed",group:"compression",effect:"live"},"compression.target_ratio":{type:"float",default:0.2,doc:"fraction of threshold to preserve as recent tail",group:"compression",effect:"live"},"compression.threshold":{type:"float",default:0.5,doc:"compress when context usage exceeds this ratio",group:"compression",effect:"live"},"computer_use.cua_telemetry":{type:"bool",default:!1,doc:"cua-driver ships with anonymous usage telemetry (PostHog) ENABLED by default upstream. Hermes disables it for our users unless they explicitly opt in here. When false (default), Hermes sets CUA_DRIVER_RS_TELEMETRY_ENABLED=0 in the cua-driver child env for every invocation (MCP backend, status, doctor, install). Set true to let cua-driver use its own default (telemetry on).",group:"computer_use",effect:"live"},"context.engine":{type:"str",default:"compressor",doc:"",group:"context",effect:"live"},context_file_max_chars:{type:"null",default:null,doc:"Hard cap (chars) for a single automatic context file such as SOUL.md, AGENTS.md, CLAUDE.md, .hermes.md, or .cursorrules before Hermes applies head/tail truncation. ``null`` (the default) lets the cap scale with the model's context window (floor 20K, ceiling 500K) so large-context models rarely truncate a project doc. Set a positive integer to pin a fixed cap and override the dynamic behavior. Separate from read_file tool limits.",group:"general",effect:"live"},credential_pool_strategies:{type:"dict",default:{},doc:"",group:"general",effect:"live"},"cron.chronos.callback_url":{type:"str",default:"",doc:"The agent's OWN publicly-reachable base URL for NAS\u2192agent fires (NAS POSTs {callback_url}/api/cron/fire). Empty \u2192 Chronos is unavailable and the resolver falls back to the built-in ticker.",group:"cron",effect:"live"},"cron.chronos.expected_audience":{type:"str",default:"",doc:`This agent's expected JWT audience (e.g. "agent:{instance_id}").`,group:"cron",effect:"live"},"cron.chronos.nas_jwks_url":{type:"str",default:"",doc:"NAS JWKS URL for verifying the inbound fire JWT's signature. Empty \u2192 the fire endpoint refuses all tokens (no unsigned decode).",group:"cron",effect:"live"},"cron.chronos.portal_url":{type:"str",default:"https://portal.nousresearch.com",doc:"NAS / portal base URL the agent calls to arm/cancel one-shots and that mints the inbound fire JWT (used as the expected issuer).",group:"cron",effect:"live"},"cron.max_parallel_jobs":{type:"null",default:null,doc:"Maximum number of due jobs to run in parallel per tick. null/0 = unbounded (limited only by thread count). 1 = serial (pre-v0.9 behaviour). Also overridable via HERMES_CRON_MAX_PARALLEL env var.",group:"cron",effect:"live"},"cron.mirror_delivery":{type:"bool",default:!1,doc:"Make cron deliveries CONTINUABLE: a user can reply to a cron brief and the agent has it in context (no \"what is Task #2?\" amnesia). Default False preserves the historical isolation guarantee (cron deliveries live only in the cron job's own session). Per-job `attach_to_session` overrides this for a single job. Behaviour is THREAD-PREFERRED, scoped to the job's origin chat: - Thread-capable platforms (Telegram forum/DM topics, Discord threads, Slack threads): a dedicated thread is opened for the job via the adapter's create_handoff_thread, the brief is delivered into it, and that thread's session is seeded so the user's reply in-thread continues with full context. Each continuable job gets its own scrollback, isolated from the parent channel. - DM-only platforms (WhatsApp / Signal / SMS): no threads exist, so the brief is mirrored into the origin DM session instead \u2014 the DM itself is the continuation surface. Both paths ride the shipped gateway.mirror.mirror_to_session and are alternation- and cache-safe (appended at a turn boundary, never mid-loop, never mutating the cached system prompt). Only the origin chat is ever touched \u2014 fan-out / broadcast targets are never mirrored.",group:"cron",effect:"live"},"cron.output_retention":{type:"int",default:50,doc:"Per-job output-file retention: save_job_output keeps the N most recent .md files and prunes older ones. 0 or negative disables pruning (for operators who manage cleanup externally). Default 50.",group:"cron",effect:"live"},"cron.provider":{type:"str",default:"",doc:'Active cron SCHEDULER provider (Axis B \u2014 the trigger that decides WHEN a due job fires). Empty string = the built-in in-process 60s ticker (default). Name an installed provider (plugins/cron_providers/<name>/ or $HERMES_HOME/plugins/<name>/) to relocate the trigger \u2014 e.g. "chronos", the NAS-mediated managed-cron provider for scale-to-zero deployments. An unknown or unavailable provider falls back to the built-in, so cron never loses its trigger.',group:"cron",effect:"live"},"cron.wrap_response":{type:"bool",default:!0,doc:'Wrap delivered cron responses with a header (task name) and footer ("The agent cannot see this message"). Set to false for clean output.',group:"cron",effect:"live"},"curator.archive_after_days":{type:"int",default:90,doc:"Archive a skill (move to skills/.archive/) after this many days without use. Archived skills are recoverable \u2014 no auto-deletion.",group:"curator",effect:"live"},"curator.backup.enabled":{type:"bool",default:!0,doc:"",group:"curator",effect:"live"},"curator.backup.keep":{type:"int",default:5,doc:"retain last N regular snapshots",group:"curator",effect:"live"},"curator.consolidate":{type:"bool",default:!1,doc:"Run the LLM consolidation (umbrella-building) pass. OFF by default. When off, a curator run does ONLY the deterministic inactivity prune (mark stale / archive long-unused skills) and skips the forked aux-model review entirely \u2014 no umbrella-building, no aux-model cost. Set to true to opt back into merging overlapping skills into class-level umbrellas. `hermes curator run --consolidate` overrides this for a single invocation.",group:"curator",effect:"live"},"curator.enabled":{type:"bool",default:!0,doc:"",group:"curator",effect:"live"},"curator.interval_hours":{type:"int",default:168,doc:"How long to wait between curator runs (hours). Default: 7 days.",group:"curator",effect:"live"},"curator.min_idle_hours":{type:"int",default:2,doc:"Only run when the agent has been idle at least this long (hours).",group:"curator",effect:"live"},"curator.prune_builtins":{type:"bool",default:!0,doc:"Also prune (archive) bundled built-in skills after the inactivity period, not just agent-created ones. ON by default. Built-ins are normally restored on every `hermes update`, so pruning them only sticks because a suppression list tells the re-seeder to leave them archived. Hub-installed skills are NEVER pruned here \u2014 they have an external upstream owner. Built-ins accrue usage telemetry and their inactivity clock starts the first time the curator sees them, so a long-unused built-in is archived only after archive_after_days of genuine non-use (never a mass-prune on the first run). Set to false to keep all bundled built-ins permanently.",group:"curator",effect:"live"},"curator.stale_after_days":{type:"int",default:30,doc:'Mark a skill as "stale" after this many days without use.',group:"curator",effect:"live"},custom_prompt:{type:"str",default:"",doc:"Ad-hoc system-prompt addendum set via /prompt.",group:"general",effect:"live"},custom_providers:{type:"dict",default:{},doc:"OpenAI-compatible provider definitions keyed by name. Entries support ssl_ca_cert and ssl_verify.",group:"general",effect:"live"},"dashboard.basic_auth.password":{type:"str",default:"",doc:"plaintext fallback (hashed in-memory at load)",group:"dashboard",effect:"live"},"dashboard.basic_auth.password_hash":{type:"str",default:"",doc:"scrypt$... (preferred \u2014 no plaintext at rest)",group:"dashboard",effect:"live"},"dashboard.basic_auth.secret":{type:"str",default:"",doc:"token-signing key; blank \u2192 random per-process",group:"dashboard",effect:"live"},"dashboard.basic_auth.session_ttl_seconds":{type:"int",default:0,doc:"0 \u2192 plugin default (12h)",group:"dashboard",effect:"live"},"dashboard.basic_auth.username":{type:"str",default:"",doc:"blank \u2192 plugin no-op (no password provider)",group:"dashboard",effect:"live"},"dashboard.drain_auth.min_secret_chars":{type:"int",default:43,doc:"",group:"dashboard",effect:"live"},"dashboard.drain_auth.scope":{type:"str",default:"drain",doc:"",group:"dashboard",effect:"live"},"dashboard.oauth.client_id":{type:"str",default:"",doc:"agent:{instance_id} \u2014 Portal provisions this",group:"dashboard",effect:"live"},"dashboard.oauth.portal_url":{type:"str",default:"",doc:"blank \u2192 use plugin default (production Portal)",group:"dashboard",effect:"live"},"dashboard.public_url":{type:"str",default:"",doc:"Public URL override (env: ``HERMES_DASHBOARD_PUBLIC_URL``). When set, this is the complete authority \u2014 scheme + host + optional path prefix (e.g. ``https://example.com/hermes``) \u2014 the OAuth ``redirect_uri`` is built from. Set this for deploys behind reverse proxies that don't reliably forward ``X-Forwarded-Host`` / ``X-Forwarded-Proto`` / ``X-Forwarded-Prefix`` (manual nginx setups, on-prem ingresses, custom-domain Fly deploys without proper proxy headers). When set, ``X-Forwarded-Prefix`` is IGNORED on the OAuth path because the operator has declared the public URL \u2014 we no longer need to guess from proxy headers, and stacking the prefix on top would double-prefix the common case where the prefix is already baked into ``public_url``. Leave empty to use the existing proxy-header reconstruction (the default). Validation: rejects values without ``http(s)://`` scheme or without a host, and any string containing quote / angle / whitespace / control characters. A malformed value silently falls through to request reconstruction rather than breaking the login flow.",group:"dashboard",effect:"live"},"dashboard.show_token_analytics":{type:"bool",default:!1,doc:"Hide the token/cost analytics surfaces (Analytics page, token bars and cost figures on the Models page) by default. The numbers shown there are a local debug estimate: they only count successful main-agent responses with a usable ``response.usage``, and silently exclude every auxiliary call (context compression, title generation, vision, session search, web extract, smart approval, MCP routing, plugin LLM access) plus provider-side retries, fallback attempts, and any call whose usage block didn't come back. Cache writes are also missing from the API response. On models with heavy auxiliary traffic (Kimi K2.6, MiniMax M2.7) the local total can be 10x-100x lower than the provider bill, which is worse than hiding the numbers entirely because they look precise enough to compare against the provider. Set this to True to re-enable the surfaces with the understanding that the numbers are a local lower-bound estimate, not billing.",group:"dashboard",effect:"live"},"dashboard.theme":{type:"str",default:"default",doc:'Dashboard visual theme: "default", "midnight", "ember", "mono", "cyberpunk", "rose"',group:"dashboard",effect:"live"},"delegation.api_key":{type:"str",default:"",doc:"API key for delegation.base_url (falls back to OPENAI_API_KEY)",group:"delegation",effect:"session"},"delegation.api_mode":{type:"str",default:"",doc:`wire protocol for delegation.base_url: "chat_completions", "codex_responses", or "anthropic_messages". Empty = auto-detect from URL (e.g. /anthropic suffix \u2192 anthropic_messages). Set this explicitly for non-standard endpoints the heuristic can't detect.`,group:"delegation",effect:"session"},"delegation.base_url":{type:"str",default:"",doc:"direct OpenAI-compatible endpoint for subagents",group:"delegation",effect:"session"},"delegation.child_timeout_seconds":{type:"int",default:0,doc:"optional wall-clock cap per child agent. 0 (default) = no timeout: children fail only from real errors (API, tools, iteration budget), never a delegation stopwatch. Set a positive number of seconds (floor 30s) to enforce a hard cap.",group:"delegation",effect:"session"},"delegation.inherit_mcp_toolsets":{type:"bool",default:!0,doc:'When delegate_task narrows child toolsets explicitly, preserve any MCP toolsets the parent already has enabled. On by default so narrowing (e.g. toolsets=["web","browser"]) expresses "I want these extras" without silently stripping MCP tools the parent already has. Set to false for strict intersection.',group:"delegation",effect:"session"},"delegation.max_concurrent_children":{type:"int",default:3,doc:"unified concurrency cap: max parallel children per batch AND max concurrent background (background=true) delegation units. New async dispatches beyond the cap fall back to synchronous execution. Floor of 1, no ceiling. (Replaces the deprecated max_async_children.)",group:"delegation",effect:"session"},"delegation.max_iterations":{type:"int",default:50,doc:"per-subagent iteration cap (each subagent gets its own budget, independent of the parent's max_iterations)",group:"delegation",effect:"session"},"delegation.max_spawn_depth":{type:"int",default:1,doc:"Orchestrator role controls (see tools/delegate_tool.py:_get_max_spawn_depth and _get_orchestrator_enabled). Floored at 1, no upper ceiling \u2014 raise deliberately, each level multiplies API cost.",group:"delegation",effect:"session"},"delegation.max_summary_chars":{type:"int",default:24000,doc:`Subagent summaries return to the parent's context verbatim. A batch fan-out (N children) returns N summaries at once, which can exceed the parent's context window and trigger a compression/429 death spiral. delegate_task sizes each summary against the parent's remaining context headroom (split across the batch); when it must trim, the full text is spilled to ~/.hermes/cache/delegation/ (mounted into remote backends) and the in-context summary becomes a head+tail window plus a footer with the exact read_file offset to page the omitted middle \u2014 the same convention web_extract uses for large pages. Nothing is lost. max_summary_chars is a hard per-summary character ceiling layered on top of that dynamic budget (belt-and-suspenders for models that ignore the "be concise" instruction). 0 disables the hard ceiling; the dynamic headroom budget still applies.`,group:"delegation",effect:"session"},"delegation.model":{type:"str",default:"",doc:'e.g. "google/gemini-3-flash-preview" (empty = inherit parent model)',group:"delegation",effect:"session"},"delegation.orchestrator_enabled":{type:"bool",default:!0,doc:'kill switch for role="orchestrator"',group:"delegation",effect:"session"},"delegation.provider":{type:"str",default:"",doc:'e.g. "openrouter" (empty = inherit parent provider + credentials)',group:"delegation",effect:"session"},"delegation.reasoning_effort":{type:"str",default:"",doc:`reasoning effort for subagents: "xhigh", "high", "medium", "low", "minimal", "none" (empty = inherit parent's level)`,group:"delegation",effect:"session"},"delegation.subagent_auto_approve":{type:"bool",default:!1,doc:`When a subagent hits a dangerous-command approval prompt, the parent's prompt_toolkit TUI owns stdin \u2014 a thread-local input() call from the subagent worker would deadlock the parent UI. To avoid the deadlock, subagent threads ALWAYS resolve approvals non-interactively: false (default) \u2192 auto-deny with a logger.warning audit line (safe) true \u2192 auto-approve "once" with a logger.warning audit line Flip to true only if you trust delegated work to run dangerous cmds without human review (cron pipelines, batch automation, etc.).`,group:"delegation",effect:"session"},"desktop.disable_gpu":{type:"str",default:"auto",doc:'GPU hardware acceleration policy for the desktop app: "auto" - let the app detect remote displays (SSH/VNC/RDP) and disable GPU only then (default; current behavior). true - always disable GPU acceleration (software rendering). Use on no-GPU VMs / Proxmox hosts where the GPU path hangs. false - always keep GPU acceleration on, even over a remote display. Bridged to the HERMES_DESKTOP_DISABLE_GPU env var the Electron app reads.',group:"desktop",effect:"live"},"desktop.electron_flags":{type:"list",default:[],doc:'Extra Electron command-line flags appended to every desktop launch, e.g. ["--ozone-platform=x11"] on headless/VM X11 hosts that need an explicit ozone backend, or GPU workaround flags. A list of strings; a single string is also accepted and shell-split.',group:"desktop",effect:"live"},"discord.allow_any_attachment":{type:"bool",default:!1,doc:"DEPRECATED / no-op. Any uploaded file is now always cached and surfaced to the agent regardless of file type \u2014 authorization to message the agent is the gate, not the extension. Kept so existing configs that set it do not error. Env override: DISCORD_ALLOW_ANY_ATTACHMENT.",group:"discord",effect:"live"},"discord.allowed_channels":{type:"str",default:"",doc:"If set, bot ONLY responds in these channel IDs (whitelist)",group:"discord",effect:"live"},"discord.auto_thread":{type:"bool",default:!0,doc:"Auto-create threads on @mention in channels (like Slack)",group:"discord",effect:"live"},"discord.bots_require_inline_mention":{type:"bool",default:!1,doc:"Multi-bot rooms: if True, another bot must type @thisbot in its message to trigger a reply; a Discord reply/quote alone won't. Prevents two bots auto-replying to each other forever. Does not affect humans.",group:"discord",effect:"live"},"discord.channel_prompts":{type:"dict",default:{},doc:"Per-channel ephemeral system prompts (forum parents apply to child threads)",group:"discord",effect:"live"},"discord.dm_role_auth_guild":{type:"str",default:"",doc:"Opt-in DM role-based auth (#12136). By default, DISCORD_ALLOWED_ROLES authorizes only guild messages in the role's own guild \u2014 DMs require DISCORD_ALLOWED_USERS. Set dm_role_auth_guild to a guild ID to also authorize DMs from members of that one trusted guild holding the allowed role. Unset / empty / 0 = secure default (DM role-auth off).",group:"discord",effect:"live"},"discord.free_response_channels":{type:"str",default:"",doc:"Comma-separated channel IDs where bot responds without mention",group:"discord",effect:"live"},"discord.history_backfill":{type:"bool",default:!0,doc:"If True, prepend recent channel scrollback when bot is triggered (recovers messages missed while require_mention gated them out)",group:"discord",effect:"live"},"discord.history_backfill_limit":{type:"int",default:50,doc:"Max number of recent messages to scan when assembling the backfill block",group:"discord",effect:"live"},"discord.max_attachment_bytes":{type:"int",default:33554432,doc:"Maximum bytes per attachment the gateway will cache. The whole file is held in memory while being written, so unlimited uploads carry a real memory cost. Default 32 MiB matches the historical hardcoded cap. Set to 0 for no cap. Env override: DISCORD_MAX_ATTACHMENT_BYTES.",group:"discord",effect:"live"},"discord.reactions":{type:"bool",default:!0,doc:"Add \uD83D\uDC40/\u2705/\u274C reactions to messages during processing",group:"discord",effect:"live"},"discord.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in server channels",group:"discord",effect:"live"},"discord.server_actions":{type:"str",default:"",doc:'discord / discord_admin tools: restrict which actions the agent may call. Default (empty) = all actions allowed (subject to bot privileged intents). Accepts comma-separated string ("list_guilds,list_channels,fetch_messages") or YAML list. Unknown names are dropped with a warning at load time. Actions: list_guilds, server_info, list_channels, channel_info, list_roles, member_info, search_members, fetch_messages, list_pins, pin_message, unpin_message, create_thread, add_role, remove_role.',group:"discord",effect:"live"},"discord.thread_require_mention":{type:"bool",default:!1,doc:"If True, require @mention in threads too (multi-bot threads)",group:"discord",effect:"live"},"discord.voice_fx.ack_enabled":{type:"bool",default:!0,doc:"speak a short phrase before the first tool call",group:"discord",effect:"live"},"discord.voice_fx.ack_phrases":{type:"list",default:["Let me look into that.","One moment.","Checking on that now.","Give me a sec.","On it."],doc:"picked at random; set [] to disable phrases",group:"discord",effect:"live"},"discord.voice_fx.ambient_enabled":{type:"bool",default:!0,doc:'play the idle "thinking" bed while tools run',group:"discord",effect:"live"},"discord.voice_fx.ambient_gain":{type:"float",default:0.18,doc:"idle bed loudness, 0.0\u20131.0",group:"discord",effect:"live"},"discord.voice_fx.ambient_path":{type:"str",default:"",doc:'custom loop audio file; "" = synthesised pad',group:"discord",effect:"live"},"discord.voice_fx.duck_gain":{type:"float",default:0.06,doc:"ambient loudness while speech plays",group:"discord",effect:"live"},"discord.voice_fx.enabled":{type:"bool",default:!1,doc:"master switch for the mixer subsystem",group:"discord",effect:"live"},"discord.voice_fx.speech_gain":{type:"float",default:1,doc:"TTS / ack loudness, 0.0\u20131.0",group:"discord",effect:"live"},"display.bell_on_complete":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.busy_input_mode":{type:"str",default:"interrupt",doc:"interrupt | queue | steer",group:"display",effect:"live"},"display.busy_steer_ack_enabled":{type:"bool",default:!0,doc:'When busy_input_mode="steer", suppress only the visible "Steered into current run" confirmation bubble by setting this false. The mid-turn steering itself still happens.',group:"display",effect:"live"},"display.cli_refresh_interval":{type:"float",default:1,doc:"Seconds between prompt_toolkit redraws in the classic CLI when idle. Default 1.0 keeps the wall-clock status-bar read-outs (idle-since- last-turn) ticking and keeps the bottom chrome alive during idle \u2014 without it prompt_toolkit stops repainting the status bar after a turn and it can go stale/disappear (#45592). Set 0 to disable the background refresh if it fights terminal auto-scroll in non-fullscreen mode on some emulators (#48309).",group:"display",effect:"live"},"display.compact":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.copy_shortcut":{type:"str",default:"auto",doc:'"auto" (platform default) | "ctrl_c" | "ctrl_shift_c" | "disabled"',group:"display",effect:"live"},"display.credits_notices":{type:"bool",default:!0,doc:"Nous credits status-bar notices (usage bands, grant-spent, depleted / restored). When false, no credits notices are emitted \u2014 balance data is still captured and /usage keeps working. Off switch for sub + top-up users who find the gauge noisy.",group:"display",effect:"live"},"display.details_mode":{type:"str",default:"collapsed",doc:"Tool-progress section fold state: hidden | collapsed | expanded.",group:"display",effect:"live"},"display.ephemeral_system_ttl":{type:"int",default:0,doc:'Auto-delete system-notice replies (e.g. "\u2728 New session started!", "\u267B Restarting gateway\u2026", "\u26A1 Stopped\u2026") after N seconds on platforms that support message deletion (currently Telegram; other platforms ignore and leave the message in place). Only affects slash-command replies wrapped with gateway.platforms.base.EphemeralReply \u2014 agent responses and content messages are never touched. Default 0 (disabled) preserves prior behavior.',group:"display",effect:"live"},"display.file_mutation_verifier":{type:"bool",default:!0,doc:'File-mutation verifier footer. When true (default), the agent appends a one-line advisory to its final response whenever a write_file / patch call failed during the turn and was never superseded by a successful write to the same path. This catches the "batch of parallel patches, half fail, model claims success" class of over-claim that otherwise forces users to run `git status` to verify edits landed. Set false to suppress.',group:"display",effect:"live"},"display.final_response_markdown":{type:"str",default:"strip",doc:"render | strip | raw",group:"display",effect:"live"},"display.friendly_tool_labels":{type:"bool",default:!0,doc:'Human-phrased tool status labels for built-in tools: "Searching the web for ...", "Reading <file>", "Browsing <url>" instead of the raw tool name. Applies to CLI spinner + gateway/desktop tool-progress. Custom/plugin/MCP tools always fall back to the raw preview.',group:"display",effect:"live"},"display.inline_diffs":{type:"bool",default:!0,doc:"Show inline diff previews for write actions (write_file, patch, skill_manage)",group:"display",effect:"live"},"display.interface":{type:"str",default:"cli",doc:'Which interface bare `hermes` (and `hermes chat`) launches by default: "cli" \u2014 the classic prompt_toolkit REPL (default, preserves prior behavior) "tui" \u2014 the modern Ink TUI (same as passing `--tui`) Explicit flags always win over this setting: `--cli` forces the classic REPL and `--tui` (or HERMES_TUI=1) forces the TUI regardless of config.',group:"display",effect:"live"},"display.interim_assistant_messages":{type:"bool",default:!0,doc:"Gateway: show natural mid-turn assistant status messages",group:"display",effect:"live"},"display.language":{type:"str",default:"en",doc:"UI language for static user-facing messages (approval prompts, a handful of gateway slash-command replies). Does NOT affect agent responses, log lines, tool outputs, or slash-command descriptions. Supported: en, zh, ja, de, es, fr, tr, uk. Unknown values fall back to en.",group:"display",effect:"live"},"display.memory_notifications":{type:"str",default:"on",doc:'Background self-improvement review notifications surfaced in chat. "off" \u2014 no chat notification (the review still runs and writes) "on" \u2014 generic "\uD83D\uDCBE Memory updated" line (default) "verbose" \u2014 include a compact content preview of what changed Per-platform overrides via display.platforms.<platform>.memory_notifications.',group:"display",effect:"live"},"display.persist_prompts":{type:"bool",default:!0,doc:"Print a one-line summary of resolved modal prompts (approval / clarify) into scrollback so the question and decision survive the panel repaint. Set false to keep scrollback untouched.",group:"display",effect:"live"},"display.persistent_output":{type:"bool",default:!0,doc:"Preserve recent classic CLI output across Ctrl+L, /redraw, and terminal resize full-screen clears. Disable if a terminal emulator behaves badly with replayed scrollback.",group:"display",effect:"live"},"display.persistent_output_max_lines":{type:"int",default:200,doc:"",group:"display",effect:"live"},"display.personality":{type:"str",default:"",doc:"",group:"display",effect:"live"},"display.pet.enabled":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.pet.render_mode":{type:"str",default:"auto",doc:"Terminal render protocol for CLI/TUI: auto \u2014 detect kitty/iTerm2/sixel, else unicode half-blocks kitty | iterm | sixel | unicode | off",group:"display",effect:"live"},"display.pet.scale":{type:"float",default:0.33,doc:"Master size scalar (relative to native 192\xD7208 frames). One knob shrinks every surface: the desktop canvas scales its pixels by it and the CLI/TUI derive their terminal column width from it. The half-block fallback clamps to a legibility floor (it can't shrink as far as true-pixel kitty/GUI without turning to mush).",group:"display",effect:"live"},"display.pet.slug":{type:"str",default:"",doc:"Active pet slug; resolved against installed pets in get_hermes_home()/pets/. Empty \u2192 first installed pet.",group:"display",effect:"live"},"display.pet.unicode_cols":{type:"int",default:0,doc:"Hard override for terminal column width. 0 = auto (derive from scale); set a positive int only to pin the half-block/kitty width independently of scale.",group:"display",effect:"live"},"display.platforms.discord.streaming":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.platforms.telegram.streaming":{type:"bool",default:!0,doc:"",group:"display",effect:"live"},"display.reasoning_full":{type:"bool",default:!1,doc:'When reasoning display is on, the post-response "Reasoning" recap box collapses long thinking to the first 10 lines. Set true to print the complete thinking text uncollapsed (live streaming is always full).',group:"display",effect:"live"},"display.reasoning_style":{type:"str",default:"code",doc:'How a reasoning/thinking summary renders when show_reasoning is on. "code" (default) = \uD83D\uDCAD fenced code block; "blockquote" = "> " lines; "subtext" = "-# " lines (Discord small grey metadata text). Discord defaults to "subtext"; override per-platform via display.platforms.<platform>.reasoning_style.',group:"display",effect:"live"},"display.resume_display":{type:"str",default:"full",doc:"",group:"display",effect:"live"},"display.resume_exchanges":{type:"int",default:10,doc:"Recap tuning for /resume and startup resume. The defaults match the historical hardcoded values; expose them as config so power users can widen or tighten the snapshot to taste.",group:"display",effect:"live"},"display.resume_max_assistant_chars":{type:"int",default:200,doc:"truncate non-last assistant text",group:"display",effect:"live"},"display.resume_max_assistant_lines":{type:"int",default:3,doc:"truncate non-last assistant lines",group:"display",effect:"live"},"display.resume_max_user_chars":{type:"int",default:300,doc:"truncate user message text",group:"display",effect:"live"},"display.resume_skip_tool_only":{type:"bool",default:!0,doc:"When True (default), assistant entries that are *only* tool calls (no visible text) are skipped in the recap. This prevents the recap from being dominated by `[2 tool calls: terminal, read_file]` lines when an exchange was tool-heavy. Set False to restore the legacy behavior of showing tool-call summaries inline.",group:"display",effect:"live"},"display.runtime_footer.enabled":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.runtime_footer.fields":{type:"list",default:["model","context_pct","cwd"],doc:"Order shown; drop any to hide",group:"display",effect:"live"},"display.show_cost":{type:"bool",default:!1,doc:"Show $ cost in the status bar (off by default)",group:"display",effect:"live"},"display.show_reasoning":{type:"bool",default:!0,doc:"Stream the model's reasoning/thinking live before the response. Default ON: on thinking models the reasoning phase can run tens of seconds, and with this off the user stares at a spinner the whole time even though tokens are streaming. Set false for quiet output.",group:"display",effect:"live"},"display.skin":{type:"str",default:"default",doc:"",group:"display",effect:"live"},"display.status_phrases":{type:"dict",default:{},doc:'Optional custom phrases for generic long-running status messages. Built-in defaults live in gateway/assets/status_phrases.yaml. Users can set `path`/`paths` to HERMES_HOME-relative YAML files/directories (or rely on conventional status_phrases.yaml / status_phrases/*.yaml). Keys: status, generic. Use mode: "append" (default) to add phrases, or "replace" to fully replace configured surfaces. Per-platform overrides live under display.platforms.<platform>.status_phrases.',group:"display",effect:"live"},"display.streaming":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.thinking_mode":{type:"str",default:"collapsed",doc:"Reasoning display: collapsed | truncated | full.",group:"display",effect:"live"},"display.timestamp_format":{type:"str",default:"%H:%M",doc:'strftime format for timestamps (e.g. "%b-%d %H:%M")',group:"display",effect:"live"},"display.timestamps":{type:"bool",default:!1,doc:"Show timestamp on user and assistant labels",group:"display",effect:"live"},"display.tool_preview_length":{type:"int",default:0,doc:"Max chars for tool call previews (0 = no limit, show full paths/commands)",group:"display",effect:"live"},"display.tool_progress":{type:"str",default:"all",doc:"Tool-progress verbosity: off | new | all | verbose.",group:"display",effect:"live"},"display.tool_progress_command":{type:"bool",default:!1,doc:"Enable /verbose command in messaging gateway",group:"display",effect:"live"},"display.tool_progress_grouping":{type:"str",default:"accumulate",doc:'How gateway tool-progress is grouped on platforms that support message editing: "accumulate" (default) edits one bubble in place; "separate" sends one message per tool (the pre-v0.9 behavior, noisier). Only applies where tool_progress is already enabled. Per-platform override via display.platforms.<platform>.tool_progress_grouping.',group:"display",effect:"live"},"display.tool_progress_overrides":{type:"dict",default:{},doc:"DEPRECATED \u2014 use display.platforms instead",group:"display",effect:"live"},"display.tui_agents_nudge":{type:"bool",default:!0,doc:'When true (default), `hermes --tui` drops a one-time hint ("subagents working \xB7 /agents to watch live") the first time a turn starts delegating, nudging the user toward the live spawn-tree dashboard. Set false to suppress the hint.',group:"display",effect:"live"},"display.tui_auto_resume_recent":{type:"bool",default:!1,doc:"When true, `hermes --tui` auto-resumes the most recent human- facing session on launch instead of forging a fresh one. Mirrors `hermes -c` muscle memory. Default off so existing users aren't surprised. HERMES_TUI_RESUME=<id> always wins.",group:"display",effect:"live"},"display.tui_compact":{type:"bool",default:!1,doc:"Ink-TUI compact layout.",group:"display",effect:"live"},"display.tui_mouse":{type:"bool",default:!0,doc:"Ink-TUI mouse support.",group:"display",effect:"live"},"display.tui_status_indicator":{type:"str",default:"kaomoji",doc:"TUI busy indicator style: kaomoji (default), emoji, unicode (braille spinner), or ascii. Live-swappable via `/indicator <style>`.",group:"display",effect:"live"},"display.tui_statusbar":{type:"str",default:"top",doc:"Ink-TUI statusbar placement: top | bottom | off.",group:"display",effect:"live"},"display.turn_completion_explainer":{type:"bool",default:!0,doc:`Turn-completion explainer. When true (default), the agent appends a one-line explanation to its final response whenever a turn ends abnormally with no usable reply \u2014 empty content after retries, a partial/truncated stream, a still-pending tool result, or an iteration/budget limit. Replaces the bare "(empty)" sentinel so the failure isn't silent from the UI's perspective. Set false to suppress.`,group:"display",effect:"live"},"display.user_message_preview.first_lines":{type:"int",default:2,doc:"",group:"display",effect:"live"},"display.user_message_preview.last_lines":{type:"int",default:2,doc:"",group:"display",effect:"live"},fallback_model:{type:"dict",default:null,doc:"Fallback model (dict) or chain (list of dicts) for provider failover.",group:"general",effect:"live"},fallback_providers:{type:"list",default:[],doc:"",group:"general",effect:"live"},file_read_max_chars:{type:"int",default:1e5,doc:"Maximum characters returned by a single read_file call. Reads that exceed this are rejected with guidance to use offset+limit. 100K chars \u2248 25\u201335K tokens across typical tokenisers.",group:"general",effect:"live"},"gateway.api_server.max_concurrent_runs":{type:"int",default:10,doc:"Maximum number of agent runs the API server will service concurrently. Requests to /v1/chat/completions, /v1/responses, and /v1/runs that arrive while this many runs are already in flight are rejected with HTTP 429 + a Retry-After header, bounding CPU / memory / upstream-LLM-quota exhaustion from a request flood. Set to 0 to disable the cap entirely.",group:"gateway",effect:"live"},"gateway.max_inbound_media_bytes":{type:"int",default:134217728,doc:"Maximum bytes for an inbound image / audio / video payload the gateway will buffer into memory and cache to disk. Inbound media is read fully into RAM before being written, so an unbounded upload (Discord Nitro allows 500 MB) or a remote media URL pointing at a huge file can spike memory and OOM-kill the gateway on constrained deployments. Enforced in the shared cache helpers (gateway/platforms/base.py), so the cap holds across every platform adapter. ``0`` disables the cap. Default 128 MiB.",group:"gateway",effect:"live"},"gateway.media_delivery_allow_dirs":{type:"list",default:[],doc:"Extra directories from which model-emitted bare file paths may be uploaded as native gateway attachments. Files inside the Hermes cache (~/.hermes/cache/{documents,images,audio,video,screenshots}) are always trusted; this list adds operator-controlled roots (project dirs, scratch dirs, mounted shares). Accepts a list of absolute paths or a single os.pathsep-separated string. Bridged to HERMES_MEDIA_ALLOW_DIRS at gateway startup. Tilde paths are expanded. Honored in both default and strict mode.",group:"gateway",effect:"live"},"gateway.message_timestamps.enabled":{type:"bool",default:!1,doc:"",group:"gateway",effect:"live"},"gateway.platform_connect_timeout":{type:"int",default:30,doc:'Seconds the gateway waits for a single messaging platform to finish connecting during startup (and on reconnect). Discord in particular can blow past the old fixed 30s when an account has many slash commands to sync (#19776: 90-173 skills \u2192 ~28-31s sync). Raise this if your gateway hits "discord connect timed out" / "Timeout waiting for connection to Discord" restart loops. ``0`` or negative disables the timeout entirely (wait indefinitely). Bridged at startup to the internal HERMES_GATEWAY_PLATFORM_CONNECT_TIMEOUT env var, which still works as a manual override and wins if set explicitly.',group:"gateway",effect:"live"},"gateway.restart_loop_guard.max_restarts":{type:"int",default:3,doc:"",group:"gateway",effect:"live"},"gateway.restart_loop_guard.window_seconds":{type:"int",default:60,doc:"",group:"gateway",effect:"live"},"gateway.scale_to_zero.idle_timeout_minutes":{type:"int",default:5,doc:"",group:"gateway",effect:"live"},"gateway.strict":{type:"bool",default:!1,doc:"When false (default), any file path the agent emits is delivered as a native attachment as long as it isn't under the credential / system-path denylist (/etc, /proc, ~/.ssh, ~/.aws, ~/.hermes/.env, auth.json, etc.). This matches the symmetry of inbound delivery \u2014 we accept any document type the user uploads, and the agent can hand back any file that isn't a credential. When true, fall back to the older allowlist+recency-window behavior: files must live under the Hermes cache, under ``media_delivery_allow_dirs``, or be freshly produced inside the ``trust_recent_files_seconds`` window. Recommended for public-facing gateways where prompt injection from one user shouldn't be able to exfiltrate the host's secrets to that same user. Bridged to HERMES_MEDIA_DELIVERY_STRICT.",group:"gateway",effect:"live"},"gateway.trust_recent_files":{type:"bool",default:!0,doc:'When true, files whose mtime is within ``trust_recent_files_seconds`` of "now" are trusted for native delivery even outside the cache / operator allowlist \u2014 useful for ``pandoc -o /tmp/report.pdf`` or PDFs the agent writes into a working directory. System paths (/etc, /proc, ~/.ssh, ~/.aws, etc.) remain blocked regardless. Disable to fall back to pure-allowlist mode. Bridged to HERMES_MEDIA_TRUST_RECENT_FILES. Only consulted when ``strict`` is true; in default mode the denylist alone gates delivery.',group:"gateway",effect:"live"},"gateway.trust_recent_files_seconds":{type:"int",default:600,doc:"Recency window in seconds. 600 (10 min) comfortably covers a multi-tool agent turn. Bridged to HERMES_MEDIA_TRUST_RECENT_SECONDS. Only consulted when ``strict`` is true.",group:"gateway",effect:"live"},"gateway.write_sessions_json":{type:"bool",default:!0,doc:"Whether the gateway keeps writing the legacy sessions.json mirror of its routing index. The primary copy lives in state.db (the gateway_routing table). Default True for backward compatibility with external tooling and downgrade safety; set to false to stop producing ~/.hermes/sessions/sessions.json entirely.",group:"gateway",effect:"live"},"goals.max_turns":{type:"int",default:20,doc:"Max continuation turns before Hermes auto-pauses the goal and asks the user to /goal resume. Protects against judge false negatives (goal actually done but judge says continue) and unbounded model spend on fuzzy / unachievable goals.",group:"goals",effect:"live"},honcho:{type:"dict",default:{},doc:"Honcho AI-native memory -- reads ~/.honcho/config.json as single source of truth. This section is only needed for hermes-specific overrides; everything else (apiKey, workspace, peerName, sessions, enabled) comes from the global config.",group:"general",effect:"live"},hooks:{type:"dict",default:{},doc:"Shell-script hooks \u2014 declarative bridge that invokes shell scripts on plugin-hook events (pre_tool_call, post_tool_call, pre_llm_call, subagent_stop, etc.). Each entry maps an event name to a list of {matcher, command, timeout} dicts. First registration of a new command prompts the user for consent; subsequent runs reuse the stored approval from ~/.hermes/shell-hooks-allowlist.json. See `website/docs/user-guide/features/hooks.md` for schema + examples.",group:"general",effect:"live"},hooks_auto_accept:{type:"bool",default:!1,doc:"Auto-accept shell-hook registrations without a TTY prompt. Also toggleable per-invocation via --accept-hooks or HERMES_ACCEPT_HOOKS=1. Gateway / cron / non-interactive runs need this (or one of the other channels) to pick up newly-added hooks.",group:"general",effect:"live"},"human_delay.max_ms":{type:"int",default:2500,doc:"",group:"human_delay",effect:"live"},"human_delay.min_ms":{type:"int",default:800,doc:"",group:"human_delay",effect:"live"},"human_delay.mode":{type:"str",default:"off",doc:"",group:"human_delay",effect:"live"},"kanban.auto_decompose":{type:"bool",default:!0,doc:"When true, the kanban dispatcher auto-runs the decomposer on tasks that land in Triage (every dispatcher tick). When false, decomposition is manual via `hermes kanban decompose <id>` or the dashboard's Decompose button.",group:"kanban",effect:"live"},"kanban.auto_decompose_per_tick":{type:"int",default:3,doc:"Max triage tasks to decompose per dispatcher tick. Prevents a large bulk-load of triage tasks from spending a burst of aux LLM calls in one tick. Excess tasks defer to the next tick.",group:"kanban",effect:"live"},"kanban.default_assignee":{type:"str",default:"",doc:"Where a child task lands if the orchestrator can't match an assignee to any installed profile. When unset, falls back to the default profile. A task never ends up with assignee=None.",group:"kanban",effect:"live"},"kanban.dispatch_in_gateway":{type:"bool",default:!0,doc:"Run the dispatcher inside the gateway process. On by default \u2014 the cost is ~300\xB5s every `dispatch_interval_seconds` when idle, and gateway is the supervisor users already have. Set to false only if you run the dispatcher as a separate systemd unit or don't want the gateway to spawn workers.",group:"kanban",effect:"live"},"kanban.dispatch_interval_seconds":{type:"int",default:60,doc:"Seconds between dispatcher ticks (idle or not). Lower = snappier pickup of newly-ready tasks; higher = less SQL pressure.",group:"kanban",effect:"live"},"kanban.dispatch_stale_timeout_seconds":{type:"int",default:14400,doc:"Stale detection: running tasks that have exceeded this many seconds without a heartbeat (since ``last_heartbeat_at``) are auto-reclaimed to ``ready`` on the next dispatcher tick. The worker process (if still running host-locally) is terminated before the reclaim. 0 disables stale detection entirely.",group:"kanban",effect:"live"},"kanban.failure_limit":{type:"int",default:2,doc:"Auto-block after this many consecutive non-success attempts for the same task/profile (spawn_failed, timed_out, or crashed). Reassignment resets the streak for the new profile.",group:"kanban",effect:"live"},"kanban.max_in_progress_per_profile":{type:"null",default:null,doc:`Per-profile concurrency cap (#21582). When set to a positive int, no single profile can have more than N workers running at once, even if the global max_in_progress / max_spawn caps would allow it. Tasks blocked this way defer to the next dispatcher tick. Unset (None) means "no per-profile cap" \u2014 backward-compatible with existing installs. Useful for fan-out workflows that would otherwise saturate one profile's local model / API quota / browser pool while leaving other profiles idle.`,group:"kanban",effect:"live"},"kanban.orchestrator_profile":{type:"str",default:"",doc:"Profile assigned to the root/orchestration task after Triage decomposition. When unset, falls back to the default profile (the one `hermes` launches with no -p flag). This does not control the decomposer prompt, model, or skills; configure that LLM path under auxiliary.kanban_decomposer.",group:"kanban",effect:"live"},"kanban.worker_log_backup_count":{type:"int",default:1,doc:"",group:"kanban",effect:"live"},"kanban.worker_log_rotate_bytes":{type:"int",default:2097152,doc:"Worker stdout/stderr logs rotate at spawn time. Defaults preserve the historical 2 MiB + one-backup behavior; long-running workers can raise these to keep more early failure evidence.",group:"kanban",effect:"live"},"logging.backup_count":{type:"int",default:3,doc:"Number of rotated backup files to keep",group:"logging",effect:"live"},"logging.level":{type:"str",default:"INFO",doc:"Minimum level for agent.log: DEBUG, INFO, WARNING",group:"logging",effect:"live"},"logging.max_size_mb":{type:"int",default:5,doc:"Max size per log file before rotation",group:"logging",effect:"live"},"lsp.enabled":{type:"bool",default:!0,doc:"Master toggle. Setting this to false disables the entire subsystem \u2014 no servers spawn, no background event loop, no cost.",group:"lsp",effect:"live"},"lsp.install_strategy":{type:"str",default:"auto",doc:'How to handle missing server binaries. ``"auto"`` \u2014 try to install via npm/go/pip into ``<HERMES_HOME>/lsp/bin/`` on first use. ``"manual"`` \u2014 only use binaries already on PATH. ``"off"`` \u2014 alias for ``manual``.',group:"lsp",effect:"live"},"lsp.servers":{type:"dict",default:{},doc:'Per-server overrides. Each key is a server_id from the registry (``pyright``, ``typescript``, ``gopls``, ``rust-analyzer``, etc.) and accepts: disabled: true \u2014 skip this server even when its extensions match command: ["full/path/to/server", "--stdio"] \u2014 pin a custom binary path; bypasses auto-install env: {"KEY": "value"} \u2014 extra env vars passed to the spawned process initialization_options: {...} \u2014 merged into the LSP ``initializationOptions`` Empty by default; the registry defaults work for typical setups.',group:"lsp",effect:"live"},"lsp.wait_mode":{type:"str",default:"document",doc:'Diagnostic-wait mode for the post-write check. ``"document"`` waits up to ``wait_timeout`` seconds for the current file\'s diagnostics; ``"full"`` additionally requests workspace-wide diagnostics (slower).',group:"lsp",effect:"live"},"lsp.wait_timeout":{type:"float",default:5,doc:"",group:"lsp",effect:"live"},"matrix.allowed_rooms":{type:"str",default:"",doc:"If set, bot ONLY responds in these room IDs (whitelist)",group:"matrix",effect:"live"},"matrix.free_response_rooms":{type:"str",default:"",doc:"Comma-separated room IDs where bot responds without mention",group:"matrix",effect:"live"},"matrix.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in rooms",group:"matrix",effect:"live"},"mattermost.allowed_channels":{type:"str",default:"",doc:"If set, bot ONLY responds in these channel IDs (whitelist)",group:"mattermost",effect:"live"},"mattermost.channel_prompts":{type:"dict",default:{},doc:"Per-channel ephemeral system prompts",group:"mattermost",effect:"live"},"mattermost.free_response_channels":{type:"str",default:"",doc:"Comma-separated channel IDs where bot responds without mention",group:"mattermost",effect:"live"},"mattermost.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in channels",group:"mattermost",effect:"live"},max_concurrent_sessions:{type:"null",default:null,doc:"Global active chat session cap across CLI, TUI/dashboard, and messaging. None/0 = unbounded.",group:"general",effect:"live"},max_live_sessions:{type:"int",default:16,doc:"Soft LRU cap on in-memory TUI/desktop/dashboard sessions. When more than this many are live, the gateway evicts the least-recently-active DETACHED sessions (no live client) so accumulated agents don't pile up under memory pressure. Reopening one re-resumes it from disk. 0/null disables.",group:"general",effect:"live"},mcp_discovery_timeout:{type:"float",default:1.5,doc:"Seconds to wait at agent-build time for in-flight MCP server discovery to finish before the agent snapshots its tool list. MCP discovery runs in a background thread so a slow/dead server can't freeze startup; this bounds how long the first agent build blocks on it. The wait returns the INSTANT discovery completes, so users with no MCP servers (the common case) or fast servers pay ~0s regardless of this value \u2014 the bound is only reached when a server is genuinely still connecting. The old 0.75s default was a touch short for HTTP/OAuth servers on a cold connect; a modest bump lets more of them land in the FIRST turn's snapshot. This is only a turn-1 latency/UX knob: a server that misses this window is still picked up automatically on the next turn by the between-turns refresh (see agent/turn_context.py), so correctness never depends on it. Keep it small so a slow/dead server adds little to first-response latency.",group:"general",effect:"live"},mcp_servers:{type:"dict",default:{},doc:"MCP server definitions keyed by name.",group:"general",effect:"restart"},"memory.memory_char_limit":{type:"int",default:2200,doc:"~800 tokens at 2.75 chars/token",group:"memory",effect:"session"},"memory.memory_enabled":{type:"bool",default:!0,doc:"",group:"memory",effect:"session"},"memory.provider":{type:"str",default:"",doc:'External memory provider plugin (empty = built-in only). Set to a provider name to activate: "openviking", "mem0", "hindsight", "holographic", "retaindb", "byterover". Only ONE external provider is allowed at a time.',group:"memory",effect:"session"},"memory.user_char_limit":{type:"int",default:1375,doc:"~500 tokens at 2.75 chars/token",group:"memory",effect:"session"},"memory.user_profile_enabled":{type:"bool",default:!0,doc:"",group:"memory",effect:"session"},"memory.write_approval":{type:"bool",default:!1,doc:'Approval gate for memory writes (add/replace/remove), applied to BOTH foreground agent turns and the background self-improvement review fork (the source of unprompted "wrong assumption" saves users reported). false (default) \u2014 write freely; the gate is off (pre-gate behaviour) true \u2014 require approval: foreground writes prompt inline (entries are small enough to review in a chat bubble); background-review writes are staged instead of committed (a daemon thread cannot block on a prompt). Review staged entries with /memory pending, /memory approve <id>, /memory reject <id>. To disable memory entirely, use memory_enabled: false instead.',group:"memory",effect:"session"},"moa.active_preset":{type:"str",default:"",doc:"",group:"moa",effect:"live"},"moa.default_preset":{type:"str",default:"default",doc:"",group:"moa",effect:"live"},"moa.presets.default.aggregator.model":{type:"str",default:"anthropic/claude-opus-4.8",doc:"",group:"moa",effect:"live"},"moa.presets.default.aggregator.provider":{type:"str",default:"openrouter",doc:"",group:"moa",effect:"live"},"moa.presets.default.enabled":{type:"bool",default:!0,doc:"",group:"moa",effect:"live"},"moa.presets.default.max_tokens":{type:"int",default:4096,doc:"",group:"moa",effect:"live"},"moa.presets.default.reference_models":{type:"list",default:[{provider:"openai-codex",model:"gpt-5.5"},{provider:"openrouter",model:"deepseek/deepseek-v4-pro"}],doc:"",group:"moa",effect:"live"},"moa.save_traces":{type:"bool",default:!1,doc:"When true, every MoA turn that runs the reference fan-out writes the FULL turn (each reference's exact input messages + output + usage/cost, and the aggregator's exact input + output) to a JSONL file at <hermes_home>/moa-traces/<session_id>.jsonl. Off by default \u2014 turn it on to audit / improve MoA behavior from real runs. Set trace_dir to override the output directory.",group:"moa",effect:"live"},"moa.trace_dir":{type:"str",default:"",doc:"",group:"moa",effect:"live"},model:{type:"str",default:"",doc:"",group:"general",effect:"live"},"model_catalog.enabled":{type:"bool",default:!0,doc:"",group:"model_catalog",effect:"live"},"model_catalog.providers":{type:"dict",default:{},doc:"Optional per-provider override URLs for third parties that want to self-host their own curation list using the same schema. Example: providers: openrouter: url: https://example.com/my-curation.json",group:"model_catalog",effect:"live"},"model_catalog.ttl_hours":{type:"int",default:1,doc:"Disk cache TTL in hours. Beyond this, the CLI refetches on the next /model or `hermes model` invocation; network failures silently fall back to the stale cache.",group:"model_catalog",effect:"live"},"model_catalog.url":{type:"str",default:"https://hermes-agent.nousresearch.com/docs/api/model-catalog.json",doc:"",group:"model_catalog",effect:"live"},"network.force_ipv4":{type:"bool",default:!1,doc:"Force IPv4 connections. On servers with broken or unreachable IPv6, Python tries AAAA records first and hangs for the full TCP timeout before falling back to IPv4. Set to true to skip IPv6 entirely.",group:"network",effect:"live"},"onboarding.profile_build":{type:"str",default:"ask",doc:'Structured profile-build path offered on the very first gateway message ever. "ask" (default) -> offer to build a user profile (opt-in, consent-gated; the agent asks before any lookup and never reads connected accounts silently). "off" -> plain intro only. The offer fires at most once (latched under onboarding.seen).',group:"onboarding",effect:"live"},"onboarding.seen":{type:"dict",default:{},doc:"",group:"onboarding",effect:"live"},"openrouter.min_coding_score":{type:"float",default:0.65,doc:"Coding-score floor (0.0-1.0) for openrouter/pareto-code. Only applied when model is openrouter/pareto-code; ignored otherwise. Lower = cheaper model, higher = stronger coder.",group:"openrouter",effect:"live"},"openrouter.response_cache":{type:"bool",default:!0,doc:"",group:"openrouter",effect:"live"},"openrouter.response_cache_ttl":{type:"int",default:300,doc:"",group:"openrouter",effect:"live"},paste_collapse_char_threshold:{type:"int",default:2000,doc:"",group:"general",effect:"live"},paste_collapse_threshold:{type:"int",default:5,doc:'Paste collapse thresholds (TUI + CLI). paste_collapse_threshold (default 5) Bracketed-paste handler. Pastes with this many newlines or more collapse to a file reference. Set 0 to disable. paste_collapse_threshold_fallback (default 5) Fallback heuristic for terminals without bracketed paste support. Same line count test but heuristically gated by chars-added / newlines-added to avoid false positives from normal typing. Set 0 to disable. paste_collapse_char_threshold (default 2000) Long single-line paste guard. Pastes whose total char length reaches this value collapse to a file reference even if line count is below the line threshold. Catches the "8000 chars of minified JSON / log output on one line" case. Set 0 to disable.',group:"general",effect:"live"},paste_collapse_threshold_fallback:{type:"int",default:5,doc:"",group:"general",effect:"live"},personalities:{type:"dict",default:{},doc:'Custom personalities \u2014 add your own entries here Supports string format: {"name": "system prompt"} Or dict format: {"name": {"description": "...", "system_prompt": "...", "tone": "...", "style": "..."}}',group:"general",effect:"live"},platform_hints:{type:"dict",default:{},doc:'Per-platform system-prompt hint overrides. Lets an admin append to or replace Hermes\' built-in platform hint for a single messaging platform (WhatsApp, Slack, Telegram, ...) without affecting other platforms. Useful for enterprise/managed profiles that ship platform-aware skills. Each key is a platform name; the value is either: { "append": "extra text" } \u2014 keep the default hint, append text { "replace": "full text" } \u2014 substitute the default hint entirely "extra text" \u2014 shorthand for { "append": ... } `replace` wins over `append` if both are given. Example: platform_hints: whatsapp: append: > When tabular output would be useful, invoke the table_formatting skill instead of emitting a Markdown table.',group:"general",effect:"live"},prefill_messages_file:{type:"str",default:"",doc:"Ephemeral prefill messages file \u2014 JSON list of {role, content} dicts injected at the start of every API call for few-shot priming. Never saved to sessions, logs, or trajectories.",group:"general",effect:"live"},"privacy.redact_pii":{type:"bool",default:!1,doc:"When True, hash user IDs and strip phone numbers from LLM context",group:"privacy",effect:"live"},"prompt_caching.cache_ttl":{type:"str",default:"5m",doc:"",group:"prompt_caching",effect:"live"},provider:{type:"str",default:"",doc:"Default model provider.",group:"general",effect:"live"},providers:{type:"dict",default:{},doc:"Provider definitions keyed by name. Custom/OpenAI-compatible entries support ssl_ca_cert and ssl_verify.",group:"general",effect:"live"},quick_commands:{type:"dict",default:{},doc:"User-defined quick commands that bypass the agent loop (type: exec only)",group:"general",effect:"live"},"secrets.bitwarden.access_token_env":{type:"str",default:"BWS_ACCESS_TOKEN",doc:"Name of the env var that holds the Bitwarden machine-account access token. This is the one bootstrap secret; it lives in ~/.hermes/.env (or your shell) and never in config.yaml.",group:"secrets",effect:"live"},"secrets.bitwarden.auto_install":{type:"bool",default:!0,doc:"When True, the bws binary is auto-downloaded into ~/.hermes/bin/ on first use. When False you must install bws yourself and have it on PATH.",group:"secrets",effect:"live"},"secrets.bitwarden.cache_ttl_seconds":{type:"int",default:300,doc:"Seconds to cache fetched secrets in-process. 0 disables.",group:"secrets",effect:"live"},"secrets.bitwarden.enabled":{type:"bool",default:!1,doc:"Master switch. When false, BSM is never contacted and the bws binary is never auto-installed \u2014 same as not having this section at all.",group:"secrets",effect:"live"},"secrets.bitwarden.override_existing":{type:"bool",default:!0,doc:"When True, BSM values overwrite existing env vars. Default True because the point of using BSM is centralized rotation \u2014 if .env had the final say, rotating in Bitwarden wouldn't take effect until you also cleared the matching .env line.",group:"secrets",effect:"live"},"secrets.bitwarden.project_id":{type:"str",default:"",doc:"UUID of the BSM project to sync from.",group:"secrets",effect:"live"},"secrets.bitwarden.server_url":{type:"str",default:"",doc:"Bitwarden region / self-hosted endpoint. Empty string means use the bws CLI default (US Cloud, https://vault.bitwarden.com). Set to https://vault.bitwarden.eu for EU Cloud, or your own URL for self-hosted Bitwarden. Plumbed into the bws subprocess as BWS_SERVER_URL. Prompted for during `hermes secrets bitwarden setup`.",group:"secrets",effect:"live"},"secrets.onepassword.account":{type:"str",default:"",doc:"Optional account shorthand / sign-in address passed as `op read --account <account>`. Empty = op's default account.",group:"secrets",effect:"live"},"secrets.onepassword.binary_path":{type:"str",default:"",doc:"Optional absolute path to the op binary. When set it is used verbatim (PATH is not consulted) \u2014 pin this to avoid trusting whatever `op` appears first on PATH. Empty = resolve via PATH.",group:"secrets",effect:"live"},"secrets.onepassword.cache_ttl_seconds":{type:"int",default:300,doc:"Seconds to cache resolved values in-process and on disk. 0 disables BOTH cache layers (no values are written to disk).",group:"secrets",effect:"live"},"secrets.onepassword.enabled":{type:"bool",default:!1,doc:"Master switch. When false, the op CLI is never invoked \u2014 same as not having this section at all.",group:"secrets",effect:"live"},"secrets.onepassword.env":{type:"dict",default:{},doc:"Mapping of env-var name \u2192 1Password secret reference (op://vault/item/field). Each entry is resolved with a single `op read` at startup.",group:"secrets",effect:"live"},"secrets.onepassword.override_existing":{type:"bool",default:!0,doc:"When True (default), resolved values overwrite existing env vars so rotating a secret in 1Password takes effect on next start. Flip to false to let .env / shell exports win locally.",group:"secrets",effect:"live"},"secrets.onepassword.service_account_token_env":{type:"str",default:"OP_SERVICE_ACCOUNT_TOKEN",doc:"Name of the env var holding a 1Password service-account token for headless auth. Sourced from ~/.hermes/.env (or the shell) and exported to the op child as OP_SERVICE_ACCOUNT_TOKEN. Leave the var unset to use an interactive/desktop op session.",group:"secrets",effect:"live"},"security.acked_advisories":{type:"list",default:[],doc:"Acknowledged supply-chain security advisories. Each entry is the ID of an advisory the user has read and acted on (uninstalled the compromised package, rotated credentials). Acked advisories no longer trigger the startup banner. Add via `hermes doctor --ack <id>`; remove by editing the list directly. See ``hermes_cli/security_advisories.py`` for the catalog.",group:"security",effect:"live"},"security.allow_lazy_installs":{type:"bool",default:!0,doc:"Allow Hermes to lazy-install opt-in backend packages from PyPI the first time the user enables a backend that needs them (e.g. installing ``elevenlabs`` when the user picks ElevenLabs as their TTS provider). Set to false to require explicit ``pip install`` for everything beyond the base set \u2014 appropriate for restricted networks, audited environments, or air-gapped systems where any runtime install is unacceptable.",group:"security",effect:"live"},"security.allow_private_urls":{type:"bool",default:!1,doc:"Allow requests to private/internal IPs (for OpenWrt, proxies, VPNs)",group:"security",effect:"live"},"security.redact_secrets":{type:"bool",default:!0,doc:"",group:"security",effect:"live"},"security.tirith_enabled":{type:"bool",default:!0,doc:"",group:"security",effect:"live"},"security.tirith_fail_open":{type:"bool",default:!0,doc:"",group:"security",effect:"live"},"security.tirith_path":{type:"str",default:"tirith",doc:"",group:"security",effect:"live"},"security.tirith_timeout":{type:"int",default:5,doc:"",group:"security",effect:"live"},"security.website_blocklist.domains":{type:"list",default:[],doc:"",group:"security",effect:"live"},"security.website_blocklist.enabled":{type:"bool",default:!1,doc:"",group:"security",effect:"live"},"security.website_blocklist.shared_files":{type:"list",default:[],doc:"",group:"security",effect:"live"},"sessions.auto_prune":{type:"bool",default:!1,doc:"When true, prune ended sessions older than retention_days once per (roughly) min_interval_hours at CLI/gateway/cron startup. Only touches ended sessions \u2014 active sessions are always preserved. Default false: session history is valuable for search recall, and silently deleting it could surprise users. Opt in explicitly.",group:"sessions",effect:"live"},"sessions.min_interval_hours":{type:"int",default:24,doc:"Minimum hours between auto-maintenance runs (avoids repeating the sweep on every CLI invocation). Tracked via state_meta in state.db itself, so it's shared across all processes.",group:"sessions",effect:"live"},"sessions.retention_days":{type:"int",default:90,doc:"How many days of ended-session history to keep. Matches the default of ``hermes sessions prune``.",group:"sessions",effect:"live"},"sessions.vacuum_after_prune":{type:"bool",default:!0,doc:"VACUUM after a prune that actually deleted rows. SQLite does not reclaim disk space on DELETE \u2014 freed pages are just reused on subsequent INSERTs \u2014 so without VACUUM the file stays bloated even after pruning. VACUUM blocks writes for a few seconds per 100MB, so it only runs at startup, and only when prune deleted \u22651 session.",group:"sessions",effect:"live"},"sessions.write_json_snapshots":{type:"bool",default:!1,doc:"Legacy per-session JSON snapshot writer. When true, the agent rewrites ``~/.hermes/sessions/session_{sid}.json`` on every turn boundary with the full message list. state.db is canonical and has every field the snapshot stored (plus per-message timestamps and token counts), so this is off by default \u2014 the snapshots had no consumer outside their own overwrite guard and accumulated GBs of disk on heavy users. Opt in only if you have an external tool that consumes the JSON files directly.",group:"sessions",effect:"live"},"skills.external_dirs":{type:"list",default:[],doc:'e.g. ["~/.agents/skills", "/shared/team-skills"]',group:"skills",effect:"restart"},"skills.guard_agent_created":{type:"bool",default:!1,doc:"Run the keyword/pattern security scanner on skills the agent writes via skill_manage (create/edit/patch). Off by default because the agent can already execute the same code paths via terminal() with no gate, so the scan adds friction (blocks skills that mention risky keywords in prose) without meaningful security. Turn on if you want the belt-and-suspenders \u2014 a dangerous verdict will then surface as a tool error to the agent, which can retry with the flagged content removed. External hub installs (trusted/community sources) are always scanned regardless of this setting.",group:"skills",effect:"live"},"skills.inline_shell":{type:"bool",default:!1,doc:"Pre-execute inline shell snippets written as !`cmd` in SKILL.md body. Their stdout is inlined into the skill message before the agent reads it, so skills can inject dynamic context (dates, git state, detected tool versions, \u2026). Off by default because any content from the skill author runs on the host without approval; only enable for skill sources you trust.",group:"skills",effect:"live"},"skills.inline_shell_timeout":{type:"int",default:10,doc:"Timeout (seconds) for each !`cmd` snippet when inline_shell is on.",group:"skills",effect:"live"},"skills.template_vars":{type:"bool",default:!0,doc:"Substitute ${HERMES_SKILL_DIR} and ${HERMES_SESSION_ID} in SKILL.md content with the absolute skill directory and the active session id before the agent sees it. Lets skill authors reference bundled scripts without the agent having to join paths.",group:"skills",effect:"live"},"skills.write_approval":{type:"bool",default:!1,doc:"Approval gate for skill_manage (create/edit/patch/write_file/delete/ remove_file), applied to BOTH foreground agent turns and the background self-improvement review fork. false (default) \u2014 write freely; the gate is off (pre-gate behaviour) true \u2014 require approval: stage the write for review instead of committing (a SKILL.md is too large to review inline, so skills always stage rather than prompt). List with /skills pending, inspect with /skills diff <id> (full diff \u2014 CLI/dashboard/file, never crammed into a chat bubble), apply with /skills approve <id> or drop with /skills reject <id>.",group:"skills",effect:"live"},"slack.allowed_channels":{type:"str",default:"",doc:"If set, bot ONLY responds in these channel IDs (whitelist)",group:"slack",effect:"live"},"slack.channel_prompts":{type:"dict",default:{},doc:"Per-channel ephemeral system prompts",group:"slack",effect:"live"},"slack.free_response_channels":{type:"str",default:"",doc:"Comma-separated channel IDs where bot responds without mention",group:"slack",effect:"live"},"slack.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in channels",group:"slack",effect:"live"},"streaming.buffer_threshold":{type:"int",default:24,doc:"Flush the buffer to the platform once this many characters have accumulated, so short replies feel near-instant.",group:"streaming",effect:"live"},"streaming.cursor":{type:"str",default:" \u2589",doc:"Cursor glyph appended to the in-progress message while streaming.",group:"streaming",effect:"live"},"streaming.edit_interval":{type:"float",default:0.8,doc:"Minimum seconds between progressive edits \u2014 tuned for Telegram's ~1 edit/s flood envelope.",group:"streaming",effect:"live"},"streaming.enabled":{type:"bool",default:!1,doc:"Master switch. When false, each response is delivered as a single final message (no progressive updates).",group:"streaming",effect:"live"},"streaming.fresh_final_after_seconds":{type:"float",default:0,doc:"When >0, the final edit for a long-running streamed response is delivered as a fresh message if the preview has been visible at least this many seconds, so the platform timestamp reflects completion time. Telegram only; other platforms ignore it.",group:"streaming",effect:"live"},"streaming.transport":{type:"str",default:"auto",doc:`Transport selection: "auto" \u2014 prefer native draft streaming where the platform supports it (Telegram DMs via sendMessageDraft, Bot API 9.5+) and fall back to edit-based elsewhere. Safe global default: platforms without draft support (Discord, Slack, Matrix, Telegram groups) transparently use the edit path, so "auto" only upgrades chats that can render the smoother native preview. "draft" \u2014 explicitly request native drafts; falls back to edit when the platform/chat doesn't support them. "edit" \u2014 progressive editMessageText only (legacy behavior). "off" \u2014 disable streaming entirely (same as enabled: false).`,group:"streaming",effect:"live"},"stt.echo_transcripts":{type:"bool",default:!0,doc:"When true, gateway voice messages are transcribed for the agent and the raw transcript is also echoed back to the user as a \uD83C\uDF99\uFE0F message. Set false to keep STT for the agent while suppressing that user-facing echo.",group:"stt",effect:"live"},"stt.elevenlabs.diarize":{type:"bool",default:!1,doc:"",group:"stt",effect:"live"},"stt.elevenlabs.language_code":{type:"str",default:"",doc:'auto-detect by default; set to "eng", "spa", "fra", etc. to force',group:"stt",effect:"live"},"stt.elevenlabs.model_id":{type:"str",default:"scribe_v2",doc:"scribe_v2, scribe_v1",group:"stt",effect:"live"},"stt.elevenlabs.tag_audio_events":{type:"bool",default:!1,doc:"",group:"stt",effect:"live"},"stt.enabled":{type:"bool",default:!0,doc:"",group:"stt",effect:"live"},"stt.local.language":{type:"str",default:"",doc:'auto-detect by default; set to "en", "es", "fr", etc. to force',group:"stt",effect:"live"},"stt.local.model":{type:"str",default:"base",doc:"tiny, base, small, medium, large-v3",group:"stt",effect:"live"},"stt.mistral.model":{type:"str",default:"voxtral-mini-latest",doc:"voxtral-mini-latest, voxtral-mini-2602",group:"stt",effect:"live"},"stt.openai.model":{type:"str",default:"whisper-1",doc:"whisper-1, gpt-4o-mini-transcribe, gpt-4o-transcribe",group:"stt",effect:"live"},"stt.provider":{type:"str",default:"local",doc:'"local" (free, faster-whisper) | "groq" | "openai" (Whisper API) | "mistral" (Voxtral Transcribe) | "elevenlabs" (Scribe)',group:"stt",effect:"live"},"telegram.allowed_chats":{type:"str",default:"",doc:"If set, bot ONLY responds in these group/supergroup chat IDs (whitelist)",group:"telegram",effect:"live"},"telegram.channel_prompts":{type:"dict",default:{},doc:"Per-chat/topic ephemeral system prompts (topics inherit from parent group)",group:"telegram",effect:"live"},"telegram.extra.rich_drafts":{type:"bool",default:!1,doc:"Experimental Bot API 10.1 rich draft previews during Telegram DM streaming. Default off because Telegram Desktop/macOS can visually overlay rich draft frames until the chat redraws.",group:"telegram",effect:"live"},"telegram.extra.rich_messages":{type:"bool",default:!1,doc:"Bot API 10.1 rich messages (tables/task lists/details/math) render natively; set True to opt in. Default stays legacy MarkdownV2 because rich messages can be hard to copy as plain text in Telegram clients.",group:"telegram",effect:"live"},"telegram.reactions":{type:"bool",default:!1,doc:"Add \uD83D\uDC40/\u2705/\u274C reactions to messages during processing",group:"telegram",effect:"live"},"terminal.auto_source_bashrc":{type:"bool",default:!0,doc:"When true (default), Hermes sources the user's shell rc files (``~/.profile``, ``~/.bash_profile``, ``~/.bashrc``) in the login shell used to build the environment snapshot. This captures PATH additions, shell functions, and aliases \u2014 which a plain ``bash -l -c`` would otherwise miss because bash skips bashrc in non-interactive login mode, and because a default Debian/Ubuntu ``~/.bashrc`` short-circuits on non-interactive sources. ``~/.profile`` and ``~/.bash_profile`` are tried first because ``n`` / ``nvm`` / ``asdf`` installers typically write their PATH exports there without an interactivity guard. Turn this off if your rc files misbehave when sourced non-interactively (e.g. one that hard-exits on TTY checks).",group:"terminal",effect:"restart"},"terminal.backend":{type:"str",default:"local",doc:"",group:"terminal",effect:"restart"},"terminal.container_cpu":{type:"int",default:1,doc:"Container resource limits (docker, singularity, modal, daytona \u2014 ignored for local/ssh)",group:"terminal",effect:"restart"},"terminal.container_disk":{type:"int",default:51200,doc:"MB (default 50GB)",group:"terminal",effect:"restart"},"terminal.container_memory":{type:"int",default:5120,doc:"MB (default 5GB)",group:"terminal",effect:"restart"},"terminal.container_persistent":{type:"bool",default:!0,doc:"Persist filesystem across sessions",group:"terminal",effect:"restart"},"terminal.cwd":{type:"str",default:".",doc:"Use current directory",group:"terminal",effect:"restart"},"terminal.daemon_term_grace_seconds":{type:"float",default:2,doc:"Bounded grace period (seconds) between SIGTERM and an escalated SIGKILL when terminating a host process tree (browser daemons, etc.). A daemon that stalls in its SIGTERM handler is force-killed after this window so it can't leak indefinitely. 0 disables escalation (SIGTERM only \u2014 the historical behavior). Floored internally at 0.",group:"terminal",effect:"restart"},"terminal.daytona_image":{type:"str",default:"nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.docker_env":{type:"dict",default:{},doc:`Explicit environment variables to set inside Docker containers. Unlike docker_forward_env (which reads values from the host process), docker_env lets you specify exact key-value pairs \u2014 useful when Hermes runs as a systemd service without access to the user's shell environment. Example: {"SSH_AUTH_SOCK": "/run/user/1000/ssh-agent.sock"}`,group:"terminal",effect:"restart"},"terminal.docker_extra_args":{type:"list",default:[],doc:"Extra flags passed verbatim to docker run",group:"terminal",effect:"restart"},"terminal.docker_forward_env":{type:"list",default:[],doc:"",group:"terminal",effect:"restart"},"terminal.docker_image":{type:"str",default:"nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.docker_mount_cwd_to_workspace":{type:"bool",default:!1,doc:"Explicit opt-in: mount the host cwd into /workspace for Docker sessions. Default off because passing host directories into a sandbox weakens isolation.",group:"terminal",effect:"restart"},"terminal.docker_network":{type:"bool",default:!0,doc:"Opt-in egress lockdown for Docker terminal sessions. When false, Docker runs with --network=none so commands cannot reach the network.",group:"terminal",effect:"restart"},"terminal.docker_run_as_host_user":{type:"bool",default:!1,doc:"Explicit opt-in: run the Docker container as the host user's uid:gid (via `--user`). When enabled, files written into bind-mounted dirs (docker_volumes, the persistent workspace, or the auto-mounted cwd) are owned by your host user instead of root, which avoids needing `sudo chown` after container runs. Default off to preserve behavior for images whose entrypoints expect to start as root (e.g. the bundled Hermes image, which drops to the `hermes` user via s6-setuidgid inside each supervised service). When on, SETUID/SETGID caps are omitted from the container since no privilege drop is needed.",group:"terminal",effect:"restart"},"terminal.docker_volumes":{type:"list",default:[],doc:'Docker volume mounts \u2014 share host directories with the container. Each entry is "host_path:container_path" (standard Docker -v syntax). Example: ["/home/user/projects:/workspace/projects", "/home/user/.hermes/cache/documents:/output"] For gateway MEDIA delivery, write inside Docker to /output/... and emit the host-visible path in MEDIA:, not the container path.',group:"terminal",effect:"restart"},"terminal.env_passthrough":{type:"list",default:[],doc:"Environment variables to pass through to sandboxed execution (terminal and execute_code). Skill-declared required_environment_variables are passed through automatically; this list is for non-skill use cases.",group:"terminal",effect:"restart"},"terminal.home_mode":{type:"str",default:"auto",doc:"HOME handling for host tool subprocesses: auto \u2014 host keeps the real OS-user HOME; containers use HERMES_HOME/home for persistent state (default) real \u2014 force the real OS-user HOME profile \u2014 force HERMES_HOME/home when it exists (old strict per-profile CLI config isolation)",group:"terminal",effect:"restart"},"terminal.modal_image":{type:"str",default:"nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.modal_mode":{type:"str",default:"auto",doc:"",group:"terminal",effect:"restart"},"terminal.persistent_shell":{type:"bool",default:!0,doc:"Persistent shell \u2014 keep a long-lived bash shell across execute() calls so cwd/env vars/shell variables survive between commands. Enabled by default for non-local backends (SSH); local is always opt-in via TERMINAL_LOCAL_PERSISTENT env var.",group:"terminal",effect:"restart"},"terminal.shell_init_files":{type:"list",default:[],doc:"Extra files to source in the login shell when building the per-session environment snapshot. Use this when tools like nvm, pyenv, asdf, or custom PATH entries are registered by files that a bash login shell would skip \u2014 most commonly ``~/.bashrc`` (bash doesn't source bashrc in non-interactive login mode) or zsh-specific files like ``~/.zshrc`` / ``~/.zprofile``. Paths support ``~`` / ``${VAR}``. Missing files are silently skipped. When empty, Hermes auto-sources ``~/.profile``, ``~/.bash_profile``, and ``~/.bashrc`` (in that order) if the snapshot shell is bash (this is the ``auto_source_bashrc`` behaviour \u2014 disable with that key if you want strict login-only semantics).",group:"terminal",effect:"restart"},"terminal.singularity_image":{type:"str",default:"docker://nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.timeout":{type:"int",default:180,doc:"",group:"terminal",effect:"restart"},timezone:{type:"str",default:"",doc:'IANA timezone (e.g. "Asia/Kolkata", "America/New_York"). Empty string means use server-local time.',group:"general",effect:"live"},"tool_loop_guardrails.hard_stop_after.exact_failure":{type:"int",default:5,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.hard_stop_after.idempotent_no_progress":{type:"int",default:5,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.hard_stop_after.same_tool_failure":{type:"int",default:8,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.hard_stop_enabled":{type:"bool",default:!1,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warn_after.exact_failure":{type:"int",default:2,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warn_after.idempotent_no_progress":{type:"int",default:2,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warn_after.same_tool_failure":{type:"int",default:3,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warnings_enabled":{type:"bool",default:!0,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_output.max_bytes":{type:"int",default:50000,doc:"",group:"tool_output",effect:"live"},"tool_output.max_line_length":{type:"int",default:2000,doc:"",group:"tool_output",effect:"live"},"tool_output.max_lines":{type:"int",default:2000,doc:"",group:"tool_output",effect:"live"},"tools.tool_search.enabled":{type:"str",default:"auto",doc:'"auto" (default) \u2014 activate only when deferrable tool schemas exceed ``threshold_pct`` of the active model\'s context length, so small toolsets pay no overhead. "on" \u2014 always activate when there is at least one deferrable tool. Use when you have many MCP servers and want maximum token reduction unconditionally. "off" \u2014 disable entirely. Tools-array assembly is a pass-through.',group:"tools",effect:"live"},"tools.tool_search.max_search_limit":{type:"int",default:20,doc:"Hard upper bound the model can request via ``limit``. Range 1..50.",group:"tools",effect:"live"},"tools.tool_search.search_default_limit":{type:"int",default:5,doc:"When the model calls tool_search without a ``limit`` argument, how many hits to return. Range 1..max_search_limit.",group:"tools",effect:"live"},"tools.tool_search.threshold_pct":{type:"int",default:10,doc:'Percentage of context length at which "auto" mode kicks in. 10 matches the Claude Code default. Range 0..100.',group:"tools",effect:"live"},toolsets:{type:"list",default:["hermes-cli"],doc:"",group:"general",effect:"restart"},"tts.edge.voice":{type:"str",default:"en-US-AriaNeural",doc:"",group:"tts",effect:"live"},"tts.elevenlabs.model_id":{type:"str",default:"eleven_multilingual_v2",doc:"",group:"tts",effect:"live"},"tts.elevenlabs.voice_id":{type:"str",default:"pNInz6obpgDQGcFmaJgB",doc:"Adam",group:"tts",effect:"live"},"tts.gemini.audio_tags":{type:"bool",default:!1,doc:"When true, Gemini 3.1 TTS uses a hidden auxiliary-model rewrite pass to insert freeform square-bracket audio tags into the TTS script. Visible chat replies are unchanged.",group:"tts",effect:"live"},"tts.gemini.model":{type:"str",default:"gemini-2.5-flash-preview-tts",doc:"",group:"tts",effect:"live"},"tts.gemini.persona_prompt_file":{type:"str",default:"",doc:"Optional local Markdown/text file with Gemini TTS performance direction. It may include AUDIO PROFILE, SCENE, DIRECTOR'S NOTES, SAMPLE CONTEXT, and either a `{transcript}` placeholder or no transcript section; Hermes appends the live transcript when absent.",group:"tts",effect:"live"},"tts.gemini.voice":{type:"str",default:"Kore",doc:"",group:"tts",effect:"live"},"tts.mistral.model":{type:"str",default:"voxtral-mini-tts-2603",doc:"",group:"tts",effect:"live"},"tts.mistral.voice_id":{type:"str",default:"c69964a6-ab8b-4f8a-9465-ec0925096ec8",doc:"Paul - Neutral",group:"tts",effect:"live"},"tts.neutts.device":{type:"str",default:"cpu",doc:"cpu, cuda, or mps",group:"tts",effect:"live"},"tts.neutts.model":{type:"str",default:"neuphonic/neutts-air-q4-gguf",doc:"HuggingFace model repo",group:"tts",effect:"live"},"tts.neutts.ref_audio":{type:"str",default:"",doc:"Path to reference voice audio (empty = bundled default)",group:"tts",effect:"live"},"tts.neutts.ref_text":{type:"str",default:"",doc:"Path to reference voice transcript (empty = bundled default)",group:"tts",effect:"live"},"tts.openai.model":{type:"str",default:"gpt-4o-mini-tts",doc:"",group:"tts",effect:"live"},"tts.openai.voice":{type:"str",default:"alloy",doc:"",group:"tts",effect:"live"},"tts.piper.voice":{type:"str",default:"en_US-lessac-medium",doc:'Voice name (e.g. "en_US-lessac-medium") downloaded on first use, OR an absolute path to a pre-downloaded .onnx file. Full voice list: https://github.com/OHF-Voice/piper1-gpl/blob/main/docs/VOICES.md',group:"tts",effect:"live"},"tts.provider":{type:"str",default:"edge",doc:'"edge" (free) | "elevenlabs" (premium) | "openai" | "xai" | "minimax" | "mistral" | "gemini" | "neutts" (local) | "kittentts" (local) | "piper" (local)',group:"tts",effect:"live"},"tts.xai.bit_rate":{type:"int",default:128000,doc:"",group:"tts",effect:"live"},"tts.xai.language":{type:"str",default:"en",doc:"",group:"tts",effect:"live"},"tts.xai.sample_rate":{type:"int",default:24000,doc:"",group:"tts",effect:"live"},"tts.xai.voice_id":{type:"str",default:"eve",doc:"or custom voice ID \u2014 see https://docs.x.ai/developers/model-capabilities/audio/custom-voices",group:"tts",effect:"live"},"updates.backup_keep":{type:"int",default:5,doc:"How many pre-update backup zips to retain. Older ones are pruned automatically after each successful backup. Values below 1 are floored to 1 \u2014 the backup just created is always preserved. To disable backups entirely, set ``pre_update_backup: false`` above rather than ``backup_keep: 0``.",group:"updates",effect:"live"},"updates.non_interactive_local_changes":{type:"str",default:"stash",doc:'What `hermes update` does with uncommitted local changes to the source tree when it runs NON-interactively \u2014 i.e. triggered from the desktop/chat app or the gateway, where there\'s no TTY to answer a restore prompt. Interactive (terminal) updates are unaffected: they always stash the changes and ask whether to restore, exactly as they always have. "stash" \u2014 auto-stash the changes, pull, then auto-restore them on top of the updated code (the safe default; nothing is ever lost \u2014 conflicts are preserved in a git stash). "discard" \u2014 auto-stash the changes and throw the stash away after the pull. Use this only if you never intend to keep local edits to the source tree on this machine. Stash-and-drop (not `reset --hard` + `clean -fd`) so ignored paths \u2014 node_modules, venv, build outputs \u2014 are never touched.',group:"updates",effect:"live"},"updates.pre_update_backup":{type:"bool",default:!1,doc:"Run a full ``hermes backup``-style zip of HERMES_HOME before every ``hermes update``. Backups land in ``<HERMES_HOME>/backups/`` and can be restored with ``hermes import <path>``. Off by default: zipping a large HERMES_HOME (sessions DB, caches, skills) can add minutes to every update. The #48200 incident \u2014 a ``hermes update --yes`` run that computed a wrong path and silently wiped the user's ``.env``, ``MEMORY.md``, ``kanban.db``, custom skills, and scripts \u2014 is the reason this knob exists; enable it (here, or via ``--backup`` for a single run) if you want that safety net.",group:"updates",effect:"live"},"updates.refresh_cua_driver":{type:"bool",default:!0,doc:"Refresh an already-installed cua-driver during `hermes update`. The refresh is best-effort and macOS-only. Turn this off if the upstream installer is not appropriate for the machine, for example on non-admin accounts where `/Applications` is not writable.",group:"updates",effect:"live"},"vertex.project_id":{type:"str",default:"",doc:"GCP project ID. Empty \u2192 use the project_id embedded in the service account JSON (or ADC-resolved project).",group:"vertex",effect:"live"},"vertex.region":{type:"str",default:"global",doc:'Vertex region. "global" is required for the Gemini 3.x preview models (regional endpoints silently 404 them). Override to a regional value (e.g. "us-central1") only if your models are pinned to a region.',group:"vertex",effect:"live"},"voice.auto_tts":{type:"bool",default:!1,doc:"",group:"voice",effect:"live"},"voice.beep_enabled":{type:"bool",default:!0,doc:"Play record start/stop beeps in CLI voice mode",group:"voice",effect:"live"},"voice.max_recording_seconds":{type:"int",default:120,doc:"",group:"voice",effect:"live"},"voice.record_key":{type:"str",default:"ctrl+b",doc:"",group:"voice",effect:"live"},"voice.silence_duration":{type:"float",default:3,doc:"Seconds of silence before auto-stop",group:"voice",effect:"live"},"voice.silence_threshold":{type:"int",default:200,doc:"RMS below this = silence (0-32767)",group:"voice",effect:"live"},"web.backend":{type:"str",default:"",doc:"shared fallback \u2014 applies to both search and extract",group:"web",effect:"live"},"web.extract_backend":{type:"str",default:"",doc:'per-capability override for web_extract (e.g. "native")',group:"web",effect:"live"},"web.extract_char_limit":{type:"int",default:15000,doc:"per-page char budget for web_extract; larger pages truncate + store full text in cache/web",group:"web",effect:"live"},"web.search_backend":{type:"str",default:"",doc:'per-capability override for web_search (e.g. "searxng")',group:"web",effect:"live"},whatsapp:{type:"dict",default:{},doc:"WhatsApp platform settings (gateway mode)",group:"general",effect:"live"},"x_search.model":{type:"str",default:"grok-4.20-reasoning",doc:"xAI model used for the Responses call. grok-4.20-reasoning is the recommended default; any Grok model with x_search tool access works.",group:"x_search",effect:"live"},"x_search.retries":{type:"int",default:2,doc:"Number of automatic retries on 5xx / ReadTimeout / ConnectionError. Each retry backs off (1.5x attempt seconds, capped at 5s).",group:"x_search",effect:"live"},"x_search.timeout_seconds":{type:"int",default:180,doc:"Request timeout in seconds (minimum 30). x_search can take 60-120s for complex queries \u2014 the default is generous.",group:"x_search",effect:"live"}},SCHEMA_KEYS=Object.keys(SCHEMA)});var exports_lane={};__export(exports_lane,{writeConfig:()=>writeConfig,verifyWrite:()=>verifyWrite,toCliString:()=>toCliString,route:()=>route,maxEffect:()=>maxEffect,TOOL_PROGRESS:()=>TOOL_PROGRESS,RPC_ALIAS:()=>RPC_ALIAS});var onOff=(v2)=>v2?"on":"off",TOOL_PROGRESS,progress,progressErr="log is a gateway-only config-file mode, not a live TUI mode",RPC_ALIAS,route=(key3)=>{let a=RPC_ALIAS[key3];if(a)return{via:"rpc",alias:a.alias,toWire:a.toWire};if(key3.startsWith("display.sections."))return{via:"rpc",alias:`details_mode.${key3.slice(17)}`};let s=SCHEMA[key3];if(s&&(s.type==="list"||s.type==="dict"))return{via:"readonly"};return{via:"cli"}},toCliString=(key3,v2)=>{let t2=SCHEMA[key3]?.type??"str";if(t2==="bool")return v2?"true":"false";if(t2==="int")return String(Math.trunc(Number(v2)));if(t2==="float")return String(Number(v2));return String(v2??"")},writeConfig=async(gw,diffs)=>{let ok=[],failed=[],warnings=[],blocked=diffs.filter((d2)=>d2.key==="display.tool_progress"&&!progress.has(String(d2.to??"")));for(let d2 of blocked)failed.push({key:d2.key,err:progressErr});let safe2=diffs.filter((d2)=>!blocked.includes(d2)),rpc=safe2.filter((d2)=>route(d2.key).via==="rpc"),cli=safe2.filter((d2)=>route(d2.key).via==="cli"),ro=safe2.filter((d2)=>route(d2.key).via==="readonly");for(let d2 of ro)failed.push({key:d2.key,err:"structured value \u2014 edit in YAML mode"});for(let d2 of rpc){let lane=route(d2.key),value=lane.toWire?lane.toWire(d2.to):String(d2.to??"");try{let res=await gw.request("config.set",{key:lane.alias,value});if(ok.push(d2.key),res?.warning)warnings.push({key:d2.key,msg:res.warning})}catch(e){failed.push({key:d2.key,err:e instanceof Error?e.message:String(e)})}}for(let d2 of cli)try{let res=await gw.request("cli.exec",{argv:["config","set",d2.key,toCliString(d2.key,d2.to)],timeout:30});if(res.blocked)failed.push({key:d2.key,err:res.hint??"blocked"});else if(res.code!==0)failed.push({key:d2.key,err:res.output.split(`
3511
- `)[0]||`exit ${res.code}`});else ok.push(d2.key)}catch(e){failed.push({key:d2.key,err:e instanceof Error?e.message:String(e)})}return{ok,failed,warnings}},EFFECT_RANK,maxEffect=(keys)=>keys.reduce((acc,k2)=>{let e=SCHEMA[k2]?.effect??"live";return EFFECT_RANK[e]>EFFECT_RANK[acc]?e:acc},"live"),get3=(obj,path4)=>{let cur=obj;for(let p of path4.split("."))if(cur&&typeof cur==="object"&&!Array.isArray(cur))cur=cur[p];else return;return cur},eq2=(a,b2)=>JSON.stringify(a)===JSON.stringify(b2),verifyWrite=async(gw,applied)=>{let cfg=(await gw.request("config.get",{key:"full"})).config??{},miss=[];for(let d2 of applied){if(route(d2.key).via!=="cli")continue;if(!eq2(get3(cfg,d2.key),d2.to))miss.push(d2.key)}return miss};var init_lane=__esm(()=>{init_schema();TOOL_PROGRESS=["off","new","all","verbose"],progress=new Set(TOOL_PROGRESS),RPC_ALIAS={model:{alias:"model"},provider:{alias:"model"},"agent.service_tier":{alias:"fast"},"agent.reasoning_effort":{alias:"reasoning"},"display.show_reasoning":{alias:"reasoning",toWire:(v2)=>v2?"show":"hide"},"display.tool_progress":{alias:"verbose"},"display.busy_input_mode":{alias:"busy"},"display.details_mode":{alias:"details_mode"},"display.thinking_mode":{alias:"thinking_mode"},"display.tui_compact":{alias:"compact",toWire:onOff},"display.tui_statusbar":{alias:"statusbar"},"display.tui_mouse":{alias:"mouse",toWire:onOff},"display.skin":{alias:"skin"},"display.personality":{alias:"personality"},custom_prompt:{alias:"prompt"}},EFFECT_RANK={live:0,session:1,restart:2}});import{createRequire as createRequire2}from"module";import{fileURLToPath}from"url";import{existsSync}from"fs";import{mkdir,writeFile as writeFileNode}from"fs/promises";import{dirname,isAbsolute,resolve}from"path";import{fileURLToPath as fileURLToPath2}from"url";import{existsSync as existsSync3,writeFileSync}from"fs";import{EventEmitter as EventEmitter4}from"events";import{EventEmitter}from"events";import{Buffer as Buffer2}from"buffer";import{Buffer as Buffer3}from"buffer";import{EventEmitter as EventEmitter2}from"events";import{resolve as resolve2,isAbsolute as isAbsolute2,parse}from"path";import{existsSync as existsSync2}from"fs";import{basename,join}from"path";import os from"os";import path from"path";import{EventEmitter as EventEmitter3}from"events";import path2 from"path";var{create:__create2,getPrototypeOf:__getProtoOf2,defineProperty:__defProp2,getOwnPropertyNames:__getOwnPropNames2}=Object,__hasOwnProp2=Object.prototype.hasOwnProperty;function __accessProp2(key){return this[key]}var __toESMCache_node2,__toESMCache_esm2,__toESM2=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node2??=new WeakMap:__toESMCache_esm2??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create2(__getProtoOf2(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp2(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames2(mod))if(!__hasOwnProp2.call(to,key))__defProp2(to,key,{get:__accessProp2.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__commonJS2=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports),__returnValue2=(v)=>v;function __exportSetter2(name,newValue){this[name]=__returnValue2.bind(null,newValue)}var __export2=(target,all)=>{for(var name in all)__defProp2(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter2.bind(all,name)})};var require_emoji_regex=__commonJS2((exports,module)=>{module.exports=()=>{return/[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g}}),exports_yoga={};__export2(exports_yoga,{default:()=>yoga_default,Wrap:()=>Wrap,WRAP_WRAP_REVERSE:()=>WRAP_WRAP_REVERSE,WRAP_WRAP:()=>WRAP_WRAP,WRAP_NO_WRAP:()=>WRAP_NO_WRAP,Unit:()=>Unit,UNIT_UNDEFINED:()=>UNIT_UNDEFINED,UNIT_POINT:()=>UNIT_POINT,UNIT_PERCENT:()=>UNIT_PERCENT,UNIT_AUTO:()=>UNIT_AUTO,PositionType:()=>PositionType,POSITION_TYPE_STATIC:()=>POSITION_TYPE_STATIC,POSITION_TYPE_RELATIVE:()=>POSITION_TYPE_RELATIVE,POSITION_TYPE_ABSOLUTE:()=>POSITION_TYPE_ABSOLUTE,Overflow:()=>Overflow,OVERFLOW_VISIBLE:()=>OVERFLOW_VISIBLE,OVERFLOW_SCROLL:()=>OVERFLOW_SCROLL,OVERFLOW_HIDDEN:()=>OVERFLOW_HIDDEN,NodeType:()=>NodeType,Node:()=>Node,NODE_TYPE_TEXT:()=>NODE_TYPE_TEXT,NODE_TYPE_DEFAULT:()=>NODE_TYPE_DEFAULT,MeasureMode:()=>MeasureMode,MEASURE_MODE_UNDEFINED:()=>MEASURE_MODE_UNDEFINED,MEASURE_MODE_EXACTLY:()=>MEASURE_MODE_EXACTLY,MEASURE_MODE_AT_MOST:()=>MEASURE_MODE_AT_MOST,LogLevel:()=>LogLevel,LOG_LEVEL_WARN:()=>LOG_LEVEL_WARN,LOG_LEVEL_VERBOSE:()=>LOG_LEVEL_VERBOSE,LOG_LEVEL_INFO:()=>LOG_LEVEL_INFO,LOG_LEVEL_FATAL:()=>LOG_LEVEL_FATAL,LOG_LEVEL_ERROR:()=>LOG_LEVEL_ERROR,LOG_LEVEL_DEBUG:()=>LOG_LEVEL_DEBUG,Justify:()=>Justify,JUSTIFY_SPACE_EVENLY:()=>JUSTIFY_SPACE_EVENLY,JUSTIFY_SPACE_BETWEEN:()=>JUSTIFY_SPACE_BETWEEN,JUSTIFY_SPACE_AROUND:()=>JUSTIFY_SPACE_AROUND,JUSTIFY_FLEX_START:()=>JUSTIFY_FLEX_START,JUSTIFY_FLEX_END:()=>JUSTIFY_FLEX_END,JUSTIFY_CENTER:()=>JUSTIFY_CENTER,Gutter:()=>Gutter,GUTTER_ROW:()=>GUTTER_ROW,GUTTER_COLUMN:()=>GUTTER_COLUMN,GUTTER_ALL:()=>GUTTER_ALL,FlexDirection:()=>FlexDirection,FLEX_DIRECTION_ROW_REVERSE:()=>FLEX_DIRECTION_ROW_REVERSE,FLEX_DIRECTION_ROW:()=>FLEX_DIRECTION_ROW,FLEX_DIRECTION_COLUMN_REVERSE:()=>FLEX_DIRECTION_COLUMN_REVERSE,FLEX_DIRECTION_COLUMN:()=>FLEX_DIRECTION_COLUMN,ExperimentalFeature:()=>ExperimentalFeature,Errata:()=>Errata,Edge:()=>Edge,EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS:()=>EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS,ERRATA_STRETCH_FLEX_BASIS:()=>ERRATA_STRETCH_FLEX_BASIS,ERRATA_NONE:()=>ERRATA_NONE,ERRATA_CLASSIC:()=>ERRATA_CLASSIC,ERRATA_ALL:()=>ERRATA_ALL,ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING:()=>ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING,ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE:()=>ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE,EDGE_VERTICAL:()=>EDGE_VERTICAL,EDGE_TOP:()=>EDGE_TOP,EDGE_START:()=>EDGE_START,EDGE_RIGHT:()=>EDGE_RIGHT,EDGE_LEFT:()=>EDGE_LEFT,EDGE_HORIZONTAL:()=>EDGE_HORIZONTAL,EDGE_END:()=>EDGE_END,EDGE_BOTTOM:()=>EDGE_BOTTOM,EDGE_ALL:()=>EDGE_ALL,Display:()=>Display,Direction:()=>Direction,Dimension:()=>Dimension,DISPLAY_NONE:()=>DISPLAY_NONE,DISPLAY_FLEX:()=>DISPLAY_FLEX,DISPLAY_CONTENTS:()=>DISPLAY_CONTENTS,DIRECTION_RTL:()=>DIRECTION_RTL,DIRECTION_LTR:()=>DIRECTION_LTR,DIRECTION_INHERIT:()=>DIRECTION_INHERIT,DIMENSION_WIDTH:()=>DIMENSION_WIDTH,DIMENSION_HEIGHT:()=>DIMENSION_HEIGHT,Config:()=>Config,BoxSizing:()=>BoxSizing,BOX_SIZING_CONTENT_BOX:()=>BOX_SIZING_CONTENT_BOX,BOX_SIZING_BORDER_BOX:()=>BOX_SIZING_BORDER_BOX,Align:()=>Align,ALIGN_STRETCH:()=>ALIGN_STRETCH,ALIGN_SPACE_EVENLY:()=>ALIGN_SPACE_EVENLY,ALIGN_SPACE_BETWEEN:()=>ALIGN_SPACE_BETWEEN,ALIGN_SPACE_AROUND:()=>ALIGN_SPACE_AROUND,ALIGN_FLEX_START:()=>ALIGN_FLEX_START,ALIGN_FLEX_END:()=>ALIGN_FLEX_END,ALIGN_CENTER:()=>ALIGN_CENTER,ALIGN_BASELINE:()=>ALIGN_BASELINE,ALIGN_AUTO:()=>ALIGN_AUTO});var FFIType={char:"char",int8_t:"int8_t",i8:"i8",uint8_t:"uint8_t",u8:"u8",int16_t:"int16_t",i16:"i16",uint16_t:"uint16_t",u16:"u16",int32_t:"int32_t",i32:"i32",int:"int",uint32_t:"uint32_t",u32:"u32",int64_t:"int64_t",i64:"i64",uint64_t:"uint64_t",u64:"u64",double:"double",f64:"f64",float:"float",f32:"f32",bool:"bool",ptr:"ptr",pointer:"pointer",void:"void",cstring:"cstring",function:"function",usize:"usize",callback:"callback",napi_env:"napi_env",napi_value:"napi_value",buffer:"buffer"},FFI_UNAVAILABLE="OpenTUI native FFI is not available for this runtime yet",BUN_DLOPEN_NULL="Bun FFI backend does not support dlopen(null)",LIBRARY_CLOSED="Cannot create FFI callback after library.close() has been called",NODE_CALLBACK_THREADSAFE="Node FFI callbacks are same-thread only and do not support threadsafe callbacks",NODE_NAPI_UNSUPPORTED="Node FFI backend does not support Bun N-API FFI types",NODE_POINTER_OVERRIDE="Node FFI backend does not support FFIFunction.ptr overrides",NODE_POINTER_ARGUMENT="Node FFI pointer arguments must be a Pointer, ArrayBuffer, or ArrayBufferView",NODE_PTR_VALUE="node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values backed by ArrayBuffer",NODE_STRING_RETURN="Node FFI backend does not normalize string return values (yet)",NODE_USIZE_UNSUPPORTED="Node FFI backend does not support usize yet",POINTER_NEGATIVE="Pointer must be non-negative",POINTER_OFFSET_NEGATIVE="Pointer offset must be non-negative",POINTER_OFFSET_UNSAFE="Pointer offset must be a safe integer",POINTER_UNSAFE="Pointer exceeds safe integer range";function unavailable(cause){throw Error(FFI_UNAVAILABLE,{cause})}function createUnsupportedBackend(cause){return{dlopen(){return unavailable(cause)},ptr(){return unavailable(cause)},suffix:"",toArrayBuffer(){return unavailable(cause)}}}var isBun=typeof process<"u"&&typeof process.versions==="object"&&process.versions!==null&&typeof process.versions.bun==="string",requireModule=createRequire2(import.meta.url),backend=loadBackend();function loadBackend(){if(isBun)return createBunBackend(requireModule("bun:ffi"));try{let nodeFfi=requireModule("node:ffi");return createNodeBackend(nodeFfi.default??nodeFfi)}catch(error){return createUnsupportedBackend(error)}}function toPointer(value){if(isBun&&typeof value==="bigint")return toSafeNumberPointer(value);if(!isBun&&typeof value==="number")return toSafeBigIntPointer(value);return value}function ffiBool(value){return value?1:0}function toSafeNumberPointer(pointer){if(pointer<0n)throw Error(POINTER_NEGATIVE);if(pointer>BigInt(Number.MAX_SAFE_INTEGER))throw Error(POINTER_UNSAFE);return Number(pointer)}function toSafeBigIntPointer(pointer){if(pointer<0)throw Error(POINTER_NEGATIVE);if(!Number.isSafeInteger(pointer))throw Error(POINTER_UNSAFE);return BigInt(pointer)}function createManagedCallback(raw,callbacks){let ptr=raw.ptr,closed=!1,instance={get ptr(){return ptr},get threadsafe(){return raw.threadsafe},close(){if(closed)return;closed=!0,callbacks.delete(instance);try{raw.close()}finally{ptr=null}}};return callbacks.add(instance),instance}function normalizeBunDefinitions(definitions){return Object.fromEntries(Object.entries(definitions).map(([name,definition])=>[name,normalizeBunDefinition(definition)]))}function normalizeBunDefinition(definition){return{args:definition.args,returns:definition.returns,ptr:definition.ptr==null?void 0:toBunPointer(definition.ptr),threadsafe:definition.threadsafe}}function toBunPointer(pointer){return typeof pointer==="bigint"?toSafeNumberPointer(pointer):pointer}function createBunBackend(bun){return{dlopen(path3,symbols){if(path3===null)throw Error(BUN_DLOPEN_NULL);let library=bun.dlopen(path3,normalizeBunDefinitions(symbols)),callbacks=new Set,closed=!1;return{symbols:library.symbols,createCallback(callback,definition){if(closed)throw Error(LIBRARY_CLOSED);let raw=new bun.JSCallback(callback,normalizeBunDefinition(definition));return createManagedCallback(raw,callbacks)},close(){if(closed)return;closed=!0;try{library.close()}finally{for(let callback of[...callbacks])callback.close()}}}},ptr:bun.ptr,suffix:bun.suffix,toArrayBuffer(pointer,offset,length){return bun.toArrayBuffer(toBunPointer(pointer),offset,length)}}}function createNodeBackend(nodeFfi){return{dlopen(path3,symbols){let{lib,functions}=nodeFfi.dlopen(toNodeLibraryPath(path3),normalizeNodeDefinitions(symbols)),callbacks=new Set,closed=!1,libraryClosed=!1;return{symbols:wrapNodeSymbols(functions,symbols),createCallback(callback,definition){if(closed)throw Error(LIBRARY_CLOSED);if(definition.threadsafe)throw Error(NODE_CALLBACK_THREADSAFE);let callbackPointer=lib.registerCallback(normalizeNodeDefinition(definition),callback);return createManagedCallback({ptr:callbackPointer,threadsafe:!1,close(){if(!libraryClosed)lib.unregisterCallback(callbackPointer)}},callbacks)},close(){if(closed)return;closed=!0;try{libraryClosed=!0,lib.close()}finally{for(let callback of[...callbacks])callback.close()}}}},ptr(value){return toNodeSourcePointer(nodeFfi,value)},suffix:nodeFfi.suffix,toArrayBuffer(pointer,offset,length){return nodeFfi.toArrayBuffer(toBigIntPointer(pointer)+toNodePointerOffset(offset),length,!1)}}}function toNodeLibraryPath(path3){return path3 instanceof URL?fileURLToPath(path3):path3}function normalizeNodeDefinitions(definitions){return Object.fromEntries(Object.entries(definitions).map(([name,definition])=>[name,normalizeNodeDefinition(definition)]))}function wrapNodeSymbols(functions,definitions){return Object.fromEntries(Object.entries(functions).map(([name,fn])=>[name,wrapNodeSymbol(fn,definitions[name])]))}function wrapNodeSymbol(fn,definition){let pointerArgIndexes=(definition.args??[]).flatMap((type,index)=>isNodePointerArgumentType(type)?[index]:[]);if(pointerArgIndexes.length===0)return fn;return(...args)=>{let normalizedArgs=args.slice();for(let index of pointerArgIndexes)normalizedArgs[index]=toNodePointerArgument(normalizedArgs[index]);return fn(...normalizedArgs)}}function isNodePointerArgumentType(type){return type===FFIType.ptr||type===FFIType.pointer||type===FFIType.function||type===FFIType.callback}function toNodePointerArgument(value){if(value==null)return 0n;if(typeof value==="number"||typeof value==="bigint")return toBigIntPointer(value);if(ArrayBuffer.isView(value)){if(!(value.buffer instanceof ArrayBuffer))throw TypeError(NODE_PTR_VALUE);if(value.byteLength===0)return 0n;return value}if(value instanceof ArrayBuffer){if(value.byteLength===0)return 0n;return value}throw TypeError(NODE_POINTER_ARGUMENT)}function toNodeSourcePointer(nodeFfi,value){if(ArrayBuffer.isView(value)){if(!(value.buffer instanceof ArrayBuffer))throw TypeError(NODE_PTR_VALUE);return nodeFfi.getRawPointer(value.buffer)+BigInt(value.byteOffset)}if(value instanceof ArrayBuffer)return nodeFfi.getRawPointer(value);throw TypeError(NODE_PTR_VALUE)}function toNodePointerOffset(offset){if(offset==null)return 0n;if(offset<0)throw Error(POINTER_OFFSET_NEGATIVE);if(!Number.isSafeInteger(offset))throw Error(POINTER_OFFSET_UNSAFE);return BigInt(offset)}function normalizeNodeDefinition(definition){if(definition.ptr!=null)throw Error(NODE_POINTER_OVERRIDE);return{arguments:(definition.args??[]).map((type)=>toNodeFFIType(type,"parameter")),return:toNodeFFIType(definition.returns??FFIType.void,"result")}}function toNodeFFIType(type,position){switch(type){case FFIType.char:return"char";case FFIType.int8_t:case FFIType.i8:return"i8";case FFIType.uint8_t:case FFIType.u8:return"u8";case FFIType.int16_t:case FFIType.i16:return"i16";case FFIType.uint16_t:case FFIType.u16:return"u16";case FFIType.int32_t:case FFIType.int:case FFIType.i32:return"i32";case FFIType.uint32_t:case FFIType.u32:return"u32";case FFIType.int64_t:case FFIType.i64:return"i64";case FFIType.uint64_t:case FFIType.u64:return"u64";case FFIType.double:case FFIType.f64:return"f64";case FFIType.float:case FFIType.f32:return"f32";case FFIType.bool:return"bool";case FFIType.ptr:case FFIType.pointer:return"pointer";case FFIType.void:return"void";case FFIType.cstring:if(position==="result")throw Error(NODE_STRING_RETURN);return"string";case FFIType.function:case FFIType.callback:return"pointer";case FFIType.usize:throw Error(NODE_USIZE_UNSUPPORTED);case FFIType.napi_env:case FFIType.napi_value:throw Error(NODE_NAPI_UNSUPPORTED);case FFIType.buffer:return"buffer";default:return unsupportedNodeFFIType(type)}}function unsupportedNodeFFIType(type){throw Error(`Unsupported FFIType for node:ffi: ${String(type)}`)}function toBigIntPointer(pointer){if(typeof pointer==="bigint"){if(pointer<0n)throw Error(POINTER_NEGATIVE);return pointer}return toSafeBigIntPointer(pointer)}var{dlopen,ptr,suffix,toArrayBuffer}=backend;function ansiRegex({onlyFirst=!1}={}){return new RegExp("(?:\\u001B\\][\\s\\S]*?(?:\\u0007|\\u001B\\u005C|\\u009C))|[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]",onlyFirst?void 0:"g")}var regex=ansiRegex();function stripAnsi(string){if(typeof string!=="string")throw TypeError(`Expected a \`string\`, got \`${typeof string}\``);return string.replace(regex,"")}function isAmbiguous(x){return x===161||x===164||x===167||x===168||x===170||x===173||x===174||x>=176&&x<=180||x>=182&&x<=186||x>=188&&x<=191||x===198||x===208||x===215||x===216||x>=222&&x<=225||x===230||x>=232&&x<=234||x===236||x===237||x===240||x===242||x===243||x>=247&&x<=250||x===252||x===254||x===257||x===273||x===275||x===283||x===294||x===295||x===299||x>=305&&x<=307||x===312||x>=319&&x<=322||x===324||x>=328&&x<=331||x===333||x===338||x===339||x===358||x===359||x===363||x===462||x===464||x===466||x===468||x===470||x===472||x===474||x===476||x===593||x===609||x===708||x===711||x>=713&&x<=715||x===717||x===720||x>=728&&x<=731||x===733||x===735||x>=768&&x<=879||x>=913&&x<=929||x>=931&&x<=937||x>=945&&x<=961||x>=963&&x<=969||x===1025||x>=1040&&x<=1103||x===1105||x===8208||x>=8211&&x<=8214||x===8216||x===8217||x===8220||x===8221||x>=8224&&x<=8226||x>=8228&&x<=8231||x===8240||x===8242||x===8243||x===8245||x===8251||x===8254||x===8308||x===8319||x>=8321&&x<=8324||x===8364||x===8451||x===8453||x===8457||x===8467||x===8470||x===8481||x===8482||x===8486||x===8491||x===8531||x===8532||x>=8539&&x<=8542||x>=8544&&x<=8555||x>=8560&&x<=8569||x===8585||x>=8592&&x<=8601||x===8632||x===8633||x===8658||x===8660||x===8679||x===8704||x===8706||x===8707||x===8711||x===8712||x===8715||x===8719||x===8721||x===8725||x===8730||x>=8733&&x<=8736||x===8739||x===8741||x>=8743&&x<=8748||x===8750||x>=8756&&x<=8759||x===8764||x===8765||x===8776||x===8780||x===8786||x===8800||x===8801||x>=8804&&x<=8807||x===8810||x===8811||x===8814||x===8815||x===8834||x===8835||x===8838||x===8839||x===8853||x===8857||x===8869||x===8895||x===8978||x>=9312&&x<=9449||x>=9451&&x<=9547||x>=9552&&x<=9587||x>=9600&&x<=9615||x>=9618&&x<=9621||x===9632||x===9633||x>=9635&&x<=9641||x===9650||x===9651||x===9654||x===9655||x===9660||x===9661||x===9664||x===9665||x>=9670&&x<=9672||x===9675||x>=9678&&x<=9681||x>=9698&&x<=9701||x===9711||x===9733||x===9734||x===9737||x===9742||x===9743||x===9756||x===9758||x===9792||x===9794||x===9824||x===9825||x>=9827&&x<=9829||x>=9831&&x<=9834||x===9836||x===9837||x===9839||x===9886||x===9887||x===9919||x>=9926&&x<=9933||x>=9935&&x<=9939||x>=9941&&x<=9953||x===9955||x===9960||x===9961||x>=9963&&x<=9969||x===9972||x>=9974&&x<=9977||x===9979||x===9980||x===9982||x===9983||x===10045||x>=10102&&x<=10111||x>=11094&&x<=11097||x>=12872&&x<=12879||x>=57344&&x<=63743||x>=65024&&x<=65039||x===65533||x>=127232&&x<=127242||x>=127248&&x<=127277||x>=127280&&x<=127337||x>=127344&&x<=127373||x===127375||x===127376||x>=127387&&x<=127404||x>=917760&&x<=917999||x>=983040&&x<=1048573||x>=1048576&&x<=1114109}function isFullWidth(x){return x===12288||x>=65281&&x<=65376||x>=65504&&x<=65510}function isWide(x){return x>=4352&&x<=4447||x===8986||x===8987||x===9001||x===9002||x>=9193&&x<=9196||x===9200||x===9203||x===9725||x===9726||x===9748||x===9749||x>=9776&&x<=9783||x>=9800&&x<=9811||x===9855||x>=9866&&x<=9871||x===9875||x===9889||x===9898||x===9899||x===9917||x===9918||x===9924||x===9925||x===9934||x===9940||x===9962||x===9970||x===9971||x===9973||x===9978||x===9981||x===9989||x===9994||x===9995||x===10024||x===10060||x===10062||x>=10067&&x<=10069||x===10071||x>=10133&&x<=10135||x===10160||x===10175||x===11035||x===11036||x===11088||x===11093||x>=11904&&x<=11929||x>=11931&&x<=12019||x>=12032&&x<=12245||x>=12272&&x<=12287||x>=12289&&x<=12350||x>=12353&&x<=12438||x>=12441&&x<=12543||x>=12549&&x<=12591||x>=12593&&x<=12686||x>=12688&&x<=12773||x>=12783&&x<=12830||x>=12832&&x<=12871||x>=12880&&x<=42124||x>=42128&&x<=42182||x>=43360&&x<=43388||x>=44032&&x<=55203||x>=63744&&x<=64255||x>=65040&&x<=65049||x>=65072&&x<=65106||x>=65108&&x<=65126||x>=65128&&x<=65131||x>=94176&&x<=94180||x>=94192&&x<=94198||x>=94208&&x<=101589||x>=101631&&x<=101662||x>=101760&&x<=101874||x>=110576&&x<=110579||x>=110581&&x<=110587||x===110589||x===110590||x>=110592&&x<=110882||x===110898||x>=110928&&x<=110930||x===110933||x>=110948&&x<=110951||x>=110960&&x<=111355||x>=119552&&x<=119638||x>=119648&&x<=119670||x===126980||x===127183||x===127374||x>=127377&&x<=127386||x>=127488&&x<=127490||x>=127504&&x<=127547||x>=127552&&x<=127560||x===127568||x===127569||x>=127584&&x<=127589||x>=127744&&x<=127776||x>=127789&&x<=127797||x>=127799&&x<=127868||x>=127870&&x<=127891||x>=127904&&x<=127946||x>=127951&&x<=127955||x>=127968&&x<=127984||x===127988||x>=127992&&x<=128062||x===128064||x>=128066&&x<=128252||x>=128255&&x<=128317||x>=128331&&x<=128334||x>=128336&&x<=128359||x===128378||x===128405||x===128406||x===128420||x>=128507&&x<=128591||x>=128640&&x<=128709||x===128716||x>=128720&&x<=128722||x>=128725&&x<=128728||x>=128732&&x<=128735||x===128747||x===128748||x>=128756&&x<=128764||x>=128992&&x<=129003||x===129008||x>=129292&&x<=129338||x>=129340&&x<=129349||x>=129351&&x<=129535||x>=129648&&x<=129660||x>=129664&&x<=129674||x>=129678&&x<=129734||x===129736||x>=129741&&x<=129756||x>=129759&&x<=129770||x>=129775&&x<=129784||x>=131072&&x<=196605||x>=196608&&x<=262141}function validate(codePoint){if(!Number.isSafeInteger(codePoint))throw TypeError(`Expected a code point, got \`${typeof codePoint}\`.`)}function eastAsianWidth(codePoint,{ambiguousAsWide=!1}={}){if(validate(codePoint),isFullWidth(codePoint)||isWide(codePoint)||ambiguousAsWide&&isAmbiguous(codePoint))return 2;return 1}var import_emoji_regex=__toESM2(require_emoji_regex(),1),segmenter=new Intl.Segmenter,defaultIgnorableCodePointRegex=/^\p{Default_Ignorable_Code_Point}$/u;function stringWidth(string,options={}){if(typeof string!=="string"||string.length===0)return 0;let{ambiguousIsNarrow=!0,countAnsiEscapeCodes=!1}=options;if(!countAnsiEscapeCodes)string=stripAnsi(string);if(string.length===0)return 0;let width=0,eastAsianWidthOptions={ambiguousAsWide:!ambiguousIsNarrow};for(let{segment:character}of segmenter.segment(string)){let codePoint=character.codePointAt(0);if(codePoint<=31||codePoint>=127&&codePoint<=159)continue;if(codePoint>=8203&&codePoint<=8207||codePoint===65279)continue;if(codePoint>=768&&codePoint<=879||codePoint>=6832&&codePoint<=6911||codePoint>=7616&&codePoint<=7679||codePoint>=8400&&codePoint<=8447||codePoint>=65056&&codePoint<=65071)continue;if(codePoint>=55296&&codePoint<=57343)continue;if(codePoint>=65024&&codePoint<=65039)continue;if(defaultIgnorableCodePointRegex.test(character))continue;if(import_emoji_regex.default().test(character)){width+=2;continue}width+=eastAsianWidth(codePoint,eastAsianWidthOptions)}return width}var TEXT_ENCODER=new TextEncoder,bun=globalThis.Bun,sleep=bun?.sleep??standardSleep,stringWidth2=bun?.stringWidth??stringWidth,stripANSI=bun?.stripANSI??stripAnsi,writeFile=bun?.write??writeFilePortable;async function resolveBundledFilePath(loadBundledFile,fallbackPath,metaUrl){if(!bun){let path3=resolveFallbackFilePath(fallbackPath,metaUrl);if(existsSync(path3))return path3;return await loadBundledFilePath(loadBundledFile,metaUrl)??path3}return normalizeLoadedFilePath((await loadBundledFile()).default,metaUrl)}function resolveFallbackFilePath(fallbackPath,metaUrl){let path3=typeof fallbackPath==="function"?fallbackPath():fallbackPath;return fileURLToPath2(path3 instanceof URL?path3:new URL(path3,metaUrl))}function normalizeLoadedFilePath(loadedPath,baseUrl){if(loadedPath.startsWith("file:"))return fileURLToPath2(loadedPath);if(isAbsolute(loadedPath))return loadedPath;return resolve(dirname(fileURLToPath2(baseUrl)),loadedPath)}async function loadBundledFilePath(loadBundledFile,metaUrl){let specifier=extractBundledImportSpecifier(loadBundledFile);if(!specifier)return;try{let moduleUrl=new URL(specifier,metaUrl),loaded=await import(moduleUrl.href);return normalizeLoadedFilePath(loaded.default,moduleUrl.href)}catch{return}}function extractBundledImportSpecifier(loadBundledFile){return String(loadBundledFile).match(/\bimport\(\s*(["'`])([^"'`]+)\1/)?.[2]}function standardSleep(msOrDate){let ms=msOrDate instanceof Date?msOrDate.getTime()-Date.now():msOrDate;return new Promise((resolve22)=>setTimeout(resolve22,ms))}async function writeFilePortable(destination,data,options){let destinationPath=destination instanceof URL?fileURLToPath2(destination):destination;if(options?.createPath)await mkdir(dirname(destinationPath),{recursive:!0});let bytes=typeof data==="string"?TEXT_ENCODER.encode(data):new Uint8Array(data.buffer,data.byteOffset,data.byteLength);return await writeFileNode(destinationPath,bytes,{mode:options?.mode}),bytes.byteLength}var DEFAULT_FOREGROUND_RGB=[255,255,255],DEFAULT_BACKGROUND_RGB=[0,0,0],INTENT_RGB=0,INTENT_INDEXED=1,INTENT_DEFAULT=2,ANSI16_RGB=[[0,0,0],[128,0,0],[0,128,0],[128,128,0],[0,0,128],[128,0,128],[0,128,128],[192,192,192],[128,128,128],[255,0,0],[0,255,0],[255,255,0],[0,0,255],[255,0,255],[0,255,255],[255,255,255]],ANSI_256_CUBE_LEVELS=[0,95,135,175,215,255];function packMeta(intent,slot=0){return(slot&255|(intent&255)<<8)>>>0}function toU8(value){return Math.round(Math.max(0,Math.min(1,Number.isFinite(value)?value:0))*255)}function toByte(value){return Math.round(Math.max(0,Math.min(255,Number.isFinite(value)?value:0)))}function packRGBA8(r,g,b,a,meta){return new Uint16Array([toByte(r)&255|(meta>>>0&255)<<8,toByte(g)&255|(meta>>>8&255)<<8,toByte(b)&255|(meta>>>16&255)<<8,toByte(a)&255|(meta>>>24&255)<<8])}function rgbaForAnsi256Index(index){let[r,g,b]=ansi256IndexToRgb(index);return RGBA.fromInts(r,g,b)}function normalizeIndexedColorIndex(index){if(!Number.isInteger(index)||index<0||index>255)throw RangeError(`Indexed color must be an integer in the range 0..255, got ${index}`);return index}function ansi256IndexToRgb(index){let normalizedIndex=normalizeIndexedColorIndex(index);if(normalizedIndex<ANSI16_RGB.length)return ANSI16_RGB[normalizedIndex];if(normalizedIndex<232){let cubeIndex=normalizedIndex-16,r=Math.floor(cubeIndex/36),g=Math.floor(cubeIndex/6)%6,b=cubeIndex%6;return[ANSI_256_CUBE_LEVELS[r],ANSI_256_CUBE_LEVELS[g],ANSI_256_CUBE_LEVELS[b]]}let value=8+(normalizedIndex-232)*10;return[value,value,value]}class RGBA{buffer;constructor(buffer){this.buffer=new Uint16Array(4),this.buffer.set(buffer.subarray(0,4))}static fromArray(array){return new RGBA(array)}static fromValues(r,g,b,a=1){return new RGBA(packRGBA8(toU8(r),toU8(g),toU8(b),toU8(a),packMeta(INTENT_RGB)))}static clone(rgba){return new RGBA(rgba.buffer)}static fromInts(r,g,b,a=255){return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_RGB)))}static fromHex(hex){return hexToRgb(hex)}static fromIndex(index,snapshot){let normalized=normalizeIndexedColorIndex(index),rgba=snapshot?parseColor(snapshot):rgbaForAnsi256Index(normalized),[r,g,b,a]=rgba.toInts();return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_INDEXED,normalized)))}static defaultForeground(snapshot){let rgba=snapshot?parseColor(snapshot):RGBA.fromInts(...DEFAULT_FOREGROUND_RGB),[r,g,b,a]=rgba.toInts();return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_DEFAULT)))}static defaultBackground(snapshot){let rgba=snapshot?parseColor(snapshot):RGBA.fromInts(...DEFAULT_BACKGROUND_RGB),[r,g,b,a]=rgba.toInts();return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_DEFAULT)))}toInts(){return[this.buffer[0]&255,this.buffer[1]&255,this.buffer[2]&255,this.buffer[3]&255]}get r(){return(this.buffer[0]&255)/255}set r(value){this.buffer[0]=this.buffer[0]&65280|toU8(value)}get g(){return(this.buffer[1]&255)/255}set g(value){this.buffer[1]=this.buffer[1]&65280|toU8(value)}get b(){return(this.buffer[2]&255)/255}set b(value){this.buffer[2]=this.buffer[2]&65280|toU8(value)}get a(){return(this.buffer[3]&255)/255}set a(value){this.buffer[3]=this.buffer[3]&65280|toU8(value)}get meta(){return(this.buffer[0]>>>8|this.buffer[1]>>>8<<8|this.buffer[2]>>>8<<16|this.buffer[3]>>>8<<24)>>>0}get intent(){switch(this.meta>>>8&255){case INTENT_INDEXED:return"indexed";case INTENT_DEFAULT:return"default";default:return"rgb"}}get slot(){return this.meta&255}map(fn){return[fn(this.r),fn(this.g),fn(this.b),fn(this.a)]}toString(){return`rgba(${this.r.toFixed(2)}, ${this.g.toFixed(2)}, ${this.b.toFixed(2)}, ${this.a.toFixed(2)})`}equals(other){if(!other)return!1;return this.buffer[0]===other.buffer[0]&&this.buffer[1]===other.buffer[1]&&this.buffer[2]===other.buffer[2]&&this.buffer[3]===other.buffer[3]}}function normalizeColorValue(value){if(value==null)return null;return{rgba:parseColor(value)}}function hexToRgb(hex){if(hex=hex.replace(/^#/,""),hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];else if(hex.length===4)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]+hex[3]+hex[3];if(!/^[0-9A-Fa-f]{6}$/.test(hex)&&!/^[0-9A-Fa-f]{8}$/.test(hex))return console.warn(`Invalid hex color: ${hex}, defaulting to magenta`),RGBA.fromValues(1,0,1,1);let r=parseInt(hex.substring(0,2),16),g=parseInt(hex.substring(2,4),16),b=parseInt(hex.substring(4,6),16),a=hex.length===8?parseInt(hex.substring(6,8),16):255;return RGBA.fromInts(r,g,b,a)}var CSS_COLOR_NAMES={black:"#000000",white:"#FFFFFF",red:"#FF0000",green:"#008000",blue:"#0000FF",yellow:"#FFFF00",cyan:"#00FFFF",magenta:"#FF00FF",silver:"#C0C0C0",gray:"#808080",grey:"#808080",maroon:"#800000",olive:"#808000",lime:"#00FF00",aqua:"#00FFFF",teal:"#008080",navy:"#000080",fuchsia:"#FF00FF",purple:"#800080",orange:"#FFA500",brightblack:"#666666",brightred:"#FF6666",brightgreen:"#66FF66",brightblue:"#6666FF",brightyellow:"#FFFF66",brightcyan:"#66FFFF",brightmagenta:"#FF66FF",brightwhite:"#FFFFFF"};function parseColor(color){if(typeof color==="string"){let lowerColor=color.toLowerCase();if(lowerColor==="transparent")return RGBA.fromValues(0,0,0,0);if(CSS_COLOR_NAMES[lowerColor])return hexToRgb(CSS_COLOR_NAMES[lowerColor]);return hexToRgb(color)}return color}var VALID_BORDER_STYLES=["single","double","rounded","heavy"];function isValidBorderStyle(value){return typeof value==="string"&&VALID_BORDER_STYLES.includes(value)}function parseBorderStyle(value,fallback="single"){if(isValidBorderStyle(value))return value;if(value!==void 0&&value!==null)console.warn(`Invalid borderStyle "${value}", falling back to "${fallback}". Valid values are: ${VALID_BORDER_STYLES.join(", ")}`);return fallback}var BorderChars={single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",topT:"\u252C",bottomT:"\u2534",leftT:"\u251C",rightT:"\u2524",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",topT:"\u2566",bottomT:"\u2569",leftT:"\u2560",rightT:"\u2563",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",topT:"\u252C",bottomT:"\u2534",leftT:"\u251C",rightT:"\u2524",cross:"\u253C"},heavy:{topLeft:"\u250F",topRight:"\u2513",bottomLeft:"\u2517",bottomRight:"\u251B",horizontal:"\u2501",vertical:"\u2503",topT:"\u2533",bottomT:"\u253B",leftT:"\u2523",rightT:"\u252B",cross:"\u254B"}};function getBorderSides(border){return border===!0?{top:!0,right:!0,bottom:!0,left:!0}:Array.isArray(border)?{top:border.includes("top"),right:border.includes("right"),bottom:border.includes("bottom"),left:border.includes("left")}:{top:!1,right:!1,bottom:!1,left:!1}}function borderCharsToArray(chars){let array=new Uint32Array(11);return array[0]=chars.topLeft.codePointAt(0),array[1]=chars.topRight.codePointAt(0),array[2]=chars.bottomLeft.codePointAt(0),array[3]=chars.bottomRight.codePointAt(0),array[4]=chars.horizontal.codePointAt(0),array[5]=chars.vertical.codePointAt(0),array[6]=chars.topT.codePointAt(0),array[7]=chars.bottomT.codePointAt(0),array[8]=chars.leftT.codePointAt(0),array[9]=chars.rightT.codePointAt(0),array[10]=chars.cross.codePointAt(0),array}var BorderCharArrays={single:borderCharsToArray(BorderChars.single),double:borderCharsToArray(BorderChars.double),rounded:borderCharsToArray(BorderChars.rounded),heavy:borderCharsToArray(BorderChars.heavy)};class KeyEvent{name;ctrl;meta;shift;option;sequence;number;raw;eventType;source;code;super;hyper;capsLock;numLock;baseCode;repeated;_defaultPrevented=!1;_propagationStopped=!1;constructor(key){this.name=key.name,this.ctrl=key.ctrl,this.meta=key.meta,this.shift=key.shift,this.option=key.option,this.sequence=key.sequence,this.number=key.number,this.raw=key.raw,this.eventType=key.eventType,this.source=key.source,this.code=key.code,this.super=key.super,this.hyper=key.hyper,this.capsLock=key.capsLock,this.numLock=key.numLock,this.baseCode=key.baseCode,this.repeated=key.repeated}get defaultPrevented(){return this._defaultPrevented}get propagationStopped(){return this._propagationStopped}preventDefault(){this._defaultPrevented=!0}stopPropagation(){this._propagationStopped=!0}}class PasteEvent{type="paste";bytes;metadata;_defaultPrevented=!1;_propagationStopped=!1;constructor(bytes,metadata){this.bytes=bytes,this.metadata=metadata}get defaultPrevented(){return this._defaultPrevented}get propagationStopped(){return this._propagationStopped}preventDefault(){this._defaultPrevented=!0}stopPropagation(){this._propagationStopped=!0}}class KeyHandler extends EventEmitter{processParsedKey(parsedKey){try{switch(parsedKey.eventType){case"press":this.emit("keypress",new KeyEvent(parsedKey));break;case"release":this.emit("keyrelease",new KeyEvent(parsedKey));break;default:this.emit("keypress",new KeyEvent(parsedKey));break}}catch(error){return console.error("[KeyHandler] Error processing parsed key:",error),!0}return!0}processPaste(bytes,metadata){try{this.emit("paste",new PasteEvent(bytes,metadata))}catch(error){console.error("[KeyHandler] Error processing paste:",error)}}}class InternalKeyHandler extends KeyHandler{renderableHandlers=new Map;emit(event,...args){return this.emitWithPriority(event,...args)}emitWithPriority(event,...args){let hasGlobalListeners=!1,globalListeners=this.listeners(event);if(globalListeners.length>0){hasGlobalListeners=!0;for(let listener of globalListeners){try{listener(...args)}catch(error){console.error(`[KeyHandler] Error in global ${event} handler:`,error)}if(event==="keypress"||event==="keyrelease"||event==="paste"){if(args[0].propagationStopped)return hasGlobalListeners}}}let renderableSet=this.renderableHandlers.get(event),renderableHandlers=renderableSet&&renderableSet.size>0?[...renderableSet]:[],hasRenderableListeners=!1;if(renderableSet&&renderableSet.size>0){if(hasRenderableListeners=!0,event==="keypress"||event==="keyrelease"||event==="paste"){let keyEvent=args[0];if(keyEvent.defaultPrevented)return hasGlobalListeners||hasRenderableListeners;if(keyEvent.propagationStopped)return hasGlobalListeners||hasRenderableListeners}for(let handler of renderableHandlers){try{handler(...args)}catch(error){console.error(`[KeyHandler] Error in renderable ${event} handler:`,error)}if(event==="keypress"||event==="keyrelease"||event==="paste"){if(args[0].propagationStopped)return hasGlobalListeners||hasRenderableListeners}}}return hasGlobalListeners||hasRenderableListeners}onInternal(event,handler){if(!this.renderableHandlers.has(event))this.renderableHandlers.set(event,new Set);this.renderableHandlers.get(event).add(handler)}offInternal(event,handler){let handlers=this.renderableHandlers.get(event);if(handlers)handlers.delete(handler)}}var block_default={name:"block",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:[" "," "," "," "," "," "],letterspace_size:1,chars:{A:[" <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2> ","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],B:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],C:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],D:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],E:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],F:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A\u2550\u255D </c2>"],G:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],H:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],I:["<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D</c2>"],J:["<c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588 \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u255D </c2>"],K:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],L:["<c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],M:["<c1>\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551\u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551 \u255A\u2550\u255D</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],N:["<c1>\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551 \u255A</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D</c2>"],O:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],P:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A\u2550\u255D </c2>"],Q:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2584\u2584 \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550</c2><c1>\u2580\u2580</c1><c2>\u2550\u255D </c2>"],R:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],S:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],T:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c2> \u255A\u2550\u255D </c2>"],U:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],V:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c2> \u255A\u2550\u2550\u2550\u255D </c2>"],W:["<c1>\u2588\u2588</c1><c2>\u2557 </c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D </c2>"],X:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],Y:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c2> \u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c2> \u255A\u2550\u255D </c2>"],Z:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"0":[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"1":[" <c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2> \u255A\u2550\u255D</c2>"],"2":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>"," <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"3":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>"," <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"4":["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2> \u255A\u2550\u255D</c2>"],"5":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"6":[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"7":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c2> \u255A\u2550\u255D </c2>"],"8":[" <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u255D </c2>"],"9":[" <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2> \u255A\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u255D </c2>"],"!":["<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>"],"?":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1> \u2584\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2580\u2580</c1><c2>\u2550\u2550\u255D </c2>","<c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c2> \u255A\u2550\u255D </c2>"],".":[" "," "," "," ","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>"],"+":[" ","<c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2> \u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550\u255D</c2>","<c2> \u255A\u2550\u255D </c2>"," "],"-":[" "," ","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u255D</c2>"," "," "],_:[" "," "," "," ","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"=":[" ","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D</c2>"," "],"@":[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u255D\u255A\u2550\u2550\u2550\u255D </c2>"],"#":[" <c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u255D \u255A\u2550\u255D </c2>"],$:["<c1>\u2584\u2584\u2588\u2588\u2588\u2584\u2584</c1><c2>\xB7</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550</c2><c1>\u2580\u2580\u2580</c1><c2>\u2550\u2550\u255D</c2>"],"%":["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],"&":["<c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"(":[" <c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2551 ","<c1>\u2588\u2588</c1><c2>\u2551 ","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2> \u255A\u2550\u255D</c2>"],")":["<c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u255D </c2>"],"/":["<c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c2>\u255A\u2550\u255D </c2>"],":":[" ","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>"," "],";":[" "," ","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>","<c1>\u2584\u2588</c1><c2>\u2557</c2>","<c1>\u2580</c1><c2>\u2550\u255D</c2>"],",":[" "," "," "," ","<c1>\u2584\u2588</c1><c2>\u2557</c2>","<c1>\u2580</c1><c2>\u2550\u255D</c2>"],"'":["<c1>\u2588</c1><c2>\u2557</c2> ","<c2>\u255A\u255D</c2> "," "," "," "," "],'"':["<c1>\u2588</c1><c2>\u2557</c2><c1>\u2588</c1><c2>\u2557</c2> ","<c2>\u255A\u255D\u255A\u255D</c2> "," "," "," "," "]," ":[" "," "," "," "," "," "]}},shade_default={name:"shade",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:8,buffer:["","","","","","","",""],letterspace:["<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>"],letterspace_size:1,chars:{A:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],B:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],C:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],D:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],E:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],F:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],G:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2> <c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],H:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],I:["<c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591</c2>"],J:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],K:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],L:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],M:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],N:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588</c1><c2>\u2591</c2><c1>\u2588</c1>","<c1>\u2588 \u2588\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2> <c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],O:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],P:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],Q:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588\u2588</c1>","<c2>\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],R:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],S:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588</c1> "," <c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2> <c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],T:["<c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591</c2>"],U:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],V:["<c2>\u2591\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1> ","<c2>\u2591</c2> <c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591</c2>"],W:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],X:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],Y:["<c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591</c2>"],Z:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"0":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u258C\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2> <c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"1":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588</c1><c2>\u2591\u2591</c2>"," <c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"2":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2590\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"3":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588\u2588</c1>","<c2>\u2591\u2591</c2> <c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"4":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c2>\u2591\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],"5":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"6":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"7":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c1>\u2588</c1> <c2>\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"8":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"9":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588\u2588</c1>","<c2>\u2591</c2> <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"!":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"?":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2590\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],".":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"+":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c2>\u2591</c2> <c1>\u2588</c1> ","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"-":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],_:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," "],"=":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"@":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u258C\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1> "," <c1>\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"#":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u258C\u2590</c1> ","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u258C\u2590</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],$:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u258C</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1> "," <c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u258C\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>"],"%":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1> "," <c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1> <c2>\u2591</c2> "," <c2>\u2591\u2591\u2591</c2>"],"&":["<c2>\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1> ","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c2> </c2> ","<c2>\u2591\u2591\u2591\u2591\u2591</c2>"],"(":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>"," <c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2> <c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591 \u2591</c2>"],")":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2> <c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591</c2> <c1>\u2588</c1>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>"],"/":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c1>\u2588</c1> <c2>\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>"],":":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],";":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>"],",":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>"],"'":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],'"':["<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>"]," ":["<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>"]}},slick_default={name:"slick",version:"0.1.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:["<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>"],letterspace_size:1,chars:{A:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>"],B:["<c1>\u256D\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u256F\u2570\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],C:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],D:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u256E\u256D\u256E\u2503</c1>","<c2>\u2571</c2><c1>\u2503\u2503\u2503\u2503</c1>","<c2>\u2571</c2><c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u256D\u256F\u2570\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],E:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],F:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2570\u256F</c1><c2>\u2571\u2571\u2571</c2>"],G:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>","<c1>\u2503\u2503\u256D\u2501\u256E</c1>","<c1>\u2503\u2570\u253B\u2501\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],H:["<c1>\u256D\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>"],I:["<c1>\u256D\u2501\u2501\u256E</c1>","<c1>\u2570\u252B\u2523\u256F</c1>","<c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u256D\u252B\u2523\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],J:["<c2>\u2571\u2571</c2><c1>\u256D\u256E</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u256D\u256E\u2503\u2503</c1>","<c1>\u2503\u2570\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],K:["<c1>\u256D\u256E\u256D\u2501\u256E</c1>","<c1>\u2503\u2503\u2503\u256D\u256F</c1>","<c1>\u2503\u2570\u256F\u256F</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503\u2503\u2570\u256E</c1>","<c1>\u2570\u256F\u2570\u2501\u256F</c1>"],L:["<c1>\u256D\u256E</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],M:["<c1>\u256D\u2501\u256E\u256D\u2501\u256E</c1>","<c1>\u2503\u2503\u2570\u256F\u2503\u2503</c1>","<c1>\u2503\u256D\u256E\u256D\u256E\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2570\u256F\u2570\u256F\u2570\u256F</c1>"],N:["<c1>\u256D\u2501\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503\u2570\u256E\u2503\u2503</c1>","<c1>\u2503\u256D\u256E\u2570\u256F\u2503</c1>","<c1>\u2503\u2503\u2570\u256E\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503\u2503</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u2570\u2501\u256F</c1>"],O:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],P:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2570\u256F</c1><c2>\u2571\u2571\u2571</c2>"],Q:["<c1>\u256D\u2501\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u2501\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u2501\u256F\u2503\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u2501\u256F</c1>"],R:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u256E\u256D\u256F</c1>","<c1>\u2503\u2503\u2503\u2570\u256E</c1>","<c1>\u2570\u256F\u2570\u2501\u256F</c1>"],S:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],T:["<c1>\u256D\u2501\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u256E\u256D\u256E\u2503</c1>","<c1>\u2570\u256F\u2503\u2503\u2570\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],U:["<c1>\u256D\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],V:["<c1>\u256D\u256E</c1><c2>\u2571\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u256E\u256D\u256F\u2503</c1>","<c1>\u2570\u256E\u2503\u2503\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2503\u2570\u256F\u2503</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2570\u256E\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],W:["<c1>\u256D\u256E\u256D\u256E\u256D\u256E</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2570\u256F\u2570\u256F\u2503</c1>","<c1>\u2570\u256E\u256D\u256E\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256F\u2570\u256F</c1><c2>\u2571</c2>"],X:["<c1>\u256D\u2501\u256E\u256D\u2501\u256E</c1>","<c1>\u2570\u256E\u2570\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256E\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256F\u2570\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u256D\u256E\u2570\u256E</c1>","<c1>\u2570\u2501\u256F\u2570\u2501\u256F</c1>"],Y:["<c1>\u256D\u256E</c1><c2>\u2571\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u256E\u256D\u256F\u2503</c1>","<c1>\u2570\u256E\u2570\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256E\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],Z:["<c1>\u256D\u2501\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2501\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2501\u2570\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u2501\u256F</c1>"],"0":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"1":["<c2>\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2503</c1><c2>\u2571</c2>","<c1>\u2570\u256E\u2503</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2570\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],"2":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c1>\u256D\u2501\u256F\u256D\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"3":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c1>\u256D\u256E\u2570\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"4":["<c1>\u256D\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c2>\u2571\u2571\u2571</c2><c1>\u2503\u2503</c1>","<c2>\u2571\u2571\u2571</c2><c1>\u2570\u256F</c1>"],"5":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u256D\u2501\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"6":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"7":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571</c2>"],"8":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"9":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u256D\u2501\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"!":["<c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1>","<c1>\u2570\u256F</c1>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>"],"?":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571</c2>"],".":["<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>"],"+":["<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2570\u256E</c1>","<c1>\u2570\u256E\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571</c2>"],"-":["<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c1>\u256D\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>","<c2>\u2571\u2571\u2571\u2571</c2>"],_:["<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c1>\u256D\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],"=":["<c2>\u2571\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571\u2571</c2>","<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>","<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"@":["<c1>\u256D\u2501\u2501\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u2501\u2501\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503\u256D\u2501\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503\u2570\u256F\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u2501\u2501\u256F\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u2501\u2501\u256F</c1>"],"#":["<c2>\u2571</c2><c1>\u256D\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u256D\u256E\u2570\u256E</c1>","<c1>\u2570\u256E\u2503\u2503\u256D\u256F</c1>","<c1>\u256D\u256F\u2503\u2503\u2570\u256E</c1>","<c1>\u2570\u256E\u2570\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u2501\u2501\u256F</c1><c2>\u2571</c2>"],$:["<c2>\u2571\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u2501\u256F\u2570\u256E</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u2570\u256E\u256D\u2501\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],"%":["<c1>\u256D\u256E</c1><c2>\u2571\u2571</c2><c1>\u256D\u2501\u256E</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571\u2571</c2>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2570\u2501\u256F</c1><c2>\u2571\u2571</c2><c1>\u2570\u256F</c1>"],"&":["<c2>\u2571</c2><c1>\u256D\u2501\u2501\u256E</c1>","<c2>\u2571</c2><c1>\u2503\u256D\u2501\u256F</c1>","<c1>\u256D\u256F\u2570\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u256F\u2503\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"(":["<c2>\u2571\u2571</c2><c1>\u256D\u2501\u256E</c1>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c1>\u2570\u256E\u2570\u256E</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2570\u256E\u2570\u256E</c1>","<c2>\u2571\u2571</c2><c1>\u2570\u2501\u256F</c1>"],")":["<c1>\u256D\u2501\u256E</c1><c2>\u2571\u2571</c2>","<c1>\u2570\u256E\u2570\u256E</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2570\u256E\u2570\u256E</c1>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c1>\u2570\u2501\u256F</c1><c2>\u2571\u2571</c2>"],"/":["<c2>\u2571\u2571\u2571\u2571</c2><c1>\u256D\u2501\u256E</c1>","<c2>\u2571\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571\u2571</c2>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2570\u2501\u256F</c1><c2>\u2571\u2571\u2571\u2571</c2>"],":":["<c2>\u2571\u2571</c2>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>","<c2>\u2571\u2571</c2>"],";":["<c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1>","<c1>\u2570\u256F</c1>","<c1>\u256D\u256E</c1>","<c1>\u2570\u252B</c1>","<c2>\u2571</c2><c1>\u256F</c1>"],",":["<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c1>\u256D\u256E</c1>","<c1>\u2570\u252B</c1>","<c2>\u2571</c2><c1>\u256F</c1>"],"'":["<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>"],'"':["<c1>\u256D\u256E\u256D\u256E</c1>","<c1>\u2570\u256F\u2570\u256F</c1>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>"]," ":["<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>"]}},tiny_default={name:"tiny",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:1,lines:2,buffer:["",""],letterspace:[" "," "],letterspace_size:1,chars:{A:["\u2584\u2580\u2588","\u2588\u2580\u2588"],B:["\u2588\u2584\u2584","\u2588\u2584\u2588"],C:["\u2588\u2580\u2580","\u2588\u2584\u2584"],D:["\u2588\u2580\u2584","\u2588\u2584\u2580"],E:["\u2588\u2580\u2580","\u2588\u2588\u2584"],F:["\u2588\u2580\u2580","\u2588\u2580 "],G:["\u2588\u2580\u2580","\u2588\u2584\u2588"],H:["\u2588 \u2588","\u2588\u2580\u2588"],I:["\u2588","\u2588"],J:[" \u2588","\u2588\u2584\u2588"],K:["\u2588\u2584\u2580","\u2588 \u2588"],L:["\u2588 ","\u2588\u2584\u2584"],M:["\u2588\u2580\u2584\u2580\u2588","\u2588 \u2580 \u2588"],N:["\u2588\u2584 \u2588","\u2588 \u2580\u2588"],O:["\u2588\u2580\u2588","\u2588\u2584\u2588"],P:["\u2588\u2580\u2588","\u2588\u2580\u2580"],Q:["\u2588\u2580\u2588","\u2580\u2580\u2588"],R:["\u2588\u2580\u2588","\u2588\u2580\u2584"],S:["\u2588\u2580\u2580","\u2584\u2584\u2588"],T:["\u2580\u2588\u2580"," \u2588 "],U:["\u2588 \u2588","\u2588\u2584\u2588"],V:["\u2588 \u2588","\u2580\u2584\u2580"],W:["\u2588 \u2588 \u2588","\u2580\u2584\u2580\u2584\u2580"],X:["\u2580\u2584\u2580","\u2588 \u2588"],Y:["\u2588\u2584\u2588"," \u2588 "],Z:["\u2580\u2588","\u2588\u2584"],"0":["\u259E\u2588\u259A","\u259A\u2588\u259E"],"1":["\u2584\u2588"," \u2588"],"2":["\u2580\u2588","\u2588\u2584"],"3":["\u2580\u2580\u2588","\u2584\u2588\u2588"],"4":["\u2588 \u2588","\u2580\u2580\u2588"],"5":["\u2588\u2580","\u2584\u2588"],"6":["\u2588\u2584\u2584","\u2588\u2584\u2588"],"7":["\u2580\u2580\u2588"," \u2588"],"8":["\u2588\u2588\u2588","\u2588\u2584\u2588"],"9":["\u2588\u2580\u2588","\u2580\u2580\u2588"],"!":["\u2588","\u2584"],"?":["\u2580\u2588"," \u2584"],".":[" ","\u2584"],"+":["\u2584\u2588\u2584"," \u2580 "],"-":["\u2584\u2584"," "],_:[" ","\u2584\u2584"],"=":["\u2580\u2580","\u2580\u2580"],"@":["\u259B\u2588\u259C","\u2599\u259F\u2583"],"#":["\u259F\u2584\u2599","\u259C\u2580\u259B"],$:["\u2596\u2588\u2597","\u2598\u2588\u259D"],"%":["\u2580 \u2584\u2580","\u2584\u2580 \u2584"],"&":["\u2584\u2584\u2588","\u2588\u2584\u2588"],"(":["\u2584\u2580","\u2580\u2584"],")":["\u2580\u2584","\u2584\u2580"],"/":[" \u2584\u2580","\u2584\u2580 "],":":["\u2580","\u2584"],";":[" ","\u2584\u2580"],",":[" ","\u2588"],"'":["\u2580"," "],'"':["\u259B \u259C"," "]," ":[" "," "]}},huge_default={name:"huge",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:11,buffer:["","","","","","","","","","",""],letterspace:[" "," "," "," "," "," "," "," "," "," "," "],letterspace_size:1,chars:{A:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],B:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],C:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],D:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],E:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],F:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],G:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],H:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],I:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],J:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],K:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],L:[" <c1>\u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],M:[" <c1>\u2584\u2584 \u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2580 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],N:[" <c1>\u2584\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580\u2580</c1> "],O:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],P:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],Q:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],R:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],S:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],T:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],U:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],V:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],W:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580 \u2580\u2580</c1> "],X:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],Y:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],Z:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"0":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"1":[" <c1>\u2584\u2584\u2584\u2584</c1> "," <c1>\u2584\u2588</c1><c2>\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580 \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"2":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"3":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"4":[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580</c1> "],"5":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"6":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"7":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],"8":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"9":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"!":[" <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "],"?":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> "," <c1>\u2584\u2588</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u2588\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580 \u2584\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2588</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u2588</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580</c1> "," <c1>\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580</c1> "],".":[" "," "," "," "," "," "," "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "],"+":[" "," "," <c1>\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580</c1> "," "," "],"-":[" "," "," "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "," "," "," "],_:[" "," "," "," "," "," "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "],"=":[" "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "," "],"@":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584\u2584\u2584\u2584 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2588</c1><c2>\u2591\u2591\u2591\u2591</c2><c1>\u2588 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2591</c2><c1>\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2588</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2584\u2584\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"#":[" <c1>\u2584 \u2584</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580 \u2580</c1> "],$:[" <c1>\u2584</c1> "," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2580</c1> "],"%":[" <c1>\u2584</c1> "," <c1>\u2584 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2580</c1> "," <c1>\u2580</c1> "],"&":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580 \u2580</c1> "],"(":[" <c1>\u2584\u2584\u2584\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u2588\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u2588\u2584\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "],")":[" <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "],"/":[" <c1>\u2584</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],":":[" "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," "," "],";":[" "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u258C</c1> "," <c1>\u2580</c1> "," "],",":[" "," "," "," "," "," "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u258C</c1> "," <c1>\u2580</c1> "],"'":[" <c1>\u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>"," <c1>\u2580</c1> "," "," "," "," "," "," "," "],'"':[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>"," <c1>\u2580 \u2580</c1> "," "," "," "," "," "," "," "]," ":[" "," "," "," "," "," "," "," "," "," "," "]}},grid_default={name:"grid",version:"0.1.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:["<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>"],letterspace_size:1,chars:{A:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],B:["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2503\u2517\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],C:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u251B</c1>","<c1>\u2503\u2517\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],D:["<c2>\u254B\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u250F\u2501\u251B\u2503</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],E:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u2503\u2501\u252B</c1>","<c1>\u2503\u2503\u2501\u252B</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],F:["<c2>\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],G:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2513\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>"],H:["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2503\u2517\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],I:["<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c1>\u250F\u2513</c1>","<c1>\u2503\u2503</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>"],J:["<c2>\u254B</c2><c1>\u250F\u2513</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1>","<c2>\u254B</c2><c1>\u250F\u2513</c1>","<c2>\u254B</c2><c1>\u2503\u2503</c1>","<c1>\u250F\u251B\u2503</c1>","<c1>\u2517\u2501\u251B</c1>"],K:["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2503\u2503\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u251B</c1>","<c1>\u2503\u250F\u2513\u2513</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],L:["<c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2517\u2513</c1>","<c1>\u2517\u2501\u251B</c1>","<c2>\u254B\u254B\u254B</c2>"],M:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2517\u253B\u253B\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],N:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2513</c1><c2>\u254B</c2>","<c1>\u2503\u250F\u2513\u2513</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],O:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],P:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2503\u250F\u2501\u251B</c1>","<c1>\u2517\u251B</c1><c2>\u254B\u254B</c2>"],Q:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2513\u2503</c1>","<c2>\u254B\u254B</c2><c1>\u2517\u251B</c1>"],R:["<c2>\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2513</c1>","<c1>\u2503\u250F\u251B</c1>","<c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B</c2>"],S:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u2501\u2501\u252B</c1>","<c1>\u2523\u2501\u2501\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],T:["<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2503\u2517\u2513</c1>","<c2>\u254B</c2><c1>\u2517\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],U:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],V:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],W:["<c2>\u254B\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u2517\u251B\u2503</c1>","<c1>\u2517\u2513\u250F\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B\u254B\u254B</c2>"],X:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2517\u254B\u254B\u251B</c1>","<c1>\u250F\u254B\u254B\u2513</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],Y:["<c2>\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513</c1><c2>\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2513\u250F\u251B</c1>","<c1>\u2517\u2501\u2501\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B\u254B</c2>"],Z:["<c2>\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2523\u2501\u2501\u2503\u2503</c1>","<c1>\u2503\u2503\u2501\u2501\u252B</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B\u254B</c2>"],"0":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"1":["<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2503</c1><c2>\u254B</c2>","<c1>\u2517\u2513\u2503</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>"],"2":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c1>\u250F\u2501\u251B\u250F\u251B</c1>","<c1>\u2503\u2517\u2501\u253B\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"3":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c1>\u250F\u2513\u2517\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"4":["<c1>\u250F\u2513</c1><c2>\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u2503\u2503</c1><c2>\u254B</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2513\u2503</c1>","<c2>\u254B\u254B\u254B</c2><c1>\u2503\u2503</c1>","<c2>\u254B\u254B\u254B</c2><c1>\u2517\u251B</c1>"],"5":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2501\u251B</c1>","<c1>\u2503\u2517\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u2513\u2503</c1>","<c1>\u250F\u2501\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"6":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2501\u251B</c1>","<c1>\u2503\u2517\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"7":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c2>\u254B\u254B</c2><c1>\u2503\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c2>\u254B\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>"],"8":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"9":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2513\u2503</c1>","<c1>\u250F\u2501\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"!":["<c1>\u250F\u2513</c1>","<c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1>","<c1>\u2517\u251B</c1>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>"],"?":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c2>\u254B\u254B</c2><c1>\u2503\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c2>\u254B\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>"],".":["<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>"],"+":["<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],"-":["<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],_:["<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>"],"=":["<c2>\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>","<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B\u254B</c2>"],"@":["<c1>\u250F\u2501\u2501\u2501\u2501\u2513</c1><c2>\u254B</c2>","<c1>\u2503\u250F\u2501\u2501\u2513\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2503\u250F\u2501\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2503\u2517\u251B\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2517\u2501\u2501\u251B\u2517\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u2501\u2501\u251B</c1>"],"#":["<c2>\u254B</c2><c1>\u250F\u2501\u2501\u2501\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u250F\u2501\u2513\u2517\u2513</c1>","<c1>\u2517\u2513\u2503\u2503\u2503\u250F\u251B</c1>","<c1>\u250F\u251B\u2503\u2503\u2503\u2517\u2513</c1>","<c1>\u2517\u2513\u2517\u2501\u251B\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u2501\u2501\u2501\u251B</c1><c2>\u254B</c2>"],$:["<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2503\u2501\u2501\u252B</c1>","<c1>\u2523\u2501\u2501\u2503</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>"],"%":["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c1>\u2517\u251B</c1><c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B\u254B</c2>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u2517\u2501\u251B</c1><c2>\u254B\u254B</c2><c1>\u2517\u251B</c1>"],"&":["<c2>\u254B\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c2>\u254B\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u250F\u2501\u251B\u2517\u2513</c1>","<c1>\u2503\u250F\u2513\u250F\u251B</c1>","<c1>\u2503\u2517\u251B\u2503</c1><c2>\u254B</c2>","<c1>\u2517\u2501\u2501\u251B</c1><c2>\u254B</c2>"],"(":["<c2>\u254B\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c1>\u2517\u2513\u2517\u2513</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2517\u2513\u2517\u2513</c1>","<c2>\u254B\u254B</c2><c1>\u2517\u2501\u251B</c1>"],")":["<c1>\u250F\u2501\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2517\u2513\u2517\u2513</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2517\u2513\u2517\u2513</c1>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c1>\u2517\u2501\u251B</c1><c2>\u254B\u254B</c2>"],"/":["<c2>\u254B\u254B\u254B\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c2>\u254B\u254B\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B\u254B</c2>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B\u254B\u254B</c2>","<c1>\u2517\u2501\u251B</c1><c2>\u254B\u254B\u254B\u254B</c2>"],":":["<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>"],";":["<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u252B</c1>"],",":["<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u252B</c1>"],"'":["<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>"],'"':["<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"]," ":["<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>"]}},pallet_default={name:"pallet",version:"0.1.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:["<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>"],letterspace_size:1,chars:{A:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>"],B:["<c1>\u2554\u2550\u2550\u2557</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u255A\u255D\u255A\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],C:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],D:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2557\u2554\u2557\u2551</c1>","<c2>\u2500</c2><c1>\u2551\u2551\u2551\u2551</c1>","<c2>\u2500</c2><c1>\u2551\u2551\u2551\u2551</c1>","<c1>\u2554\u255D\u255A\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],E:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],F:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u255A\u255D</c1><c2>\u2500\u2500\u2500</c2>"],G:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>","<c1>\u2551\u2551\u2554\u2550\u2557</c1>","<c1>\u2551\u255A\u2569\u2550\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],H:["<c1>\u2554\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>"],I:["<c1>\u2554\u2550\u2550\u2557</c1>","<c1>\u255A\u2563\u2560\u255D</c1>","<c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2554\u2563\u2560\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],J:["<c2>\u2500\u2500</c2><c1>\u2554\u2557</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2554\u2557\u2551\u2551</c1>","<c1>\u2551\u255A\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],K:["<c1>\u2554\u2557\u2554\u2550\u2557</c1>","<c1>\u2551\u2551\u2551\u2554\u255D</c1>","<c1>\u2551\u255A\u255D\u255D</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551\u2551\u255A\u2557</c1>","<c1>\u255A\u255D\u255A\u2550\u255D</c1>"],L:["<c1>\u2554\u2557</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],M:["<c1>\u2554\u2550\u2557\u2554\u2550\u2557</c1>","<c1>\u2551\u2551\u255A\u255D\u2551\u2551</c1>","<c1>\u2551\u2554\u2557\u2554\u2557\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u255A\u255D\u255A\u255D\u255A\u255D</c1>"],N:["<c1>\u2554\u2550\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551\u255A\u2557\u2551\u2551</c1>","<c1>\u2551\u2554\u2557\u255A\u255D\u2551</c1>","<c1>\u2551\u2551\u255A\u2557\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551\u2551</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u255A\u2550\u255D</c1>"],O:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],P:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u255A\u255D</c1><c2>\u2500\u2500\u2500</c2>"],Q:["<c1>\u2554\u2550\u2550\u2550\u2557</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2550\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u255A\u2550\u255D\u2560\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u2550\u255D</c1>"],R:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2557\u2554\u255D</c1>","<c1>\u2551\u2551\u2551\u255A\u2557</c1>","<c1>\u255A\u255D\u255A\u2550\u255D</c1>"],S:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],T:["<c1>\u2554\u2550\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2557\u2554\u2557\u2551</c1>","<c1>\u255A\u255D\u2551\u2551\u255A\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500\u2500</c2>"],U:["<c1>\u2554\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],V:["<c1>\u2554\u2557</c1><c2>\u2500\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2557\u2554\u255D\u2551</c1>","<c1>\u255A\u2557\u2551\u2551\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u2551\u255A\u255D\u2551</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u255A\u2557\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500\u2500</c2>"],W:["<c1>\u2554\u2557\u2554\u2557\u2554\u2557</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u255A\u255D\u255A\u255D\u2551</c1>","<c1>\u255A\u2557\u2554\u2557\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u255D\u255A\u255D</c1><c2>\u2500</c2>"],X:["<c1>\u2554\u2550\u2557\u2554\u2550\u2557</c1>","<c1>\u255A\u2557\u255A\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u2557\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u255D\u255A\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2554\u2557\u255A\u2557</c1>","<c1>\u255A\u2550\u255D\u255A\u2550\u255D</c1>"],Y:["<c1>\u2554\u2557</c1><c2>\u2500\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2557\u2554\u255D\u2551</c1>","<c1>\u255A\u2557\u255A\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u2557\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500\u2500</c2>"],Z:["<c1>\u2554\u2550\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2550\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2550\u255A\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u2550\u255D</c1>"],"0":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"1":["<c2>\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2551</c1><c2>\u2500</c2>","<c1>\u255A\u2557\u2551</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u255A\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],"2":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c1>\u2554\u2550\u255D\u2554\u255D</c1>","<c1>\u2551\u2551\u255A\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"3":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c1>\u2554\u2557\u255A\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"4":["<c1>\u2554\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c2>\u2500\u2500\u2500</c2><c1>\u2551\u2551</c1>","<c2>\u2500\u2500\u2500</c2><c1>\u255A\u255D</c1>"],"5":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2554\u2550\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"6":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"7":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500</c2>"],"8":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"9":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2554\u2550\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"!":["<c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>"],"?":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500</c2>"],".":["<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>"],"+":["<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u255A\u2557</c1>","<c1>\u255A\u2557\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500</c2>"],"-":["<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c1>\u2554\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>"],_:["<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c1>\u2554\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],"=":["<c2>\u2500\u2500\u2500\u2500\u2500</c2>","<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>","<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>","<c2>\u2500\u2500\u2500\u2500\u2500</c2>"],"@":["<c1>\u2554\u2550\u2550\u2550\u2550\u2557</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2550\u2550\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551\u2554\u2550\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551\u255A\u255D\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u255A\u2550\u2550\u255D\u2560\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u2550\u2550\u255D</c1>"],"#":["<c2>\u2500</c2><c1>\u2554\u2569\u2569\u2569\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2554\u2550\u2557\u255A\u2557</c1>","<c1>\u255A\u2557\u2560\u2550\u2563\u2554\u255D</c1>","<c1>\u2554\u255D\u2560\u2550\u2563\u255A\u2557</c1>","<c1>\u255A\u2557\u255A\u2550\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u2566\u2566\u2566\u255D</c1><c2>\u2500</c2>"],$:["<c1>\u2554\u255D\u2569\u255A\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2557\u2566\u2554\u255D</c1>"],"%":["<c1>\u2554\u2557</c1><c2>\u2500\u2500</c2><c1>\u2554\u2550\u2557</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500\u2500</c2>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u255A\u2550\u255D</c1><c2>\u2500\u2500</c2><c1>\u255A\u255D</c1>"],"&":["<c2>\u2500\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2554\u2550\u255D\u255A\u2557</c1>","<c1>\u2551\u2554\u2557\u2554\u255D</c1>","<c1>\u2551\u255A\u255D\u2551</c1><c2>\u2500</c2>","<c1>\u255A\u2550\u2550\u255D</c1><c2>\u2500</c2>"],"(":["<c2>\u2500\u2500</c2><c1>\u2554\u2550\u2557</c1>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c1>\u255A\u2557\u255A\u2557</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u255A\u2557\u255A\u2557</c1>","<c2>\u2500\u2500</c2><c1>\u255A\u2550\u255D</c1>"],")":["<c1>\u2554\u2550\u2557</c1><c2>\u2500\u2500</c2>","<c1>\u255A\u2557\u255A\u2557</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u255A\u2557\u255A\u2557</c1>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c1>\u255A\u2550\u255D</c1><c2>\u2500\u2500</c2>"],"/":["<c2>\u2500\u2500\u2500\u2500</c2><c1>\u2554\u2550\u2557</c1>","<c2>\u2500\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500\u2500</c2>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u255A\u2550\u255D</c1><c2>\u2500\u2500\u2500\u2500</c2>"],":":["<c2>\u2500\u2500</c2>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>","<c2>\u2500\u2500</c2>"],";":["<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c1>\u2554\u2557</c1>","<c1>\u255A\u2563</c1>","<c2>\u2500</c2><c1>\u255D</c1>"],",":["<c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1>","<c1>\u2554\u2557</c1>","<c1>\u255A\u2563</c1>","<c2>\u2500</c2><c1>\u255D</c1>"],"'":["<c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>"],'"':["<c1>\u2554\u2557\u2554\u2557</c1>","<c1>\u2551\u2551\u2551\u2551</c1>","<c1>\u255A\u255D\u255A\u255D</c1>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>"]," ":["<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>"]}},fonts={tiny:tiny_default,block:block_default,shade:shade_default,slick:slick_default,huge:huge_default,grid:grid_default,pallet:pallet_default},parsedFonts={};function parseColorTags(text){let segments=[],currentIndex=0,colorTagRegex=/<c(\d+)>(.*?)<\/c\d+>/g,lastIndex=0,match;while((match=colorTagRegex.exec(text))!==null){if(match.index>lastIndex){let plainText=text.slice(lastIndex,match.index);if(plainText)segments.push({text:plainText,colorIndex:0})}let colorIndex=parseInt(match[1])-1,taggedText=match[2];segments.push({text:taggedText,colorIndex:Math.max(0,colorIndex)}),lastIndex=match.index+match[0].length}if(lastIndex<text.length){let remainingText=text.slice(lastIndex);if(remainingText)segments.push({text:remainingText,colorIndex:0})}return segments}function getParsedFont(fontKey){if(!parsedFonts[fontKey]){let fontDef=fonts[fontKey],parsedChars={};for(let[char,lines]of Object.entries(fontDef.chars))parsedChars[char]=lines.map((line)=>parseColorTags(line));parsedFonts[fontKey]={...fontDef,colors:fontDef.colors||1,chars:parsedChars}}return parsedFonts[fontKey]}function measureText({text,font="tiny"}){let fontDef=getParsedFont(font);if(!fontDef)return console.warn(`Font '${font}' not found`),{width:0,height:0};let currentX=0;for(let i=0;i<text.length;i++){let char=text[i].toUpperCase(),charDef=fontDef.chars[char];if(!charDef){let spaceChar=fontDef.chars[" "];if(spaceChar&&spaceChar[0]){let spaceWidth=0;for(let segment of spaceChar[0])spaceWidth+=segment.text.length;currentX+=spaceWidth}else currentX+=1;continue}let charWidth=0;if(charDef[0])for(let segment of charDef[0])charWidth+=segment.text.length;if(currentX+=charWidth,i<text.length-1)currentX+=fontDef.letterspace_size}return{width:currentX,height:fontDef.lines}}function getCharacterPositions(text,font="tiny"){let fontDef=getParsedFont(font);if(!fontDef)return[0];let positions=[0],currentX=0;for(let i=0;i<text.length;i++){let char=text[i].toUpperCase(),charDef=fontDef.chars[char],charWidth=0;if(!charDef){let spaceChar=fontDef.chars[" "];if(spaceChar&&spaceChar[0])for(let segment of spaceChar[0])charWidth+=segment.text.length;else charWidth=1}else if(charDef[0])for(let segment of charDef[0])charWidth+=segment.text.length;if(currentX+=charWidth,i<text.length-1)currentX+=fontDef.letterspace_size;positions.push(currentX)}return positions}function coordinateToCharacterIndex(x,text,font="tiny"){let positions=getCharacterPositions(text,font);if(x<0)return 0;for(let i=0;i<positions.length-1;i++){let currentPos=positions[i],nextPos=positions[i+1];if(x>=currentPos&&x<nextPos){let charMidpoint=currentPos+(nextPos-currentPos)/2;return x<charMidpoint?i:i+1}}if(positions.length>0&&x>=positions[positions.length-1])return text.length;return 0}function renderFontToFrameBuffer(buffer,{text,x=0,y=0,color=[RGBA.fromInts(255,255,255,255)],backgroundColor=RGBA.fromInts(0,0,0,255),font="tiny"}){let{width,height}=buffer,fontDef=getParsedFont(font);if(!fontDef)return console.warn(`Font '${font}' not found`),{width:0,height:0};let colors=Array.isArray(color)?color:[color];if(y<0||y+fontDef.lines>height)return{width:0,height:fontDef.lines};let currentX=x,startX=x;for(let i=0;i<text.length;i++){let char=text[i].toUpperCase(),charDef=fontDef.chars[char];if(!charDef){let spaceChar=fontDef.chars[" "];if(spaceChar&&spaceChar[0]){let spaceWidth=0;for(let segment of spaceChar[0])spaceWidth+=segment.text.length;currentX+=spaceWidth}else currentX+=1;continue}let charWidth=0;if(charDef[0])for(let segment of charDef[0])charWidth+=segment.text.length;if(currentX>=width)break;if(currentX+charWidth<0){currentX+=charWidth+fontDef.letterspace_size;continue}for(let lineIdx=0;lineIdx<fontDef.lines&&lineIdx<charDef.length;lineIdx++){let segments=charDef[lineIdx],renderY=y+lineIdx;if(renderY>=0&&renderY<height){let segmentX=currentX;for(let segment of segments){let segmentColor=colors[segment.colorIndex]||colors[0];for(let charIdx=0;charIdx<segment.text.length;charIdx++){let renderX=segmentX+charIdx;if(renderX>=0&&renderX<width){let fontChar=segment.text[charIdx];if(fontChar!==" ")buffer.setCellWithAlphaBlending(renderX,renderY,fontChar,parseColor(segmentColor),parseColor(backgroundColor))}}segmentX+=segment.text.length}}}if(currentX+=charWidth,i<text.length-1)currentX+=fontDef.letterspace_size}return{width:currentX-startX,height:fontDef.lines}}var TextAttributes={NONE:0,BOLD:1,DIM:2,ITALIC:4,UNDERLINE:8,BLINK:16,INVERSE:32,HIDDEN:64,STRIKETHROUGH:128};var DebugOverlayCorner;((DebugOverlayCorner2)=>{DebugOverlayCorner2[DebugOverlayCorner2.topLeft=0]="topLeft",DebugOverlayCorner2[DebugOverlayCorner2.topRight=1]="topRight",DebugOverlayCorner2[DebugOverlayCorner2.bottomLeft=2]="bottomLeft",DebugOverlayCorner2[DebugOverlayCorner2.bottomRight=3]="bottomRight"})(DebugOverlayCorner||={});var TargetChannel;((TargetChannel2)=>{TargetChannel2[TargetChannel2.FG=1]="FG",TargetChannel2[TargetChannel2.BG=2]="BG",TargetChannel2[TargetChannel2.Both=3]="Both"})(TargetChannel||={});function createTextAttributes({bold=!1,italic=!1,underline=!1,dim=!1,blink=!1,inverse=!1,hidden=!1,strikethrough=!1}={}){let attributes=TextAttributes.NONE;if(bold)attributes|=TextAttributes.BOLD;if(italic)attributes|=TextAttributes.ITALIC;if(underline)attributes|=TextAttributes.UNDERLINE;if(dim)attributes|=TextAttributes.DIM;if(blink)attributes|=TextAttributes.BLINK;if(inverse)attributes|=TextAttributes.INVERSE;if(hidden)attributes|=TextAttributes.HIDDEN;if(strikethrough)attributes|=TextAttributes.STRIKETHROUGH;return attributes}var BrandedStyledText=Symbol.for("@opentui/core/StyledText");function isStyledText(obj){return obj&&obj[BrandedStyledText]}class StyledText{[BrandedStyledText]=!0;chunks;constructor(chunks){this.chunks=chunks}}function stringToStyledText(content){return new StyledText([{__isChunk:!0,text:content}])}function applyStyle(input,style){if(typeof input==="object"&&"__isChunk"in input){let existingChunk=input,fg=style.fg?parseColor(style.fg):existingChunk.fg,bg=style.bg?parseColor(style.bg):existingChunk.bg,newAttrs=createTextAttributes(style),mergedAttrs=existingChunk.attributes?existingChunk.attributes|newAttrs:newAttrs;return{__isChunk:!0,text:existingChunk.text,fg,bg,attributes:mergedAttrs,link:existingChunk.link}}else{let plainTextStr=String(input),fg=style.fg?parseColor(style.fg):void 0,bg=style.bg?parseColor(style.bg):void 0,attributes=createTextAttributes(style);return{__isChunk:!0,text:plainTextStr,fg,bg,attributes}}}var fg=(color)=>(input)=>applyStyle(input,{fg:color});class SystemClock{now(){if(!globalThis.performance||typeof globalThis.performance.now!=="function")throw Error("SystemClock requires globalThis.performance.now()");return globalThis.performance.now()}setTimeout(fn,delayMs){return globalThis.setTimeout(fn,delayMs)}clearTimeout(handle){globalThis.clearTimeout(handle)}setInterval(fn,delayMs){return globalThis.setInterval(fn,delayMs)}clearInterval(handle){globalThis.clearInterval(handle)}}var kittyKeyMap={27:"escape",9:"tab",13:"return",127:"backspace",57344:"escape",57345:"return",57346:"tab",57347:"backspace",57348:"insert",57349:"delete",57350:"left",57351:"right",57352:"up",57353:"down",57354:"pageup",57355:"pagedown",57356:"home",57357:"end",57358:"capslock",57359:"scrolllock",57360:"numlock",57361:"printscreen",57362:"pause",57363:"menu",57364:"f1",57365:"f2",57366:"f3",57367:"f4",57368:"f5",57369:"f6",57370:"f7",57371:"f8",57372:"f9",57373:"f10",57374:"f11",57375:"f12",57376:"f13",57377:"f14",57378:"f15",57379:"f16",57380:"f17",57381:"f18",57382:"f19",57383:"f20",57384:"f21",57385:"f22",57386:"f23",57387:"f24",57388:"f25",57389:"f26",57390:"f27",57391:"f28",57392:"f29",57393:"f30",57394:"f31",57395:"f32",57396:"f33",57397:"f34",57398:"f35",57399:"kp0",57400:"kp1",57401:"kp2",57402:"kp3",57403:"kp4",57404:"kp5",57405:"kp6",57406:"kp7",57407:"kp8",57408:"kp9",57409:"kpdecimal",57410:"kpdivide",57411:"kpmultiply",57412:"kpminus",57413:"kpplus",57414:"kpenter",57415:"kpequal",57416:"kpseparator",57417:"kpleft",57418:"kpright",57419:"kpup",57420:"kpdown",57421:"kppageup",57422:"kppagedown",57423:"kphome",57424:"kpend",57425:"kpinsert",57426:"kpdelete",57427:"clear",57428:"mediaplay",57429:"mediapause",57430:"mediaplaypause",57431:"mediareverse",57432:"mediastop",57433:"mediafastforward",57434:"mediarewind",57435:"medianext",57436:"mediaprev",57437:"mediarecord",57438:"volumedown",57439:"volumeup",57440:"mute",57441:"leftshift",57442:"leftctrl",57443:"leftalt",57444:"leftsuper",57445:"lefthyper",57446:"leftmeta",57447:"rightshift",57448:"rightctrl",57449:"rightalt",57450:"rightsuper",57451:"righthyper",57452:"rightmeta",57453:"iso_level3_shift",57454:"iso_level5_shift"},kittyNamedSingleStrokeKeys=[...new Set(Object.values(kittyKeyMap))],printableKeypadText={kp0:"0",kp1:"1",kp2:"2",kp3:"3",kp4:"4",kp5:"5",kp6:"6",kp7:"7",kp8:"8",kp9:"9",kpdecimal:".",kpdivide:"/",kpmultiply:"*",kpminus:"-",kpplus:"+",kpequal:"=",kpseparator:","};function getPrintableKittyKeyText(key){return printableKeypadText[key.name]}function fromKittyMods(mod){return{shift:!!(mod&1),alt:!!(mod&2),ctrl:!!(mod&4),super:!!(mod&8),hyper:!!(mod&16),meta:!!(mod&32),capsLock:!!(mod&64),numLock:!!(mod&128)}}var functionalKeyMap={A:"up",B:"down",C:"right",D:"left",H:"home",F:"end",E:"clear",P:"f1",Q:"f2",S:"f4"},tildeKeyMap={"1":"home","2":"insert","3":"delete","4":"end","5":"pageup","6":"pagedown","7":"home","8":"end","11":"f1","12":"f2","13":"f3","14":"f4","15":"f5","17":"f6","18":"f7","19":"f8","20":"f9","21":"f10","23":"f11","24":"f12","29":"menu","57427":"clear"};function parseKittySpecialKey(sequence){let match=/^\x1b\[(\d+);(\d+):(\d+)([A-Z~])$/.exec(sequence);if(!match)return null;let keyNumOrOne=match[1],modifierStr=match[2],eventTypeStr=match[3],terminator=match[4],keyName;if(terminator==="~")keyName=tildeKeyMap[keyNumOrOne];else{if(keyNumOrOne!=="1")return null;keyName=functionalKeyMap[terminator]}if(!keyName)return null;let key={name:keyName,ctrl:!1,meta:!1,shift:!1,option:!1,number:!1,sequence,raw:sequence,eventType:"press",source:"kitty",super:!1,hyper:!1,capsLock:!1,numLock:!1};if(modifierStr){let modifierMask=parseInt(modifierStr,10);if(!isNaN(modifierMask)&&modifierMask>1){let mods=fromKittyMods(modifierMask-1);key.shift=mods.shift,key.ctrl=mods.ctrl,key.meta=mods.alt||mods.meta,key.option=mods.alt,key.super=mods.super,key.hyper=mods.hyper,key.capsLock=mods.capsLock,key.numLock=mods.numLock}}if(eventTypeStr==="1"||!eventTypeStr)key.eventType="press";else if(eventTypeStr==="2")key.eventType="press",key.repeated=!0;else if(eventTypeStr==="3")key.eventType="release";return key}function parseKittyKeyboard(sequence){let specialResult=parseKittySpecialKey(sequence);if(specialResult)return specialResult;let match=/^\x1b\[([^\x1b]+)u$/.exec(sequence);if(!match)return null;let fields=match[1].split(";");if(fields.length<1)return null;let key={name:"",ctrl:!1,meta:!1,shift:!1,option:!1,number:!1,sequence,raw:sequence,eventType:"press",source:"kitty",super:!1,hyper:!1,capsLock:!1,numLock:!1},text="",field1=fields[0]?.split(":")||[],codepointStr=field1[0];if(!codepointStr)return null;let codepoint=parseInt(codepointStr,10);if(isNaN(codepoint))return null;let shiftedCodepoint,baseCodepoint;if(field1[1]){let shifted=parseInt(field1[1],10);if(!isNaN(shifted)&&shifted>0&&shifted<=1114111)shiftedCodepoint=shifted}if(field1[2]){let base=parseInt(field1[2],10);if(!isNaN(base)&&base>0&&base<=1114111)baseCodepoint=base}let knownKey=kittyKeyMap[codepoint];if(knownKey)key.name=knownKey,key.code=`[${codepoint}u`;else if(codepoint===0)key.name="";else if(codepoint>0&&codepoint<=1114111){let char=String.fromCodePoint(codepoint);if(key.name=char===" "?"space":char,baseCodepoint)key.baseCode=baseCodepoint}else return null;if(fields[1]){let field2=fields[1].split(":"),modifierStr=field2[0],eventTypeStr=field2[1];if(modifierStr){let modifierMask=parseInt(modifierStr,10);if(!isNaN(modifierMask)&&modifierMask>1){let mods=fromKittyMods(modifierMask-1);key.shift=mods.shift,key.ctrl=mods.ctrl,key.meta=mods.alt||mods.meta,key.option=mods.alt,key.super=mods.super,key.hyper=mods.hyper,key.capsLock=mods.capsLock,key.numLock=mods.numLock}}if(eventTypeStr==="1"||!eventTypeStr)key.eventType="press";else if(eventTypeStr==="2")key.eventType="press",key.repeated=!0;else if(eventTypeStr==="3")key.eventType="release";else key.eventType="press"}if(fields[2]){let codepoints=fields[2].split(":");for(let cpStr of codepoints){let cp=parseInt(cpStr,10);if(!isNaN(cp)&&cp>0&&cp<=1114111)text+=String.fromCodePoint(cp)}}if(text==="")text=getPrintableKittyKeyText(key)??"";if(text===""){if(key.name.length>0&&!kittyKeyMap[codepoint])if(codepoint===32)text=" ";else if(key.shift&&shiftedCodepoint)text=String.fromCodePoint(shiftedCodepoint);else if(key.shift&&key.name.length===1)text=key.name.toLocaleUpperCase();else text=key.name}if(text){if(codepoint===0)key.name=text;key.sequence=text}if(codepoint===0&&text==="")return null;return key}var metaKeyCodeRe=/^(?:\x1b)([a-zA-Z0-9])$/,fnKeyRe=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,keyName={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[29~":"menu","[57427~":"clear","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home","[P":"f1","[Q":"f2","[S":"f4",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home",OM:"return",Oj:"*",Ok:"+",Ol:",",Om:"-",On:".",Oo:"/",Op:"0",Oq:"1",Or:"2",Os:"3",Ot:"4",Ou:"5",Ov:"6",Ow:"7",Ox:"8",Oy:"9",OX:"=","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear",f:"right",b:"left",p:"up",n:"down","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"},nonAlphanumericKeys=[...Object.values(keyName),"backspace"],terminalNamedSingleStrokeKeys=[...new Set(["return","linefeed","tab","escape","space",...nonAlphanumericKeys,...kittyNamedSingleStrokeKeys])],isShiftKey=(code)=>{return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(code)},isCtrlKey=(code)=>{return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(code)},getCtrlKeyName=(charCode)=>{if(charCode===0)return"space";if(charCode>=1&&charCode<=26)return String.fromCharCode(charCode+97-1);if(charCode>=28&&charCode<=31)return String.fromCharCode(charCode+64);return},ss3NumpadPrintable={Op:"0",Oq:"1",Or:"2",Os:"3",Ot:"4",Ou:"5",Ov:"6",Ow:"7",Ox:"8",Oy:"9",Oj:"*",Ok:"+",Ol:",",Om:"-",On:".",Oo:"/",OX:"="},modifyOtherKeysRe=/^\x1b\[27;(\d+);(\d+)~$/,parseKeypress=(s="",options={})=>{let parts;if(Buffer2.isBuffer(s))if(s[0]>127&&s[1]===void 0)s[0]-=128,s="\x1B"+String(s);else s=String(s);else if(s!==void 0&&typeof s!=="string")s=String(s);else if(!s)s="";if(/^\x1b\[<\d+;\d+;\d+[Mm]$/.test(s))return null;if(/^\[<\d+;\d+;\d+[Mm]$/.test(s))return null;if(/^\x1b\[<[\d;]*$/.test(s))return null;if(/^\[<[\d;]*$/.test(s))return null;if(s.startsWith("\x1B[M")&&s.length>=6)return null;if(/^\x1b\[\d+;\d+;\d+t$/.test(s))return null;if(/^\x1b\[\d+;\d+R$/.test(s))return null;if(/^\x1b\[\?[\d;]+c$/.test(s))return null;if(/^\x1b\[\?[\d;]+\$y$/.test(s))return null;if(s==="\x1B[I"||s==="\x1B[O")return null;if(/^\x1b\][\d;].*(\x1b\\|\x07)$/.test(s))return null;if(s==="\x1B[200~"||s==="\x1B[201~")return null;let key={name:"",ctrl:!1,meta:!1,shift:!1,option:!1,number:!1,sequence:s,raw:s,eventType:"press",source:"raw"};key.sequence=key.sequence||s||key.name;let ctrlKeyName=s.length===1?getCtrlKeyName(s.charCodeAt(0)):void 0,metaCtrlKeyName=s.length===2&&s[0]==="\x1B"?getCtrlKeyName(s.charCodeAt(1)):void 0;if(options.useKittyKeyboard){let kittyResult=parseKittyKeyboard(s);if(kittyResult)return kittyResult}let modifyOtherKeysMatch=modifyOtherKeysRe.exec(s);if(modifyOtherKeysMatch){let modifier=parseInt(modifyOtherKeysMatch[1],10)-1,charCode=parseInt(modifyOtherKeysMatch[2],10);if(key.ctrl=!!(modifier&4),key.meta=!!(modifier&2),key.shift=!!(modifier&1),key.option=!!(modifier&2),key.super=!!(modifier&8),key.hyper=!!(modifier&16),charCode===13)key.name="return";else if(charCode===27)key.name="escape";else if(charCode===9)key.name="tab";else if(charCode===32)key.name="space";else if(charCode===127||charCode===8)key.name="backspace";else{let char=String.fromCharCode(charCode);if(key.name=char,key.sequence=char,charCode>=48&&charCode<=57)key.number=!0}return key}if(s==="\r"||s==="\x1B\r")key.name="return",key.meta=s.length===2;else if(s===`
3510
+ ORDER BY m.id DESC LIMIT ?`).all(scan),out=[];for(let r of rows2)for(let a of extract2(r))if(out.push(a),out.length>=limit)return out;return out}var WRITE,READ,MEMORY_TOOLS,trunc4=(s,n=80)=>{let t2=String(s??"").replace(/\s+/g," ").trim();return t2.length>n?t2.slice(0,n-1)+"\u2026":t2},stripPrefix=(name)=>name.replace(/^(mem0|honcho|hindsight|viking|retaindb|supermemory|brv|fact)_/,""),describe=(name,args)=>{if(name==="memory"){let action=String(args.action??""),target=String(args.target??""),body=action==="remove"?args.old_text:args.content??args.old_text;return{verb:action,summary:`${target}: ${trunc4(body)}`}}let verb=stripPrefix(name);for(let k2 of["conclusion","content","query","text","fact","question","note","path"])if(k2 in args)return{verb,summary:trunc4(args[k2])};let first=Object.values(args).find((v2)=>typeof v2==="string");return{verb,summary:trunc4(first??"")}},extract2=(r)=>{let calls;try{calls=JSON.parse(r.tool_calls)}catch{return[]}if(!Array.isArray(calls))return[];let out=[];for(let c of calls){let name=c.function?.name;if(!name||!(name in MEMORY_TOOLS))continue;let args={};try{args=JSON.parse(c.function?.arguments??"{}")}catch{}let{verb,summary}=describe(name,args);out.push({ts:r.ts,provider:MEMORY_TOOLS[name],tool:name,op:name in WRITE?"write":"read",verb,summary,sessionId:r.session_id,sessionTitle:r.title??r.session_id})}return out};var init_memory_activity=__esm(()=>{init_sessions_db();WRITE={memory:"builtin",mem0_conclude:"mem0",honcho_conclude:"honcho",hindsight_retain:"hindsight",hindsight_reflect:"hindsight",fact_store:"holographic",fact_feedback:"holographic",viking_remember:"openviking",viking_add_resource:"openviking",retaindb_remember:"retaindb",retaindb_forget:"retaindb",supermemory_store:"supermemory",supermemory_forget:"supermemory",brv_curate:"byterover"},READ={mem0_search:"mem0",mem0_profile:"mem0",honcho_search:"honcho",honcho_profile:"honcho",honcho_reasoning:"honcho",honcho_context:"honcho",hindsight_recall:"hindsight",viking_search:"openviking",viking_read:"openviking",viking_browse:"openviking",retaindb_search:"retaindb",retaindb_profile:"retaindb",retaindb_context:"retaindb",supermemory_search:"supermemory",supermemory_profile:"supermemory",brv_query:"byterover",brv_status:"byterover"},MEMORY_TOOLS={...WRITE,...READ}});var exports_fns={};__export(exports_fns,{FNS:()=>FNS});var FNS;var init_fns=__esm(()=>{init_sessions_db();init_hermes_analytics();init_memory_activity();FNS={roots:exports_sessions_db.roots,children:exports_sessions_db.children,lineage:exports_sessions_db.lineage,peek:exports_sessions_db.peek,search:exports_sessions_db.search,systemPrompt:exports_sessions_db.systemPrompt,goalState:exports_sessions_db.goalState,analytics,memoryActivity:readMemoryActivity}});var SCHEMA,SCHEMA_KEYS,APPROVAL_MODES;var init_schema=__esm(()=>{SCHEMA={"agent.api_max_retries":{type:"int",default:3,doc:"Max app-level retry attempts for API errors (connection drops, provider timeouts, 5xx, etc.) before the agent surfaces the failure. The OpenAI SDK already does its own low-level retries (max_retries=2 default) for transient network errors; this is the Hermes-level retry loop that wraps the whole call. Lower this to 1 if you use fallback providers and want fast failover on flaky primaries; raise it if you prefer to tolerate longer provider hiccups on a single provider.",group:"agent",effect:"session"},"agent.build_wait_timeout":{type:"int",default:600,doc:"Upper bound (seconds) a submitted prompt waits for the deferred agent build (MCP discovery, model metadata, skills scan) before failing with a visible error (#63078). The gateway's wait is patient \u2014 the prompt is delivered the moment the build completes and a progress notice is emitted past 30s \u2014 so this cap only fires on a genuinely hung build. Raise it for deployments with many slow or unreachable MCP servers.",group:"agent",effect:"session"},"agent.clarify_timeout":{type:"int",default:3600,doc:`Maximum time (seconds) the gateway will block an agent waiting for a clarify-tool response from the user. Hit this and the agent unblocks with "[user did not respond within Xm]" so it can adapt rather than pinning the running-agent guard forever. CLI clarify blocks indefinitely (input() is synchronous) and ignores this. Default 3600 (1h): real users step away (meetings, AFK) and the old 600s default evicted the entry mid-think, so a later button tap landed on a dead entry (#32762). Tradeoff: a higher value holds the gateway's running-agent guard longer for a genuinely abandoned prompt \u2014 lower it if a single session must free up the guard sooner.`,group:"agent",effect:"session"},"agent.coding_context":{type:"str",default:"auto",doc:`Coding posture \u2014 on interactive coding surfaces (CLI, TUI, desktop app, ACP) in a code workspace, Hermes adds a coding operating brief + a live git/workspace snapshot to the system prompt. See agent/coding_context.py. "auto" (default) \u2014 prompt-only posture when the surface is interactive AND cwd is a code workspace. Toolsets are never touched; messaging platforms unaffected. "focus" \u2014 auto + collapse the toolset to the lean coding set (+ enabled MCP servers) + demote non-coding skill categories to names-only in the prompt's skill index. Explicit opt-in. "on" \u2014 force the prompt posture everywhere. "off" \u2014 disable entirely.`,group:"agent",effect:"session"},"agent.coding_instructions":{type:"str",default:"",doc:`Standing operator instructions for the coding posture. A string (or list of strings) appended to the coding brief as an extra stable system block \u2014 pin project-wide workflow rules here instead of editing the shipped brief, e.g. "For UI work, don't run tsc/lint until I approve. Clean the diff before you commit and push." Cache-safe: takes effect next session. Empty by default.`,group:"agent",effect:"session"},"agent.disabled_toolsets":{type:"list",default:[],doc:"",group:"agent",effect:"session"},"agent.environment_hint":{type:"str",default:"",doc:"Embedder-supplied environment description appended to the system prompt's environment-hints block. Lets a host that wraps Hermes (sandbox runner, managed platform) explain the runtime environment \u2014 proxy, credential handling, mount layout \u2014 without editing the identity slot (SOUL.md). Empty by default. The HERMES_ENVIRONMENT_HINT env var overrides this (build-time/container mechanism).",group:"agent",effect:"session"},"agent.environment_probe":{type:"bool",default:!0,doc:"Local-environment toolchain probe \u2014 surfaces Python/pip/uv/PEP-668 state in the system prompt when something non-default is detected (e.g. python3 has no pip module, pip\u2192python version mismatch, PEP 668 enforcement without uv). Costs zero tokens when the env is clean (probe emits nothing). Skipped for remote terminal backends (docker/modal/ssh \u2014 they have their own probe). Set False to disable entirely.",group:"agent",effect:"session"},"agent.gateway_auto_continue_freshness":{type:"int",default:3600,doc:`Freshness window for the gateway auto-continue note (seconds). After a gateway crash/restart/SIGTERM mid-run, the next user message gets a "[System note: your previous turn was interrupted \u2014 process the unfinished tool result(s) first]" prepended so the model picks up where it left off. That's the right behaviour while the interruption is fresh, but stale markers (transcript last touched hours or days ago) can revive an unrelated old task when the user's next message starts new work. This window is the max age of the last persisted transcript row for which we still inject the continue note. Default 3600s comfortably covers a long turn (gateway_timeout default is 1800s) plus runtime slack. Set to 0 to disable the gate and restore pre-fix behaviour (always inject).`,group:"agent",effect:"session"},"agent.gateway_notify_interval":{type:"int",default:180,doc:`Periodic "still working" notification interval (seconds). Sends a status message every N seconds so the user knows the agent hasn't died during long tasks. 0 = disable notifications. Lower values mean faster feedback on slow tasks but more chat noise; 180s is a compromise that catches spinning weak-model runs (60+ tool iterations with tiny output) before users assume the bot is dead and /restart.`,group:"agent",effect:"session"},"agent.gateway_startup_restore_drain_timeout":{type:"int",default:30,doc:`Max seconds the gateway waits for boot auto-resume turns to finish before it releases the startup-restore inbound gate. While startup restore is in progress the gateway QUEUES every inbound message instead of replying, so no channel gets an answer until this gate opens. Without a bound, one pathologically long resumed turn holds the gate shut and every channel's inbound piles up unanswered for as long as that turn runs. On timeout the gate releases and the slow resume turn keeps running in the background; duplicate-agent protection is unaffected because the resume slot is claimed synchronously before the gate runs. Set to 0 to disable the bound (historical "wait forever" behaviour).`,group:"agent",effect:"session"},"agent.gateway_timeout":{type:"int",default:1800,doc:"Inactivity timeout for gateway agent execution (seconds). The agent can run indefinitely as long as it's actively calling tools or receiving API responses. Only fires when the agent has been completely idle for this duration. 0 = unlimited.",group:"agent",effect:"session"},"agent.gateway_timeout_warning":{type:"int",default:900,doc:"Staged inactivity warning: send a warning to the user at this threshold before escalating to a full timeout. The warning fires once per run and does not interrupt the agent. 0 = disable warning.",group:"agent",effect:"session"},"agent.image_input_mode":{type:"str",default:"auto",doc:`How user-attached images are presented to the main model on each turn. "auto" \u2014 attach natively when the active model reports supports_vision=True AND the user hasn't explicitly configured auxiliary.vision.provider. Otherwise fall back to text (vision_analyze pre-analysis). "native" \u2014 always attach natively; non-vision models will either error at the provider or get a last-chance text fallback (see run_agent._prepare_messages_for_api). "text" \u2014 always pre-analyze with vision_analyze and prepend the description as text; the main model never sees pixels. Affects gateway platforms, the TUI, and CLI /attach. vision_analyze remains available as a tool regardless of this setting \u2014 the routing only controls how inbound user images are presented.`,group:"agent",effect:"session"},"agent.intent_ack_continuation":{type:"str",default:"auto",doc:`Intent-ack continuation: when the model opens a turn by narrating an action it will take ("I'll go check the logs...") but emits no tool call, intercept the turn-end, inject a "continue now, execute the tools" nudge, and loop instead of ending the turn (capped at 2 nudges per turn). This is the corrective sibling of tool_use_enforcement (the preventive prompt-side guard). Values: "auto" (default \u2014 fires only on the codex_responses api_mode, the historical behavior), true (all api_modes \u2014 fixes the Gemini/Claude "stops after stating intent" case), false (never), or a list of model-name substrings to match.`,group:"agent",effect:"session"},"agent.local_stream_stale_timeout":{type:"int",default:900,doc:"Stale-stream ceiling for local providers (Ollama, oMLX, llama-cpp) in seconds. When the base stale timeout is at its default (180s) and a local endpoint is detected, this finite ceiling replaces the former infinite disable so a wedged local server eventually trips the detector instead of hanging forever. The env var ``HERMES_LOCAL_STREAM_STALE_TIMEOUT`` overrides for escape-hatch use.",group:"agent",effect:"session"},"agent.max_turns":{type:"int",default:500,doc:"",group:"agent",effect:"session"},"agent.max_verify_nudges":{type:"int",default:3,doc:'Upper bound on consecutive `pre_verify` "continue" nudges in a single turn, so a user/plugin hook can never trap the loop.',group:"agent",effect:"session"},"agent.parallel_tool_call_guidance":{type:"bool",default:!0,doc:"Universal parallel-tool-call guidance \u2014 short prompt block applied to all models that tells the model to batch independent tool calls (reads, searches, web fetches, read-only commands) into one turn instead of one call per turn. The runtime already runs independent calls concurrently, so this just steers the model to produce the batch \u2014 cutting round-trips and the resent-context cost that compounds over a long conversation. Costs ~70 tokens in the cached system prompt. Set False to disable globally.",group:"agent",effect:"session"},"agent.reasoning_effort":{type:"str",default:"",doc:"Reasoning effort for the main agent: none | minimal | low | medium | high | xhigh.",group:"agent",effect:"live"},"agent.reasoning_overrides":{type:"dict",default:{},doc:"Per-model reasoning effort overrides (spelling-tolerant). Dict mapping model names (any reasonable spelling) to effort levels. Takes precedence over agent.reasoning_effort when the current model matches a key in this dict. Edit directly in config.yaml (no CLI support due to dots in keys).",group:"agent",effect:"session"},"agent.restart_drain_timeout":{type:"int",default:0,doc:`Graceful drain timeout for gateway stop/restart (seconds). The gateway stops accepting new work, waits for running agents to finish, then interrupts any remaining runs after the timeout. 0 = no drain, interrupt immediately (the default). Contract: if you restart the gateway, in-flight work stops. We do not hold the restart open for a grace window \u2014 a drain timeout large enough to "save" a long agent turn would have to outlast an unbounded task (some runs take days), which is impossible, and a drain timeout shorter than systemd's TimeoutStopSec invites a SIGKILL-mid-cleanup race that leaves a stale lock and crash-loops the service. 0 sidesteps both: interrupt now, clean up, exit fast. Set a positive value in config.yaml only if you explicitly want a grace window on /restart (and keep it well under TimeoutStopSec).`,group:"agent",effect:"session"},"agent.service_tier":{type:"str",default:"",doc:"",group:"agent",effect:"live"},"agent.system_prompt":{type:"str",default:"",doc:"System-prompt override applied by the active personality.",group:"agent",effect:"session"},"agent.task_completion_guidance":{type:"bool",default:!0,doc:'Universal "finish the job" guidance \u2014 short prompt block applied to all models that targets two cross-family failure modes: (1) stopping after a stub instead of finishing the artifact, (2) fabricating plausible-looking output when a real path is blocked. Costs ~80 tokens in the cached system prompt. Set False to disable globally.',group:"agent",effect:"session"},"agent.tool_use_enforcement":{type:"str",default:"auto",doc:'Tool-use enforcement: injects system prompt guidance that tells the model to actually call tools instead of describing intended actions. Values: "auto" (default \u2014 applies to gpt/codex models), true/false (force on/off for all models), or a list of model-name substrings to match (e.g. ["gpt", "codex", "gemini", "qwen"]).',group:"agent",effect:"session"},"agent.verify_guidance":{type:"bool",default:!0,doc:"When verify-on-stop finds edited code without fresh verification evidence, append guidance for creative UI work (avoid broad tsc/lint/test before visual approval) and clean-diff expectations. Set false to keep the evidence nudge terse.",group:"agent",effect:"session"},"agent.verify_on_stop":{type:"str",default:"auto",doc:'Verification closure: after the agent edits files in a code workspace, do not accept a final answer until fresh verification evidence exists or the agent explains why it cannot run checks. The loop is bounded and uses the passive verification ledger. Default is "auto" \u2014 surface-aware: on for interactive coding surfaces (CLI, TUI, desktop) and programmatic callers, off for conversational messaging surfaces (Telegram, Discord, etc.) where the verification narrative would reach a human as chat noise. Doc/markdown/skill-only edits never fire it. Set true to force on everywhere, or false to disable.',group:"agent",effect:"session"},"approvals.cron_mode":{type:"str",default:"deny",doc:"",group:"approvals",effect:"live"},"approvals.denial_breaker_threshold":{type:"int",default:3,doc:`Consecutive-denial circuit breaker for smart approvals: after this many guardian DENY verdicts in a row within one session, the deny message returned to the model escalates to a hard-stop instruction (report to the user / ask for manual run or /approve) instead of a plain "Do NOT retry". Any approval resets the count. 0 disables. Inspired by ChatGPT Work's auto-review circuit breaker.`,group:"approvals",effect:"live"},"approvals.deny":{type:"list",default:[],doc:'User-defined deny rules: fnmatch globs matched against terminal commands. A match blocks the command unconditionally \u2014 BEFORE the --yolo / /yolo / mode=off bypass \u2014 making this the user-editable counterpart to the code-shipped hardline blocklist. Patterns are case-insensitive and must be quoted in YAML when they start with * or contain {}/!/: sequences. Example: deny: - "git push --force*" - "*curl*|*sh*"',group:"approvals",effect:"live"},"approvals.destructive_slash_confirm":{type:"bool",default:!0,doc:'When true, destructive session slash commands (/clear, /new, /reset, /undo) ask the user to confirm before discarding conversation state. Three-option prompt (Approve Once / Always Approve / Cancel) routed through tools.slash_confirm \u2014 native yes/no buttons on Telegram, Discord, and Slack; text fallback elsewhere. Users click "Always Approve" to silence the prompt permanently; that flips this key to false. TUI has its own modal overlay (HERMES_TUI_NO_CONFIRM=1 to opt out there).',group:"approvals",effect:"live"},"approvals.mcp_reload_confirm":{type:"bool",default:!0,doc:'When true, /reload-mcp asks the user to confirm before rebuilding the MCP tool set for the active session. Reloading invalidates the provider prompt cache (tool schemas are baked into the system prompt), so the next message re-sends full input tokens \u2014 this can be expensive on long-context or high-reasoning models. Users click "Always Approve" to silence the prompt permanently; that flips this key to false.',group:"approvals",effect:"live"},"approvals.mode":{type:"str",default:"smart",doc:"",group:"approvals",effect:"live"},"approvals.smart_policy":{type:"str",default:"",doc:`Operator-customizable policy text for smart approvals. When non-empty, this is appended to the smart-approval guardian's SYSTEM prompt (trusted channel) as additional rules \u2014 e.g. "Always ESCALATE commands touching /etc" or "APPROVE docker compose restarts under ~/deploys". Inspired by ChatGPT Work's customizable auto-review guardian policy.`,group:"approvals",effect:"live"},"approvals.timeout":{type:"int",default:300,doc:"",group:"approvals",effect:"live"},"auxiliary.approval.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.model":{type:"str",default:"",doc:"fast/cheap model recommended (e.g. gemini-flash, haiku)",group:"auxiliary",effect:"session"},"auxiliary.approval.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.approval.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.approval.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.background_review.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.background_review.timeout":{type:"int",default:120,doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.compression.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.compression.timeout":{type:"int",default:120,doc:"seconds \u2014 compression summarises large contexts; increase for local models",group:"auxiliary",effect:"session"},"auxiliary.curator.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.curator.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.curator.timeout":{type:"int",default:600,doc:"",group:"auxiliary",effect:"session"},"auxiliary.goal_judge.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.goal_judge.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.goal_judge.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.goal_judge.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.goal_judge.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.goal_judge.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.goal_judge.timeout":{type:"int",default:60,doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.kanban_decomposer.timeout":{type:"int",default:180,doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.mcp.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.mcp.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.memory_query_rewrite.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.memory_query_rewrite.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.memory_query_rewrite.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.memory_query_rewrite.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.memory_query_rewrite.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.memory_query_rewrite.timeout":{type:"int",default:8,doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_aggregator.timeout":{type:"int",default:900,doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.moa_reference.timeout":{type:"int",default:900,doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.monitor.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.monitor.timeout":{type:"int",default:60,doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.profile_describer.timeout":{type:"int",default:60,doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.skills_hub.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.stream_only_base_urls":{type:"list",default:[],doc:'Endpoints that reject NON-streaming chat requests outright (e.g. Tencent Copilot returns HTTP 400 "Non-stream chat request is currently not supported"). Auxiliary calls to a matching endpoint are sent with stream=True and aggregated client-side. Entries are case-insensitive substrings matched against the endpoint URL; copilot.tencent.com is always treated as stream-only.',group:"auxiliary",effect:"session"},"auxiliary.title_generation.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.enabled":{type:"bool",default:!0,doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.language":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.title_generation.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.title_generation.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.transient_retries":{type:"int",default:2,doc:"Same-provider retries for a transient transport blip (connection reset / timeout / 5xx / 408) on ANY auxiliary call before falling back. Default 2 (\u2192 3 total attempts), clamped [0,6]. Matters most for pinned calls like MoA reference advisors, where provider fallback is not a meaningful recovery, so an unretried blip silently loses the call.",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.triage_specifier.timeout":{type:"int",default:120,doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.tts_audio_tags.timeout":{type:"int",default:30,doc:"",group:"auxiliary",effect:"session"},"auxiliary.vision.api_key":{type:"str",default:"",doc:"API key for base_url (falls back to OPENAI_API_KEY)",group:"auxiliary",effect:"session"},"auxiliary.vision.base_url":{type:"str",default:"",doc:"direct OpenAI-compatible endpoint (takes precedence over provider)",group:"auxiliary",effect:"session"},"auxiliary.vision.download_timeout":{type:"int",default:30,doc:"seconds \u2014 image HTTP download timeout; increase for slow connections",group:"auxiliary",effect:"session"},"auxiliary.vision.extra_body":{type:"dict",default:{},doc:"OpenAI-compatible provider-specific request fields",group:"auxiliary",effect:"session"},"auxiliary.vision.model":{type:"str",default:"",doc:'e.g. "google/gemini-2.5-flash", "gpt-4o"',group:"auxiliary",effect:"session"},"auxiliary.vision.provider":{type:"str",default:"auto",doc:"auto | openrouter | nous | codex | custom",group:"auxiliary",effect:"session"},"auxiliary.vision.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.vision.timeout":{type:"int",default:120,doc:"seconds \u2014 LLM API call timeout; vision payloads need generous timeout",group:"auxiliary",effect:"session"},"auxiliary.web_extract.api_key":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.base_url":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.extra_body":{type:"dict",default:{},doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.model":{type:"str",default:"",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.provider":{type:"str",default:"auto",doc:"",group:"auxiliary",effect:"session"},"auxiliary.web_extract.reasoning_effort":{type:"str",default:"",doc:"per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default)",group:"auxiliary",effect:"session"},"auxiliary.web_extract.timeout":{type:"int",default:360,doc:"seconds (6min) \u2014 per-attempt LLM summarization timeout; increase for slow local models",group:"auxiliary",effect:"session"},"bedrock.discovery.enabled":{type:"bool",default:!0,doc:"Auto-discover models via ListFoundationModels",group:"bedrock",effect:"live"},"bedrock.discovery.provider_filter":{type:"list",default:[],doc:'Only show models from these providers (e.g. ["anthropic", "amazon"])',group:"bedrock",effect:"live"},"bedrock.discovery.refresh_interval":{type:"int",default:3600,doc:"Cache discovery results for this many seconds",group:"bedrock",effect:"live"},"bedrock.guardrail.guardrail_identifier":{type:"str",default:"",doc:"Amazon Bedrock Guardrails \u2014 content filtering and safety policies. Create a guardrail in the Bedrock console, then set the ID and version here. See: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html",group:"bedrock",effect:"live"},"bedrock.guardrail.guardrail_version":{type:"str",default:"",doc:'e.g. "1" or "DRAFT"',group:"bedrock",effect:"live"},"bedrock.guardrail.stream_processing_mode":{type:"str",default:"async",doc:'"sync" or "async"',group:"bedrock",effect:"live"},"bedrock.guardrail.trace":{type:"str",default:"disabled",doc:'"enabled", "disabled", or "enabled_full"',group:"bedrock",effect:"live"},"bedrock.region":{type:"str",default:"",doc:"AWS region for Bedrock API calls (empty = AWS_REGION env var \u2192 us-east-1)",group:"bedrock",effect:"live"},"browser.allow_private_urls":{type:"bool",default:!1,doc:"Allow navigating to private/internal IPs (localhost, 192.168.x.x, etc.)",group:"browser",effect:"live"},"browser.allow_unsafe_evaluate":{type:"bool",default:!1,doc:"Legacy override: when true, browser_console(expression=...) bypasses the restrict_evaluate denylist entirely",group:"browser",effect:"live"},"browser.auto_local_for_private_urls":{type:"bool",default:!0,doc:"When a cloud provider is set, auto-spawn local Chromium for LAN/localhost URLs instead of sending them to the cloud",group:"browser",effect:"live"},"browser.camofox.adopt_existing_tab":{type:"bool",default:!1,doc:"Rehydrate tab_id from Camofox before creating a new tab.",group:"browser",effect:"live"},"browser.camofox.loopback_host_alias":{type:"str",default:"host.docker.internal",doc:"",group:"browser",effect:"live"},"browser.camofox.managed_persistence":{type:"bool",default:!1,doc:"When true, Hermes sends a stable profile-scoped userId to Camofox so the server maps it to a persistent Firefox profile automatically. When false (default), each session gets a random userId (ephemeral).",group:"browser",effect:"live"},"browser.camofox.rewrite_loopback_urls":{type:"bool",default:!1,doc:"Docker Camofox opens page URLs from inside the container. Enable this to rewrite loopback page URLs (localhost/127.0.0.1/::1) to a host alias while leaving CAMOFOX_URL itself unchanged.",group:"browser",effect:"live"},"browser.camofox.session_key":{type:"str",default:"",doc:"",group:"browser",effect:"live"},"browser.camofox.user_id":{type:"str",default:"",doc:"Optional externally managed Camofox identity. Useful when another app owns the visible browser and Hermes should operate in it.",group:"browser",effect:"live"},"browser.cdp_url":{type:"str",default:"",doc:"Optional persistent CDP endpoint for attaching to an existing Chromium/Chrome",group:"browser",effect:"live"},"browser.command_timeout":{type:"int",default:30,doc:"Timeout for browser commands in seconds (screenshot, navigate, etc.)",group:"browser",effect:"live"},"browser.dialog_policy":{type:"str",default:"must_respond",doc:"CDP supervisor \u2014 dialog + frame detection via a persistent WebSocket. Active only when a CDP-capable backend is attached (Browserbase or local Chrome via /browser connect). See website/docs/developer-guide/browser-supervisor.md.",group:"browser",effect:"live"},"browser.dialog_timeout_s":{type:"int",default:300,doc:"Safety auto-dismiss after N seconds under must_respond",group:"browser",effect:"live"},"browser.engine":{type:"str",default:"auto",doc:'Browser engine for local mode. Passed as ``--engine <value>`` to agent-browser v0.25.3+. "auto" \u2014 use Chrome (default, don\'t pass --engine at all) "lightpanda" \u2014 use Lightpanda (1.3-5.8x faster navigation, no screenshots) "chrome" \u2014 explicitly request Chrome Also settable via AGENT_BROWSER_ENGINE env var.',group:"browser",effect:"live"},"browser.headed":{type:"bool",default:!1,doc:"Local mode: launch Chromium with a visible window (also skips per-turn cleanup so the window persists between turns; idle reaper still applies)",group:"browser",effect:"live"},"browser.inactivity_timeout":{type:"int",default:120,doc:"",group:"browser",effect:"live"},"browser.record_sessions":{type:"bool",default:!1,doc:"Auto-record browser sessions as WebM videos",group:"browser",effect:"live"},"browser.restrict_evaluate":{type:"bool",default:!1,doc:"Opt-in denylist blocking sensitive JS primitives (cookies/storage/clipboard/network/form values) in browser_console(expression=...)",group:"browser",effect:"live"},"checkpoints.auto_prune":{type:"bool",default:!0,doc:'Auto-maintenance: hermes sweeps the checkpoint base at startup (at most once per ``min_interval_hours``) and: * deletes project entries whose last_touch is older than ``retention_days`` * GCs the single shared store to reclaim unreachable objects * enforces ``max_total_size_mb`` across remaining projects * deletes ``legacy-*`` archives older than ``retention_days`` NOTE: this automatic sweep never deletes "orphan" entries (workdir no longer found on disk). A missing workdir at startup is ambiguous \u2014 it can mean the project was deleted, or that an external volume / network share / VPN is simply not mounted yet \u2014 and this sweep runs unattended, so it must never guess. Orphan cleanup is only available via the explicit ``hermes checkpoints prune`` command (add ``--keep-orphans`` to skip it), where a human is looking at the output.',group:"checkpoints",effect:"live"},"checkpoints.enabled":{type:"bool",default:!1,doc:"",group:"checkpoints",effect:"live"},"checkpoints.max_file_size_mb":{type:"int",default:10,doc:"Skip any single file larger than this when staging a checkpoint. Prevents accidental snapshotting of datasets, model weights, and other large generated assets. 0 disables the filter.",group:"checkpoints",effect:"live"},"checkpoints.max_snapshots":{type:"int",default:20,doc:"Max checkpoints to keep per working directory. Pre-v2 this only limited the `/rollback` listing; v2 actually rewrites the ref and garbage-collects older commits.",group:"checkpoints",effect:"live"},"checkpoints.max_total_size_mb":{type:"int",default:500,doc:"Hard ceiling on total ``~/.hermes/checkpoints/`` size (MB). When exceeded, the oldest checkpoint per project is dropped in a round-robin pass until total size falls under the cap. 0 disables the size cap.",group:"checkpoints",effect:"live"},"checkpoints.min_interval_hours":{type:"int",default:24,doc:"",group:"checkpoints",effect:"live"},"checkpoints.retention_days":{type:"int",default:7,doc:"",group:"checkpoints",effect:"live"},"code_execution.mode":{type:"str",default:"project",doc:"Execution mode: project (default) \u2014 scripts run in the session's working directory with the active virtualenv/conda env's python, so project deps (pandas, torch, project packages) and relative paths resolve. strict \u2014 scripts run in an isolated temp directory with hermes-agent's own python (sys.executable). Maximum isolation and reproducibility; project deps and relative paths won't work. Env scrubbing (strips *_API_KEY, *_TOKEN, *_SECRET, ...) and the tool whitelist apply identically in both modes.",group:"code_execution",effect:"live"},command_allowlist:{type:"list",default:[],doc:'Permanently allowed dangerous command patterns (added via "always" approval)',group:"general",effect:"live"},"compression.abort_on_summary_failure":{type:"bool",default:!1,doc:`When True, auto-compression that fails to generate a summary (aux LLM errored / returned non-JSON / timed out) aborts entirely instead of dropping the middle window with a static "summary unavailable" placeholder. Messages are preserved unchanged and the session "freezes" at its current size until the user runs /compress (which bypasses the failure cooldown) or /new. Default False matches historical behavior; set to True if you'd rather pause than silently lose context turns when your aux model is flaky.`,group:"compression",effect:"live"},"compression.codex_app_server_auto":{type:"str",default:"native",doc:"Codex app-server (codex CLI runtime) thread compaction mode. The codex agent owns the real thread context, so Hermes' summarizer cannot shrink it (#36801). native = codex decides when to compact its own thread (default); hermes = Hermes' compression threshold triggers thread/compact/start; off = never auto-trigger (codex may still compact natively).",group:"compression",effect:"live"},"compression.codex_gpt55_autoraise":{type:"bool",default:!0,doc:"Historical key name kept for compatibility. When True, gpt-5.4 / gpt-5.5 / gpt-5.6 on the ChatGPT Codex OAuth route raise their compaction trigger to 85% (vs the global `threshold` above). Codex hard-caps these families at a 272K window, so the default 50% would compact at ~136K and waste half the usable context. Set to False to opt back down to the global threshold (e.g. 0.50) for those Codex sessions. Only this exact route is affected \u2014 gpt-5.4 / 5.5 / 5.6 on OpenAI's direct API, OpenRouter, and Copilot keep the global threshold regardless.",group:"compression",effect:"live"},"compression.codex_gpt55_autoraise_notice":{type:"bool",default:!0,doc:"Display the one-time Codex gpt-5.4/5.5/5.6 autoraise banner. Set False to keep the 85% threshold autoraise but suppress the user-facing notice in CLI/gateway output.",group:"compression",effect:"live"},"compression.enabled":{type:"bool",default:!0,doc:"",group:"compression",effect:"live"},"compression.hygiene_failure_cooldown_seconds":{type:"int",default:300,doc:"skip repeated failed hygiene attempts for this session",group:"compression",effect:"live"},"compression.hygiene_hard_message_limit":{type:"int",default:5000,doc:"gateway session-hygiene force-compress threshold by message count",group:"compression",effect:"live"},"compression.hygiene_timeout_seconds":{type:"int",default:30,doc:"max seconds gateway waits for pre-agent hygiene compression WITHOUT forward progress. The summary call streams, so this is an inactivity budget: a slow model still producing tokens keeps extending the wait; only a silent/hung call is cut off.",group:"compression",effect:"live"},"compression.hygiene_total_ceiling_seconds":{type:"int",default:600,doc:"absolute cap on the hygiene compression wait even while tokens are still moving \u2014 bounds a degenerate trickle stream. Clamped to >= hygiene_timeout_seconds.",group:"compression",effect:"live"},"compression.idle_compact_after_seconds":{type:"int",default:0,doc:"Opt-in idle compaction (0 = disabled). When > 0, a session that resumes after at least this many seconds of inactivity compacts its accumulated history up front, before the first reply \u2014 so a long-lived thread resumed hours later doesn't re-read its full stale context on every turn. Time-based; complements (does not replace) the size-based `threshold` above. Skipped when the context is already at/below the post-compression target (threshold \xD7 target_ratio) and it honors the same failure-cooldown / anti-thrash / per-session lock guards as every automatic compaction. Example: 1800 = compact after 30 min idle.",group:"compression",effect:"live"},"compression.in_place":{type:"bool",default:!0,doc:"When True, compaction rewrites the message list and rebuilds the system prompt WITHOUT rotating the session id \u2014 the conversation keeps one durable id for its whole life (no parent_session_id chain, no `name #N` renumbering). Eliminates the session-rotation bug cluster (#33618 /goal loss, #14238 lost response, #33907 orphans, #45117 search gaps, #42228 null cwd) \u2014 see #38763. Non-destructive: the live context is compacted (lossy for what the model reloads), but the pre-compaction turns are soft-archived under the same id (active=0, compacted=1) \u2014 still searchable via session_search and recoverable, not deleted. Default True since 2107b86024; set False to restore the legacy rotating-compaction path.",group:"compression",effect:"live"},"compression.max_attempts":{type:"int",default:3,doc:'compression retry rounds before a turn gives up with "max compression attempts reached". Raise (e.g. 6) for tool-schema-heavy sessions where 3 rounds cannot clear the request estimate. Validated >= 1, hard-capped at 10.',group:"compression",effect:"live"},"compression.min_tail_user_messages":{type:"int",default:1,doc:"REAL (actionable) user messages guaranteed to survive in the uncompressed tail. 1 = existing single last-user anchor (default, behavior- preserving); raise to e.g. 3 to keep the last 3 real user turns verbatim when bulky tool outputs fill the tail token budget.",group:"compression",effect:"live"},"compression.model_thresholds":{type:"dict",default:{},doc:'Per-model threshold overrides. Keys are substring-matched against the model name (longest match wins); values replace the global `threshold` for that model, e.g. model_thresholds: "glm-5.2": 0.40 "claude-sonnet": 0.35 The small-context floor (0.75 for <512K models) still applies on top of overrides (raise-only: an override above the floor wins; one below it is raised to the floor).',group:"compression",effect:"live"},"compression.proactive_prune_min_reclaim_tokens":{type:"int",default:4096,doc:"a proactive prune only commits when it reclaims at least this many tokens (measured on the pruned output). Keeps prompt-cache invalidation amortized: one big episodic break instead of a tiny break every tool iteration. 0 = commit any non-zero prune.",group:"compression",effect:"live"},"compression.proactive_prune_min_result_chars":{type:"int",default:8000,doc:"the prune's summarize pass only touches tool results larger than this (chars); clamped to >= 200 so a generated summary can't itself be re-summarized.",group:"compression",effect:"live"},"compression.proactive_prune_tokens":{type:"int",default:0,doc:"opt-in trigger (tokens) for the deterministic, no-LLM tool-result prune, run independently of `threshold` above. On large-window models `threshold` (\u224850% of the window) rarely fires, so old tool output otherwise rides in history and is re-sent every turn; a low value like 48000 reclaims it early. 0 = off. Recent tail protected by `protect_last_n`. Built-in compressor only (other engines inherit a no-op). NOTE: each committed prune rewrites already-sent history, breaking the provider prompt-cache prefix \u2014 the min_reclaim gate below keeps those breaks episodic rather than per-turn.",group:"compression",effect:"live"},"compression.progress_notices":{type:"bool",default:!1,doc:"opt-in (#52995): when True, routine compression progress statuses (compacting/preflight/pre-API/ idle/retry) are delivered to chat gateway platforms instead of being suppressed by the gateway noise filter. Default False keeps routine compression silent-by-design on chat surfaces (server-side logging only). Failure notices and manual /compress feedback are always visible regardless of this setting.",group:"compression",effect:"live"},"compression.protect_first_n":{type:"int",default:3,doc:"non-system head messages always preserved verbatim, in ADDITION to the system prompt (which is always implicitly protected). Set to 0 for long-running rolling-compaction sessions where you want nothing pinned except the system prompt + rolling summary + recent tail.",group:"compression",effect:"live"},"compression.protect_last_n":{type:"int",default:20,doc:"minimum recent messages to keep uncompressed",group:"compression",effect:"live"},"compression.target_ratio":{type:"float",default:0.2,doc:"fraction of threshold to preserve as recent tail",group:"compression",effect:"live"},"compression.threshold":{type:"float",default:0.5,doc:"compress when context usage exceeds this ratio. Models with context windows below 512K are floored at 0.75 (raise-only) so compaction doesn't fire with half the window still free; set this above 0.75 to override the floor.",group:"compression",effect:"live"},"compression.threshold_tokens":{type:"null",default:null,doc:"absolute token cap \u2014 when set, compression triggers at the lower of the ratio-based threshold and this token count. Clamped to the model's context length at apply-time.",group:"compression",effect:"live"},"computer_use.capture_after_mode":{type:"str",default:"som",doc:"Mode for capture_after follow-ups: som (screenshot + overlays \u2014 default), ax (elements only, no PNG \u2014 faster), vision (pixels only).",group:"computer_use",effect:"live"},"computer_use.cua_telemetry":{type:"bool",default:!1,doc:"cua-driver ships with anonymous usage telemetry (PostHog) ENABLED by default upstream. Hermes disables it for our users unless they explicitly opt in here. When false (default), Hermes sets CUA_DRIVER_RS_TELEMETRY_ENABLED=0 in the cua-driver child env for every invocation (MCP backend, status, doctor, install). Set true to let cua-driver use its own default (telemetry on).",group:"computer_use",effect:"live"},"computer_use.max_image_dimension":{type:"int",default:1456,doc:"Cap driver screenshot longest edge (pixels) via set_config on session start. Shrinks SOM multimodal payloads; 0 disables.",group:"computer_use",effect:"live"},"computer_use.no_overlay":{type:"null",default:null,doc:"Disable the cursor overlay rendered by cua-driver. The overlay shows where agent actions land but can peg a core when idle (macOS vImage redraw loop #47032; Linux/WSL2 idle spin #28152). cua-driver \u2265 0.6.x supports --no-overlay; Hermes also calls set_agent_cursor_enabled(false) after start_session when this is on. None = auto-detect (off on macOS + headless/WSL2 Linux; on elsewhere) True = always disable the overlay False = always enable the overlay",group:"computer_use",effect:"live"},"context.engine":{type:"str",default:"compressor",doc:"",group:"context",effect:"live"},context_file_max_chars:{type:"null",default:null,doc:"Hard cap (chars) for a single automatic context file such as SOUL.md, AGENTS.md, CLAUDE.md, .hermes.md, or .cursorrules before Hermes applies head/tail truncation. ``null`` (the default) lets the cap scale with the model's context window (floor 20K, ceiling 500K) so large-context models rarely truncate a project doc. Set a positive integer to pin a fixed cap and override the dynamic behavior. Separate from read_file tool limits.",group:"general",effect:"live"},credential_pool_strategies:{type:"dict",default:{},doc:"",group:"general",effect:"live"},"cron.chronos.callback_url":{type:"str",default:"",doc:"The agent's OWN publicly-reachable base URL for NAS\u2192agent fires (NAS POSTs {callback_url}/api/cron/fire). Empty \u2192 Chronos is unavailable and the resolver falls back to the built-in ticker.",group:"cron",effect:"live"},"cron.chronos.expected_audience":{type:"str",default:"",doc:`This agent's expected JWT audience (e.g. "agent:{instance_id}").`,group:"cron",effect:"live"},"cron.chronos.nas_jwks_url":{type:"str",default:"",doc:"NAS JWKS URL for verifying the inbound fire JWT's signature. Empty \u2192 the fire endpoint refuses all tokens (no unsigned decode).",group:"cron",effect:"live"},"cron.chronos.portal_url":{type:"str",default:"https://portal.nousresearch.com",doc:"NAS / portal base URL the agent calls to arm/cancel one-shots and that mints the inbound fire JWT (used as the expected issuer).",group:"cron",effect:"live"},"cron.max_parallel_jobs":{type:"null",default:null,doc:"Maximum number of due jobs to run in parallel per tick. null/0 = unbounded (limited only by thread count). 1 = serial (pre-v0.9 behaviour). Also overridable via HERMES_CRON_MAX_PARALLEL env var.",group:"cron",effect:"live"},"cron.mirror_delivery":{type:"bool",default:!1,doc:"Make cron deliveries CONTINUABLE: a user can reply to a cron brief and the agent has it in context (no \"what is Task #2?\" amnesia). Default False preserves the historical isolation guarantee (cron deliveries live only in the cron job's own session). Per-job `attach_to_session` overrides this for a single job. Behaviour is THREAD-PREFERRED, scoped to the job's origin chat: - Thread-capable platforms (Telegram forum/DM topics, Discord threads, Slack threads): a dedicated thread is opened for the job via the adapter's create_handoff_thread, the brief is delivered into it, and that thread's session is seeded so the user's reply in-thread continues with full context. Each continuable job gets its own scrollback, isolated from the parent channel. - DM-only platforms (WhatsApp / Signal / SMS): no threads exist, so the brief is mirrored into the origin DM session instead \u2014 the DM itself is the continuation surface. Both paths ride the shipped gateway.mirror.mirror_to_session and are alternation- and cache-safe (appended at a turn boundary, never mid-loop, never mutating the cached system prompt). Only the origin chat is ever touched \u2014 fan-out / broadcast targets are never mirrored.",group:"cron",effect:"live"},"cron.output_retention":{type:"int",default:50,doc:"Per-job output-file retention: save_job_output keeps the N most recent .md files and prunes older ones. 0 or negative disables pruning (for operators who manage cleanup externally). Default 50.",group:"cron",effect:"live"},"cron.provider":{type:"str",default:"",doc:'Active cron SCHEDULER provider (Axis B \u2014 the trigger that decides WHEN a due job fires). Empty string = the built-in in-process 60s ticker (default). Name an installed provider (plugins/cron_providers/<name>/ or $HERMES_HOME/plugins/<name>/) to relocate the trigger \u2014 e.g. "chronos", the NAS-mediated managed-cron provider for scale-to-zero deployments. An unknown or unavailable provider falls back to the built-in, so cron never loses its trigger.',group:"cron",effect:"live"},"cron.session_db_timeout_seconds":{type:"int",default:10,doc:"Timeout (seconds) for SessionDB() init inside cron jobs. SessionDB opens/migrates state.db synchronously and has no timeout of its own against a wedged sqlite3.connect. An unbounded hang here wedges the job's dispatch guard forever. Also overridable via HERMES_CRON_SESSION_DB_TIMEOUT env var. 0 = unlimited (skip the bound).",group:"cron",effect:"live"},"cron.wrap_response":{type:"bool",default:!0,doc:'Wrap delivered cron responses with a header (task name) and footer ("The agent cannot see this message"). Set to false for clean output.',group:"cron",effect:"live"},"curator.archive_after_days":{type:"int",default:90,doc:"Archive a skill (move to skills/.archive/) after this many days without use. Archived skills are recoverable \u2014 no auto-deletion.",group:"curator",effect:"live"},"curator.backup.enabled":{type:"bool",default:!0,doc:"",group:"curator",effect:"live"},"curator.backup.keep":{type:"int",default:5,doc:"retain last N regular snapshots",group:"curator",effect:"live"},"curator.consolidate":{type:"bool",default:!1,doc:"Run the LLM consolidation (umbrella-building) pass. OFF by default. When off, a curator run does ONLY the deterministic inactivity prune (mark stale / archive long-unused skills) and skips the forked aux-model review entirely \u2014 no umbrella-building, no aux-model cost. Set to true to opt back into merging overlapping skills into class-level umbrellas. `hermes curator run --consolidate` overrides this for a single invocation.",group:"curator",effect:"live"},"curator.enabled":{type:"bool",default:!0,doc:"",group:"curator",effect:"live"},"curator.interval_hours":{type:"int",default:168,doc:"How long to wait between curator runs (hours). Default: 7 days.",group:"curator",effect:"live"},"curator.min_idle_hours":{type:"int",default:2,doc:"Only run when the agent has been idle at least this long (hours).",group:"curator",effect:"live"},"curator.prune_builtins":{type:"bool",default:!0,doc:"Also prune (archive) bundled built-in skills after the inactivity period, not just agent-created ones. ON by default. Built-ins are normally restored on every `hermes update`, so pruning them only sticks because a suppression list tells the re-seeder to leave them archived. Hub-installed skills are NEVER pruned here \u2014 they have an external upstream owner. Built-ins accrue usage telemetry and their inactivity clock starts the first time the curator sees them, so a long-unused built-in is archived only after archive_after_days of genuine non-use (never a mass-prune on the first run). Set to false to keep all bundled built-ins permanently.",group:"curator",effect:"live"},"curator.stale_after_days":{type:"int",default:30,doc:'Mark a skill as "stale" after this many days without use.',group:"curator",effect:"live"},custom_prompt:{type:"str",default:"",doc:"Ad-hoc system-prompt addendum set via /prompt.",group:"general",effect:"live"},custom_providers:{type:"dict",default:{},doc:"OpenAI-compatible provider definitions keyed by name. Entries support ssl_ca_cert and ssl_verify.",group:"general",effect:"live"},"dashboard.basic_auth.password":{type:"str",default:"",doc:"plaintext fallback (hashed in-memory at load)",group:"dashboard",effect:"live"},"dashboard.basic_auth.password_hash":{type:"str",default:"",doc:"scrypt$... (preferred \u2014 no plaintext at rest)",group:"dashboard",effect:"live"},"dashboard.basic_auth.secret":{type:"str",default:"",doc:"token-signing key; blank \u2192 random per-process",group:"dashboard",effect:"live"},"dashboard.basic_auth.session_ttl_seconds":{type:"int",default:0,doc:"0 \u2192 plugin default (12h)",group:"dashboard",effect:"live"},"dashboard.basic_auth.username":{type:"str",default:"",doc:"blank \u2192 plugin no-op (no password provider)",group:"dashboard",effect:"live"},"dashboard.compute_host_heartbeat_secs":{type:"int",default:15,doc:"",group:"dashboard",effect:"live"},"dashboard.compute_host_respawn_max":{type:"int",default:3,doc:"",group:"dashboard",effect:"live"},"dashboard.drain_auth.min_secret_chars":{type:"int",default:43,doc:"",group:"dashboard",effect:"live"},"dashboard.drain_auth.scope":{type:"str",default:"drain",doc:"",group:"dashboard",effect:"live"},"dashboard.oauth.client_id":{type:"str",default:"",doc:"agent:{instance_id} \u2014 Portal provisions this",group:"dashboard",effect:"live"},"dashboard.oauth.portal_url":{type:"str",default:"",doc:"blank \u2192 use plugin default (production Portal)",group:"dashboard",effect:"live"},"dashboard.public_url":{type:"str",default:"",doc:"Public URL override (env: ``HERMES_DASHBOARD_PUBLIC_URL``). When set, this is the complete authority \u2014 scheme + host + optional path prefix (e.g. ``https://example.com/hermes``) \u2014 the OAuth ``redirect_uri`` is built from. Set this for deploys behind reverse proxies that don't reliably forward ``X-Forwarded-Host`` / ``X-Forwarded-Proto`` / ``X-Forwarded-Prefix`` (manual nginx setups, on-prem ingresses, custom-domain Fly deploys without proper proxy headers). When set, ``X-Forwarded-Prefix`` is IGNORED on the OAuth path because the operator has declared the public URL \u2014 we no longer need to guess from proxy headers, and stacking the prefix on top would double-prefix the common case where the prefix is already baked into ``public_url``. Leave empty to use the existing proxy-header reconstruction (the default). Validation: rejects values without ``http(s)://`` scheme or without a host, and any string containing quote / angle / whitespace / control characters. A malformed value silently falls through to request reconstruction rather than breaking the login flow.",group:"dashboard",effect:"live"},"dashboard.show_token_analytics":{type:"bool",default:!1,doc:"Hide the token/cost analytics surfaces (Analytics page, token bars and cost figures on the Models page) by default. The numbers shown there are a local debug estimate: they only count successful main-agent responses with a usable ``response.usage``, and silently exclude every auxiliary call (context compression, title generation, vision, session search, web extract, smart approval, MCP routing, plugin LLM access) plus provider-side retries, fallback attempts, and any call whose usage block didn't come back. Cache writes are also missing from the API response. On models with heavy auxiliary traffic (Kimi K2.6, MiniMax M2.7) the local total can be 10x-100x lower than the provider bill, which is worse than hiding the numbers entirely because they look precise enough to compare against the provider. Set this to True to re-enable the surfaces with the understanding that the numbers are a local lower-bound estimate, not billing.",group:"dashboard",effect:"live"},"dashboard.theme":{type:"str",default:"default",doc:'Dashboard visual theme: "default", "midnight", "ember", "mono", "cyberpunk", "rose"',group:"dashboard",effect:"live"},"dashboard.turn_isolation":{type:"bool",default:!1,doc:"Process-isolation rollout controls. Runtime reads these through the raw config loader, so tui_gateway.server also owns explicit defaults.",group:"dashboard",effect:"live"},"delegation.api_key":{type:"str",default:"",doc:"API key for delegation.base_url (falls back to OPENAI_API_KEY)",group:"delegation",effect:"session"},"delegation.api_mode":{type:"str",default:"",doc:`wire protocol for delegation.base_url: "chat_completions", "codex_responses", or "anthropic_messages". Empty = auto-detect from URL (e.g. /anthropic suffix \u2192 anthropic_messages). Set this explicitly for non-standard endpoints the heuristic can't detect.`,group:"delegation",effect:"session"},"delegation.base_url":{type:"str",default:"",doc:"direct OpenAI-compatible endpoint for subagents",group:"delegation",effect:"session"},"delegation.child_timeout_seconds":{type:"int",default:0,doc:"optional wall-clock cap per child agent. 0 (default) = no timeout: children fail only from real errors (API, tools, iteration budget), never a delegation stopwatch. Set a positive number of seconds (floor 30s) to enforce a hard cap.",group:"delegation",effect:"session"},"delegation.inherit_mcp_toolsets":{type:"bool",default:!0,doc:'When delegate_task narrows child toolsets explicitly, preserve any MCP toolsets the parent already has enabled. On by default so narrowing (e.g. toolsets=["web","browser"]) expresses "I want these extras" without silently stripping MCP tools the parent already has. Set to false for strict intersection.',group:"delegation",effect:"session"},"delegation.max_concurrent_children":{type:"int",default:3,doc:"unified concurrency cap: max parallel children per batch AND max concurrent background (background=true) delegation units. New async dispatches beyond the cap fall back to synchronous execution. Floor of 1, no ceiling. (Replaces the deprecated max_async_children.)",group:"delegation",effect:"session"},"delegation.max_iterations":{type:"int",default:50,doc:"per-subagent iteration cap (each subagent gets its own budget, independent of the parent's max_iterations)",group:"delegation",effect:"session"},"delegation.max_spawn_depth":{type:"int",default:1,doc:"Orchestrator role controls (see tools/delegate_tool.py:_get_max_spawn_depth and _get_orchestrator_enabled). Floored at 1, no upper ceiling \u2014 raise deliberately, each level multiplies API cost.",group:"delegation",effect:"session"},"delegation.max_summary_chars":{type:"int",default:24000,doc:`Subagent summaries return to the parent's context verbatim. A batch fan-out (N children) returns N summaries at once, which can exceed the parent's context window and trigger a compression/429 death spiral. delegate_task sizes each summary against the parent's remaining context headroom (split across the batch); when it must trim, the full text is spilled to ~/.hermes/cache/delegation/ (mounted into remote backends) and the in-context summary becomes a head+tail window plus a footer with the exact read_file offset to page the omitted middle \u2014 the same convention web_extract uses for large pages. Nothing is lost. max_summary_chars is a hard per-summary character ceiling layered on top of that dynamic budget (belt-and-suspenders for models that ignore the "be concise" instruction). 0 disables the hard ceiling; the dynamic headroom budget still applies.`,group:"delegation",effect:"session"},"delegation.model":{type:"str",default:"",doc:'e.g. "google/gemini-3-flash-preview" (empty = inherit parent model)',group:"delegation",effect:"session"},"delegation.orchestrator_enabled":{type:"bool",default:!0,doc:'kill switch for role="orchestrator"',group:"delegation",effect:"session"},"delegation.provider":{type:"str",default:"",doc:'e.g. "openrouter" (empty = inherit parent provider + credentials)',group:"delegation",effect:"session"},"delegation.reasoning_effort":{type:"str",default:"",doc:'subagent effort: "ultra", "max", "xhigh", "high", "medium", "low", "minimal", "none" (empty = inherit)',group:"delegation",effect:"session"},"delegation.subagent_auto_approve":{type:"bool",default:!1,doc:`When a subagent hits a dangerous-command approval prompt, the parent's prompt_toolkit TUI owns stdin \u2014 a thread-local input() call from the subagent worker would deadlock the parent UI. To avoid the deadlock, subagent threads ALWAYS resolve approvals non-interactively: false (default) \u2192 auto-deny with a logger.warning audit line (safe) true \u2192 auto-approve "once" with a logger.warning audit line Flip to true only if you trust delegated work to run dangerous cmds without human review (cron pipelines, batch automation, etc.).`,group:"delegation",effect:"session"},"desktop.auto_continue.enabled":{type:"bool",default:!0,doc:"",group:"desktop",effect:"live"},"desktop.auto_continue.freshness_minutes":{type:"int",default:15,doc:"How recent the interruption must be to auto-continue (minutes).",group:"desktop",effect:"live"},"desktop.auto_continue.max_attempts":{type:"int",default:2,doc:"Crash-loop breaker: max automatic re-runs of one interrupted turn.",group:"desktop",effect:"live"},"desktop.disable_gpu":{type:"str",default:"auto",doc:'GPU hardware acceleration policy for the desktop app: "auto" - let the app detect remote displays (SSH/VNC/RDP) and disable GPU only then (default; current behavior). true - always disable GPU acceleration (software rendering). Use on no-GPU VMs / Proxmox hosts where the GPU path hangs. false - always keep GPU acceleration on, even over a remote display. Bridged to the HERMES_DESKTOP_DISABLE_GPU env var the Electron app reads.',group:"desktop",effect:"live"},"desktop.electron_flags":{type:"list",default:[],doc:'Extra Electron command-line flags appended to every desktop launch, e.g. ["--ozone-platform=x11"] on headless/VM X11 hosts that need an explicit ozone backend, or GPU workaround flags. A list of strings; a single string is also accepted and shell-split.',group:"desktop",effect:"live"},"desktop.repo_scan_enabled":{type:"bool",default:!0,doc:"Git repository discovery for the Desktop Projects sidebar. Empty roots preserve the historical bounded scan of the user's home.",group:"desktop",effect:"live"},"desktop.repo_scan_exclude_paths":{type:"list",default:[],doc:"",group:"desktop",effect:"live"},"desktop.repo_scan_roots":{type:"list",default:[],doc:"",group:"desktop",effect:"live"},"discord.allow_any_attachment":{type:"bool",default:!1,doc:"DEPRECATED / no-op. Any uploaded file is now always cached and surfaced to the agent regardless of file type \u2014 authorization to message the agent is the gate, not the extension. Kept so existing configs that set it do not error. Env override: DISCORD_ALLOW_ANY_ATTACHMENT.",group:"discord",effect:"live"},"discord.allowed_channels":{type:"str",default:"",doc:"If set, bot ONLY responds in these channel IDs (whitelist)",group:"discord",effect:"live"},"discord.approval_mentions":{type:"bool",default:!1,doc:"When True, Discord approval prompts mention numeric allowed users so owners notice approval requests in shared channels/threads. Env override: DISCORD_APPROVAL_MENTIONS. Default false avoids surprise pings.",group:"discord",effect:"live"},"discord.auto_thread":{type:"bool",default:!0,doc:"Auto-create threads on @mention in channels (like Slack)",group:"discord",effect:"live"},"discord.bots_require_inline_mention":{type:"bool",default:!1,doc:"Multi-bot rooms: if True, another bot must type @thisbot in its message to trigger a reply; a Discord reply/quote alone won't. Prevents two bots auto-replying to each other forever. Does not affect humans.",group:"discord",effect:"live"},"discord.channel_prompts":{type:"dict",default:{},doc:"Per-channel ephemeral system prompts (forum parents apply to child threads)",group:"discord",effect:"live"},"discord.dm_role_auth_guild":{type:"str",default:"",doc:"Opt-in DM role-based auth (#12136). By default, DISCORD_ALLOWED_ROLES authorizes only guild messages in the role's own guild \u2014 DMs require DISCORD_ALLOWED_USERS. Set dm_role_auth_guild to a guild ID to also authorize DMs from members of that one trusted guild holding the allowed role. Unset / empty / 0 = secure default (DM role-auth off).",group:"discord",effect:"live"},"discord.free_response_channels":{type:"str",default:"",doc:"Comma-separated channel IDs where bot responds without mention",group:"discord",effect:"live"},"discord.history_backfill":{type:"bool",default:!0,doc:"If True, prepend recent channel scrollback when bot is triggered (recovers messages missed while require_mention gated them out)",group:"discord",effect:"live"},"discord.history_backfill_limit":{type:"int",default:50,doc:"Max number of recent messages to scan when assembling the backfill block",group:"discord",effect:"live"},"discord.max_attachment_bytes":{type:"int",default:33554432,doc:"Maximum bytes per attachment the gateway will cache. The whole file is held in memory while being written, so unlimited uploads carry a real memory cost. Default 32 MiB matches the historical hardcoded cap. Set to 0 for no cap. Env override: DISCORD_MAX_ATTACHMENT_BYTES.",group:"discord",effect:"live"},"discord.missed_message_backfill.channels":{type:"str",default:"",doc:"Comma-separated channel IDs; empty uses free_response_channels",group:"discord",effect:"live"},"discord.missed_message_backfill.enabled":{type:"bool",default:!1,doc:"Replay missed Discord messages after reconnect/startup",group:"discord",effect:"live"},"discord.missed_message_backfill.limit":{type:"int",default:100,doc:"Global cap on messages scanned per reconnect",group:"discord",effect:"live"},"discord.missed_message_backfill.max_dispatches":{type:"int",default:10,doc:"Cap on recovered messages dispatched per reconnect",group:"discord",effect:"live"},"discord.missed_message_backfill.window_seconds":{type:"int",default:21600,doc:"Only inspect messages from the last 6 hours",group:"discord",effect:"live"},"discord.reactions":{type:"bool",default:!0,doc:"Add \uD83D\uDC40/\u2705/\u274C reactions to messages during processing",group:"discord",effect:"live"},"discord.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in server channels",group:"discord",effect:"live"},"discord.server_actions":{type:"str",default:"",doc:'discord / discord_admin tools: restrict which actions the agent may call. Default (empty) = all actions allowed (subject to bot privileged intents). Accepts comma-separated string ("list_guilds,list_channels,fetch_messages") or YAML list. Unknown names are dropped with a warning at load time. Actions: list_guilds, server_info, list_channels, channel_info, list_roles, member_info, search_members, fetch_messages, list_pins, pin_message, unpin_message, create_thread, add_role, remove_role.',group:"discord",effect:"live"},"discord.thread_require_mention":{type:"bool",default:!1,doc:"If True, require @mention in threads too (multi-bot threads)",group:"discord",effect:"live"},"discord.voice_fx.ack_enabled":{type:"bool",default:!0,doc:"speak a short phrase before the first tool call",group:"discord",effect:"live"},"discord.voice_fx.ack_phrases":{type:"list",default:["Let me look into that.","One moment.","Checking on that now.","Give me a sec.","On it."],doc:"picked at random; set [] to disable phrases",group:"discord",effect:"live"},"discord.voice_fx.ambient_enabled":{type:"bool",default:!0,doc:'play the idle "thinking" bed while tools run',group:"discord",effect:"live"},"discord.voice_fx.ambient_gain":{type:"float",default:0.18,doc:"idle bed loudness, 0.0\u20131.0",group:"discord",effect:"live"},"discord.voice_fx.ambient_path":{type:"str",default:"",doc:'custom loop audio file; "" = synthesised pad',group:"discord",effect:"live"},"discord.voice_fx.duck_gain":{type:"float",default:0.06,doc:"ambient loudness while speech plays",group:"discord",effect:"live"},"discord.voice_fx.enabled":{type:"bool",default:!1,doc:"master switch for the mixer subsystem",group:"discord",effect:"live"},"discord.voice_fx.speech_gain":{type:"float",default:1,doc:"TTS / ack loudness, 0.0\u20131.0",group:"discord",effect:"live"},"discord.websocket_heartbeat_ack_max_age_seconds":{type:"int",default:60,doc:"",group:"discord",effect:"live"},"discord.websocket_liveness_failure_threshold":{type:"int",default:2,doc:"",group:"discord",effect:"live"},"discord.websocket_liveness_interval_seconds":{type:"int",default:15,doc:"Discord Gateway transport health. These settings inspect the active WebSocket's ready/open/heartbeat state; they never use Discord REST as proof that Gateway events are still arriving. Set any value to 0 to disable this compatibility-safe probe during a rollback.",group:"discord",effect:"live"},"discord.websocket_max_latency_seconds":{type:"int",default:30,doc:"",group:"discord",effect:"live"},"display.battery":{type:"bool",default:!1,doc:"Show a color-coded battery read-out as the first status-bar element in the CLI/TUI (off by default). No-op on machines without a battery.",group:"display",effect:"live"},"display.bell_on_complete":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.busy_input_mode":{type:"str",default:"interrupt",doc:"interrupt | queue | steer",group:"display",effect:"live"},"display.busy_steer_ack_enabled":{type:"bool",default:!0,doc:'When busy_input_mode="steer", suppress only the visible "Steered into current run" confirmation bubble by setting this false. The mid-turn steering itself still happens.',group:"display",effect:"live"},"display.cli_refresh_interval":{type:"float",default:1,doc:"Seconds between prompt_toolkit redraws in the classic CLI when idle. Default 1.0 keeps the wall-clock status-bar read-outs (idle-since- last-turn) ticking and keeps the bottom chrome alive during idle \u2014 without it prompt_toolkit stops repainting the status bar after a turn and it can go stale/disappear (#45592). Set 0 to disable the background refresh if it fights terminal auto-scroll in non-fullscreen mode on some emulators (#48309).",group:"display",effect:"live"},"display.compact":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.copy_shortcut":{type:"str",default:"auto",doc:'"auto" (platform default) | "ctrl_c" | "ctrl_shift_c" | "disabled"',group:"display",effect:"live"},"display.credits_notices":{type:"bool",default:!0,doc:"Nous credits status-bar notices (usage bands, grant-spent, depleted / restored). When false, no credits notices are emitted \u2014 balance data is still captured and /usage keeps working. Off switch for sub + top-up users who find the gauge noisy.",group:"display",effect:"live"},"display.details_mode":{type:"str",default:"collapsed",doc:"Tool-progress section fold state: hidden | collapsed | expanded.",group:"display",effect:"live"},"display.ephemeral_system_ttl":{type:"int",default:0,doc:'Auto-delete system-notice replies (e.g. "\u2728 New session started!", "\u267B Restarting gateway\u2026", "\u26A1 Stopped\u2026") after N seconds on platforms that support message deletion (currently Telegram; other platforms ignore and leave the message in place). Only affects slash-command replies wrapped with gateway.platforms.base.EphemeralReply \u2014 agent responses and content messages are never touched. Default 0 (disabled) preserves prior behavior.',group:"display",effect:"live"},"display.file_mutation_verifier":{type:"bool",default:!0,doc:'File-mutation verifier footer. When true (default), the agent appends a one-line advisory to its final response whenever a write_file / patch call failed during the turn and was never superseded by a successful write to the same path. This catches the "batch of parallel patches, half fail, model claims success" class of over-claim that otherwise forces users to run `git status` to verify edits landed. Set false to suppress.',group:"display",effect:"live"},"display.final_response_markdown":{type:"str",default:"strip",doc:"render | strip | raw",group:"display",effect:"live"},"display.focus_saved_tool_progress":{type:"str",default:"all",doc:"",group:"display",effect:"live"},"display.focus_view":{type:"bool",default:!1,doc:'Focus view (/focus): display-only reduced-output mode. When true the CLI/TUI pins tool_progress to "off" (reusing the existing suppression path), reports a per-turn hidden-line count with a recovery hint, and pins a "focus" segment in the status bar. focus_saved_tool_progress holds the mode /focus off restores. Never affects what is sent to the model \u2014 see hermes_cli/focus_view.py.',group:"display",effect:"live"},"display.friendly_tool_labels":{type:"bool",default:!0,doc:'Human-phrased tool status labels for built-in tools: "Searching the web for ...", "Reading <file>", "Browsing <url>" instead of the raw tool name. Applies to CLI spinner + gateway/desktop tool-progress. Custom/plugin/MCP tools always fall back to the raw preview.',group:"display",effect:"live"},"display.inline_diffs":{type:"bool",default:!0,doc:"Show inline diff previews for write actions (write_file, patch, skill_manage)",group:"display",effect:"live"},"display.interface":{type:"str",default:"cli",doc:'Which interface bare `hermes` (and `hermes chat`) launches by default: "cli" \u2014 the classic prompt_toolkit REPL (default, preserves prior behavior) "tui" \u2014 the modern Ink TUI (same as passing `--tui`) Explicit flags always win over this setting: `--cli` forces the classic REPL and `--tui` (or HERMES_TUI=1) forces the TUI regardless of config.',group:"display",effect:"live"},"display.interim_assistant_messages":{type:"bool",default:!0,doc:"Gateway: send natural mid-turn assistant status messages. Desktop: keep mid-turn narration between tool calls instead of collapsing to the final message.",group:"display",effect:"live"},"display.language":{type:"str",default:"en",doc:"UI language for static user-facing messages (approval prompts, a handful of gateway slash-command replies). Does NOT affect agent responses, log lines, tool outputs, or slash-command descriptions. Supported: en, zh, ja, de, es, fr, tr, uk. Unknown values fall back to en.",group:"display",effect:"live"},"display.memory_notifications":{type:"str",default:"on",doc:'Background self-improvement review notifications surfaced in chat. "off" \u2014 no chat notification (the review still runs and writes) "on" \u2014 generic "\uD83D\uDCBE Memory updated" line (default) "verbose" \u2014 include a compact content preview of what changed Per-platform overrides via display.platforms.<platform>.memory_notifications.',group:"display",effect:"live"},"display.persist_prompts":{type:"bool",default:!0,doc:"Print a one-line summary of resolved modal prompts (approval / clarify) into scrollback so the question and decision survive the panel repaint. Set false to keep scrollback untouched.",group:"display",effect:"live"},"display.persistent_output":{type:"bool",default:!0,doc:"Preserve recent classic CLI output across Ctrl+L, /redraw, and terminal resize full-screen clears. Disable if a terminal emulator behaves badly with replayed scrollback.",group:"display",effect:"live"},"display.persistent_output_max_lines":{type:"int",default:200,doc:"",group:"display",effect:"live"},"display.personality":{type:"str",default:"",doc:"",group:"display",effect:"live"},"display.pet.enabled":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.pet.render_mode":{type:"str",default:"auto",doc:"Terminal render protocol for CLI/TUI: auto \u2014 detect kitty/iTerm2/sixel, else unicode half-blocks kitty | iterm | sixel | unicode | off",group:"display",effect:"live"},"display.pet.scale":{type:"float",default:0.33,doc:"Master size scalar (relative to native 192\xD7208 frames). One knob shrinks every surface: the desktop canvas scales its pixels by it and the CLI/TUI derive their terminal column width from it. The half-block fallback clamps to a legibility floor (it can't shrink as far as true-pixel kitty/GUI without turning to mush).",group:"display",effect:"live"},"display.pet.slug":{type:"str",default:"",doc:"Active pet slug; resolved against installed pets in get_hermes_home()/pets/. Empty \u2192 first installed pet.",group:"display",effect:"live"},"display.pet.unicode_cols":{type:"int",default:0,doc:"Hard override for terminal column width. 0 = auto (derive from scale); set a positive int only to pin the half-block/kitty width independently of scale.",group:"display",effect:"live"},"display.platforms.discord.streaming":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.platforms.slack.streaming":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.platforms.telegram.streaming":{type:"bool",default:!0,doc:"",group:"display",effect:"live"},"display.reasoning_full":{type:"bool",default:!1,doc:'When reasoning display is on, the post-response "Reasoning" recap box collapses long thinking to the first 10 lines. Set true to print the complete thinking text uncollapsed (live streaming is always full).',group:"display",effect:"live"},"display.reasoning_style":{type:"str",default:"code",doc:'How a reasoning/thinking summary renders when show_reasoning is on. "code" (default) = \uD83D\uDCAD fenced code block; "blockquote" = "> " lines; "subtext" = "-# " lines (Discord small grey metadata text). Discord defaults to "subtext"; override per-platform via display.platforms.<platform>.reasoning_style.',group:"display",effect:"live"},"display.resume_display":{type:"str",default:"full",doc:"",group:"display",effect:"live"},"display.resume_exchanges":{type:"int",default:10,doc:"Recap tuning for /resume and startup resume. The defaults match the historical hardcoded values; expose them as config so power users can widen or tighten the snapshot to taste.",group:"display",effect:"live"},"display.resume_max_assistant_chars":{type:"int",default:200,doc:"truncate non-last assistant text",group:"display",effect:"live"},"display.resume_max_assistant_lines":{type:"int",default:3,doc:"truncate non-last assistant lines",group:"display",effect:"live"},"display.resume_max_user_chars":{type:"int",default:300,doc:"truncate user message text",group:"display",effect:"live"},"display.resume_skip_tool_only":{type:"bool",default:!0,doc:"When True (default), assistant entries that are *only* tool calls (no visible text) are skipped in the recap. This prevents the recap from being dominated by `[2 tool calls: terminal, read_file]` lines when an exchange was tool-heavy. Set False to restore the legacy behavior of showing tool-call summaries inline.",group:"display",effect:"live"},"display.runtime_footer.enabled":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.runtime_footer.fields":{type:"list",default:["model","context_pct","cwd"],doc:"Order shown; drop any to hide",group:"display",effect:"live"},"display.show_commentary":{type:"bool",default:!0,doc:"Codex Responses models narrate progress in a dedicated commentary channel. When true (default), completed commentary messages are delivered as visible mid-turn updates via the interim message path. When false, commentary falls back to the reasoning channel and is only visible when show_reasoning is enabled.",group:"display",effect:"live"},"display.show_cost":{type:"bool",default:!1,doc:"Show $ cost in the status bar (off by default)",group:"display",effect:"live"},"display.show_reasoning":{type:"bool",default:!0,doc:"Stream the model's reasoning/thinking live before the response. Default ON: on thinking models the reasoning phase can run tens of seconds, and with this off the user stares at a spinner the whole time even though tokens are streaming. Set false for quiet output.",group:"display",effect:"live"},"display.skin":{type:"str",default:"default",doc:"",group:"display",effect:"live"},"display.spinner_token_flow":{type:"bool",default:!0,doc:'CLI-only: append cumulative turn output tokens to the live spinner timer ("\u26A1 Reading file ( 2.3s \xB7 \u2193 1.2k tok)"). Updates as each API call in the turn reports usage.',group:"display",effect:"live"},"display.status_phrases":{type:"dict",default:{},doc:'Optional custom phrases for generic long-running status messages. Built-in defaults live in gateway/assets/status_phrases.yaml. Users can set `path`/`paths` to HERMES_HOME-relative YAML files/directories (or rely on conventional status_phrases.yaml / status_phrases/*.yaml). Keys: status, generic. Use mode: "append" (default) to add phrases, or "replace" to fully replace configured surfaces. Per-platform overrides live under display.platforms.<platform>.status_phrases.',group:"display",effect:"live"},"display.streaming":{type:"bool",default:!1,doc:"",group:"display",effect:"live"},"display.thinking_mode":{type:"str",default:"collapsed",doc:"Reasoning display: collapsed | truncated | full.",group:"display",effect:"live"},"display.timestamp_format":{type:"str",default:"%H:%M",doc:'strftime format for timestamps (e.g. "%b-%d %H:%M")',group:"display",effect:"live"},"display.timestamps":{type:"bool",default:!1,doc:"Show timestamp on user and assistant labels",group:"display",effect:"live"},"display.tool_preview_length":{type:"int",default:0,doc:"Max chars for tool call previews (0 = no limit, show full paths/commands)",group:"display",effect:"live"},"display.tool_progress":{type:"str",default:"all",doc:"Tool-progress verbosity: off | new | all | verbose.",group:"display",effect:"live"},"display.tool_progress_command":{type:"bool",default:!1,doc:"Enable /verbose command in messaging gateway",group:"display",effect:"live"},"display.tool_progress_grouping":{type:"str",default:"accumulate",doc:'How gateway tool-progress is grouped on platforms that support message editing: "accumulate" (default) edits one bubble in place; "separate" sends one message per tool (the pre-v0.9 behavior, noisier). Only applies where tool_progress is already enabled. Per-platform override via display.platforms.<platform>.tool_progress_grouping.',group:"display",effect:"live"},"display.tool_progress_overrides":{type:"dict",default:{},doc:"DEPRECATED \u2014 use display.platforms instead",group:"display",effect:"live"},"display.tui_agents_nudge":{type:"bool",default:!0,doc:'When true (default), `hermes --tui` drops a one-time hint ("subagents working \xB7 /agents to watch live") the first time a turn starts delegating, nudging the user toward the live spawn-tree dashboard. Set false to suppress the hint.',group:"display",effect:"live"},"display.tui_auto_resume_recent":{type:"bool",default:!1,doc:"When true, `hermes --tui` auto-resumes the most recent human- facing session on launch instead of forging a fresh one. Mirrors `hermes -c` muscle memory. Default off so existing users aren't surprised. HERMES_TUI_RESUME=<id> always wins.",group:"display",effect:"live"},"display.tui_compact":{type:"bool",default:!1,doc:"Ink-TUI compact layout.",group:"display",effect:"live"},"display.tui_mouse":{type:"bool",default:!0,doc:"Ink-TUI mouse support.",group:"display",effect:"live"},"display.tui_status_indicator":{type:"str",default:"kaomoji",doc:"TUI busy indicator style: kaomoji (default), emoji, unicode (braille spinner), or ascii. Live-swappable via `/indicator <style>`.",group:"display",effect:"live"},"display.tui_statusbar":{type:"str",default:"top",doc:"Ink-TUI statusbar placement: top | bottom | off.",group:"display",effect:"live"},"display.turn_completion_explainer":{type:"bool",default:!0,doc:`Turn-completion explainer. When true (default), the agent appends a one-line explanation to its final response whenever a turn ends abnormally with no usable reply \u2014 empty content after retries, a partial/truncated stream, a still-pending tool result, or an iteration/budget limit. Replaces the bare "(empty)" sentinel so the failure isn't silent from the UI's perspective. Set false to suppress.`,group:"display",effect:"live"},"display.turn_summary":{type:"bool",default:!0,doc:'CLI-only post-turn accounting line printed after each interactive turn: "\u22EF 12.4s \xB7 edited 2 files +18 -3 \xB7 read 4 files \xB7 ran 3 commands". Observed from the tool-progress feed the CLI already receives; never printed in quiet/non-interactive paths or in gateway/messaging surfaces (those have their own runtime footer).',group:"display",effect:"live"},"display.user_message_preview.first_lines":{type:"int",default:2,doc:"",group:"display",effect:"live"},"display.user_message_preview.last_lines":{type:"int",default:2,doc:"",group:"display",effect:"live"},fallback_model:{type:"dict",default:null,doc:"Fallback model (dict) or chain (list of dicts) for provider failover.",group:"general",effect:"live"},fallback_providers:{type:"list",default:[],doc:"",group:"general",effect:"live"},file_read_max_chars:{type:"int",default:1e5,doc:"Maximum characters returned by a single read_file call. Reads that exceed this are rejected with guidance to use offset+limit. 100K chars \u2248 25\u201335K tokens across typical tokenisers.",group:"general",effect:"live"},"gateway.api_server.max_concurrent_runs":{type:"int",default:10,doc:"Maximum number of agent runs the API server will service concurrently. Requests to /v1/chat/completions, /v1/responses, and /v1/runs that arrive while this many runs are already in flight are rejected with HTTP 429 + a Retry-After header, bounding CPU / memory / upstream-LLM-quota exhaustion from a request flood. Set to 0 to disable the cap entirely.",group:"gateway",effect:"live"},"gateway.delivery_ledger":{type:"bool",default:!0,doc:'Durable delivery-obligation ledger: final agent responses are recorded in state.db around the platform send, and a gateway that died between finalize and platform ACK redelivers the stored response on the next boot (ambiguous cases carry a visible "recovered reply \u2014 may be a duplicate" marker; honest at-least-once). Disable to lose in-flight final responses on crash/restart, as before.',group:"gateway",effect:"live"},"gateway.loop_watchdog":{type:"bool",default:!0,doc:"In-process event-loop liveness watchdog (#69089). A daemon OS thread probes the gateway asyncio loop; after consecutive missed probes it dumps all-thread stacks and hard-exits with the service-restart exit code so the supervisor (systemd/launchd) revives the process instead of leaving a wedged-but-alive zombie. Set to false to disable.",group:"gateway",effect:"live"},"gateway.max_inbound_media_bytes":{type:"int",default:134217728,doc:"Maximum bytes for an inbound image / audio / video payload the gateway will buffer into memory and cache to disk. Inbound media is read fully into RAM before being written, so an unbounded upload (Discord Nitro allows 500 MB) or a remote media URL pointing at a huge file can spike memory and OOM-kill the gateway on constrained deployments. Enforced in the shared cache helpers (gateway/platforms/base.py), so the cap holds across every platform adapter. ``0`` disables the cap. Default 128 MiB.",group:"gateway",effect:"live"},"gateway.media_delivery_allow_dirs":{type:"list",default:[],doc:"Extra directories from which model-emitted bare file paths may be uploaded as native gateway attachments. Files inside the Hermes cache (~/.hermes/cache/{documents,images,audio,video,screenshots}) are always trusted; this list adds operator-controlled roots (project dirs, scratch dirs, mounted shares). Accepts a list of absolute paths or a single os.pathsep-separated string. Bridged to HERMES_MEDIA_ALLOW_DIRS at gateway startup. Tilde paths are expanded. Honored in both default and strict mode.",group:"gateway",effect:"live"},"gateway.message_timestamps.enabled":{type:"bool",default:!1,doc:"",group:"gateway",effect:"live"},"gateway.platform_connect_timeout":{type:"int",default:30,doc:'Seconds the gateway waits for a single messaging platform to finish connecting during startup (and on reconnect). Discord in particular can blow past the old fixed 30s when an account has many slash commands to sync (#19776: 90-173 skills \u2192 ~28-31s sync). Raise this if your gateway hits "discord connect timed out" / "Timeout waiting for connection to Discord" restart loops. ``0`` or negative disables the timeout entirely (wait indefinitely). Bridged at startup to the internal HERMES_GATEWAY_PLATFORM_CONNECT_TIMEOUT env var, which still works as a manual override and wins if set explicitly.',group:"gateway",effect:"live"},"gateway.respawn_storm.max_starts":{type:"int",default:5,doc:"",group:"gateway",effect:"live"},"gateway.respawn_storm.window_seconds":{type:"int",default:120,doc:"",group:"gateway",effect:"live"},"gateway.restart_loop_guard.max_restarts":{type:"int",default:3,doc:"",group:"gateway",effect:"live"},"gateway.restart_loop_guard.window_seconds":{type:"int",default:60,doc:"",group:"gateway",effect:"live"},"gateway.scale_to_zero.idle_timeout_minutes":{type:"int",default:5,doc:"",group:"gateway",effect:"live"},"gateway.strict":{type:"bool",default:!1,doc:"When false (default), any file path the agent emits is delivered as a native attachment as long as it isn't under the credential / system-path denylist (/etc, /proc, ~/.ssh, ~/.aws, ~/.hermes/.env, auth.json, etc.). This matches the symmetry of inbound delivery \u2014 we accept any document type the user uploads, and the agent can hand back any file that isn't a credential. When true, fall back to the older allowlist+recency-window behavior: files must live under the Hermes cache, under ``media_delivery_allow_dirs``, or be freshly produced inside the ``trust_recent_files_seconds`` window. Recommended for public-facing gateways where prompt injection from one user shouldn't be able to exfiltrate the host's secrets to that same user. Bridged to HERMES_MEDIA_DELIVERY_STRICT.",group:"gateway",effect:"live"},"gateway.trust_recent_files":{type:"bool",default:!0,doc:'When true, files whose mtime is within ``trust_recent_files_seconds`` of "now" are trusted for native delivery even outside the cache / operator allowlist \u2014 useful for ``pandoc -o /tmp/report.pdf`` or PDFs the agent writes into a working directory. System paths (/etc, /proc, ~/.ssh, ~/.aws, etc.) remain blocked regardless. Disable to fall back to pure-allowlist mode. Bridged to HERMES_MEDIA_TRUST_RECENT_FILES. Only consulted when ``strict`` is true; in default mode the denylist alone gates delivery.',group:"gateway",effect:"live"},"gateway.trust_recent_files_seconds":{type:"int",default:600,doc:"Recency window in seconds. 600 (10 min) comfortably covers a multi-tool agent turn. Bridged to HERMES_MEDIA_TRUST_RECENT_SECONDS. Only consulted when ``strict`` is true.",group:"gateway",effect:"live"},"gateway.write_sessions_json":{type:"bool",default:!0,doc:"Whether the gateway keeps writing the legacy sessions.json mirror of its routing index. The primary copy lives in state.db (the gateway_routing table). Default True for backward compatibility with external tooling and downgrade safety; set to false to stop producing ~/.hermes/sessions/sessions.json entirely.",group:"gateway",effect:"live"},"goals.max_turns":{type:"int",default:20,doc:"Max continuation turns before Hermes auto-pauses the goal and asks the user to /goal resume. Protects against judge false negatives (goal actually done but judge says continue) and unbounded model spend on fuzzy / unachievable goals.",group:"goals",effect:"live"},honcho:{type:"dict",default:{},doc:"Honcho AI-native memory -- reads ~/.honcho/config.json as single source of truth. This section is only needed for hermes-specific overrides; everything else (apiKey, workspace, peerName, sessions, enabled) comes from the global config.",group:"general",effect:"live"},hooks:{type:"dict",default:{},doc:"Shell-script hooks \u2014 declarative bridge that invokes shell scripts on plugin-hook events (pre_tool_call, post_tool_call, pre_llm_call, subagent_stop, etc.). Each entry maps an event name to a list of {matcher, command, timeout} dicts. First registration of a new command prompts the user for consent; subsequent runs reuse the stored approval from ~/.hermes/shell-hooks-allowlist.json. See `website/docs/user-guide/features/hooks.md` for schema + examples.",group:"general",effect:"live"},hooks_auto_accept:{type:"bool",default:!1,doc:"Auto-accept shell-hook registrations without a TTY prompt. Also toggleable per-invocation via --accept-hooks or HERMES_ACCEPT_HOOKS=1. Gateway / cron / non-interactive runs need this (or one of the other channels) to pick up newly-added hooks.",group:"general",effect:"live"},"human_delay.max_ms":{type:"int",default:2500,doc:"",group:"human_delay",effect:"live"},"human_delay.min_ms":{type:"int",default:800,doc:"",group:"human_delay",effect:"live"},"human_delay.mode":{type:"str",default:"off",doc:"",group:"human_delay",effect:"live"},"kanban.auto_decompose":{type:"bool",default:!0,doc:"When true, the kanban dispatcher auto-runs the decomposer on tasks that land in Triage (every dispatcher tick). When false, decomposition is manual via `hermes kanban decompose <id>` or the dashboard's Decompose button.",group:"kanban",effect:"live"},"kanban.auto_decompose_per_tick":{type:"int",default:3,doc:"Max triage tasks to decompose per dispatcher tick. Prevents a large bulk-load of triage tasks from spending a burst of aux LLM calls in one tick. Excess tasks defer to the next tick.",group:"kanban",effect:"live"},"kanban.auto_subscribe_on_create":{type:"bool",default:!0,doc:"Auto-subscribe the originating gateway/TUI session to task completion + block events when ``kanban_create`` is called from inside a session that has a persistent delivery channel. The agent that dispatched the task will get notified automatically instead of having to poll. Disable to mirror pre-feature behaviour \u2014 e.g. for a profile that prefers explicit ``kanban_notify-subscribe`` calls per task.",group:"kanban",effect:"live"},"kanban.default_assignee":{type:"str",default:"",doc:"Where a child task lands if the orchestrator can't match an assignee to any installed profile. When unset, falls back to the default profile. A task never ends up with assignee=None.",group:"kanban",effect:"live"},"kanban.dispatch_in_gateway":{type:"bool",default:!0,doc:"Run the dispatcher inside the gateway process. On by default \u2014 the cost is ~300\xB5s every `dispatch_interval_seconds` when idle, and gateway is the supervisor users already have. Set to false only if you run the dispatcher as a separate systemd unit or don't want the gateway to spawn workers.",group:"kanban",effect:"live"},"kanban.dispatch_interval_seconds":{type:"int",default:60,doc:"Seconds between dispatcher ticks (idle or not). Lower = snappier pickup of newly-ready tasks; higher = less SQL pressure.",group:"kanban",effect:"live"},"kanban.dispatch_stale_timeout_seconds":{type:"int",default:14400,doc:"Stale detection: running tasks that have exceeded this many seconds without a heartbeat (since ``last_heartbeat_at``) are auto-reclaimed to ``ready`` on the next dispatcher tick. The worker process (if still running host-locally) is terminated before the reclaim. 0 disables stale detection entirely.",group:"kanban",effect:"live"},"kanban.failure_limit":{type:"int",default:2,doc:"Auto-block after this many consecutive non-success attempts for the same task/profile (spawn_failed, timed_out, or crashed). Reassignment resets the streak for the new profile.",group:"kanban",effect:"live"},"kanban.max_in_progress_per_profile":{type:"null",default:null,doc:`Per-profile concurrency cap (#21582). When set to a positive int, no single profile can have more than N workers running at once, even if the global max_in_progress / max_spawn caps would allow it. Tasks blocked this way defer to the next dispatcher tick. Unset (None) means "no per-profile cap" \u2014 backward-compatible with existing installs. Useful for fan-out workflows that would otherwise saturate one profile's local model / API quota / browser pool while leaving other profiles idle.`,group:"kanban",effect:"live"},"kanban.orchestrator_profile":{type:"str",default:"",doc:"Profile assigned to the root/orchestration task after Triage decomposition. When unset, falls back to the default profile (the one `hermes` launches with no -p flag). This does not control the decomposer prompt, model, or skills; configure that LLM path under auxiliary.kanban_decomposer.",group:"kanban",effect:"live"},"kanban.worker_log_backup_count":{type:"int",default:1,doc:"",group:"kanban",effect:"live"},"kanban.worker_log_rotate_bytes":{type:"int",default:2097152,doc:"Worker stdout/stderr logs rotate at spawn time. Defaults preserve the historical 2 MiB + one-backup behavior; long-running workers can raise these to keep more early failure evidence.",group:"kanban",effect:"live"},"logging.backup_count":{type:"int",default:3,doc:"Number of rotated backup files to keep",group:"logging",effect:"live"},"logging.level":{type:"str",default:"INFO",doc:"Minimum level for agent.log: DEBUG, INFO, WARNING",group:"logging",effect:"live"},"logging.max_size_mb":{type:"int",default:5,doc:"Max size per log file before rotation",group:"logging",effect:"live"},"lsp.enabled":{type:"bool",default:!0,doc:"Master toggle. Setting this to false disables the entire subsystem \u2014 no servers spawn, no background event loop, no cost.",group:"lsp",effect:"live"},"lsp.install_strategy":{type:"str",default:"auto",doc:'How to handle missing server binaries. ``"auto"`` \u2014 try to install via npm/go/pip into ``<HERMES_HOME>/lsp/bin/`` on first use. ``"manual"`` \u2014 only use binaries already on PATH. ``"off"`` \u2014 alias for ``manual``.',group:"lsp",effect:"live"},"lsp.servers":{type:"dict",default:{},doc:'Per-server overrides. Each key is a server_id from the registry (``pyright``, ``typescript``, ``gopls``, ``rust-analyzer``, etc.) and accepts: disabled: true \u2014 skip this server even when its extensions match command: ["full/path/to/server", "--stdio"] \u2014 pin a custom binary path; bypasses auto-install env: {"KEY": "value"} \u2014 extra env vars passed to the spawned process initialization_options: {...} \u2014 merged into the LSP ``initializationOptions`` Empty by default; the registry defaults work for typical setups.',group:"lsp",effect:"live"},"lsp.wait_mode":{type:"str",default:"document",doc:'Diagnostic-wait mode for the post-write check. ``"document"`` waits up to ``wait_timeout`` seconds for the current file\'s diagnostics; ``"full"`` additionally requests workspace-wide diagnostics (slower).',group:"lsp",effect:"live"},"lsp.wait_timeout":{type:"float",default:5,doc:"",group:"lsp",effect:"live"},"matrix.allowed_rooms":{type:"str",default:"",doc:"If set, bot ONLY responds in these room IDs (whitelist)",group:"matrix",effect:"live"},"matrix.free_response_rooms":{type:"str",default:"",doc:"Comma-separated room IDs where bot responds without mention",group:"matrix",effect:"live"},"matrix.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in rooms",group:"matrix",effect:"live"},"mattermost.allowed_channels":{type:"str",default:"",doc:"If set, bot ONLY responds in these channel IDs (whitelist)",group:"mattermost",effect:"live"},"mattermost.channel_prompts":{type:"dict",default:{},doc:"Per-channel ephemeral system prompts",group:"mattermost",effect:"live"},"mattermost.free_response_channels":{type:"str",default:"",doc:"Comma-separated channel IDs where bot responds without mention",group:"mattermost",effect:"live"},"mattermost.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in channels",group:"mattermost",effect:"live"},max_concurrent_sessions:{type:"null",default:null,doc:"Global active chat session cap across CLI, TUI/dashboard, and messaging. None/0 = unbounded.",group:"general",effect:"live"},max_live_sessions:{type:"int",default:16,doc:"Soft LRU cap on in-memory TUI/desktop/dashboard sessions. When more than this many are live, the gateway evicts the least-recently-active DETACHED sessions (no live client) so accumulated agents don't pile up under memory pressure. Reopening one re-resumes it from disk. 0/null disables.",group:"general",effect:"live"},"mcp.auto_reload_on_config_change":{type:"bool",default:!0,doc:"Auto-reload MCP connections when config.yaml's mcp_servers section changes at runtime (CLI file watcher, default on). Set to false to stop the automatic reload: every automatic reload rebuilds the agent tool surface and INVALIDATES the provider prompt cache (the next message re-sends the full input prefix), which is expensive on long-context / high-reasoning models. When disabled, the watcher still detects the change and prints guidance to apply it deliberately via /reload-mcp.",group:"mcp",effect:"live"},mcp_discovery_timeout:{type:"float",default:1.5,doc:"Seconds to wait at agent-build time for in-flight MCP server discovery to finish before the agent snapshots its tool list. MCP discovery runs in a background thread so a slow/dead server can't freeze startup; this bounds how long the first agent build blocks on it. The wait returns the INSTANT discovery completes, so users with no MCP servers (the common case) or fast servers pay ~0s regardless of this value \u2014 the bound is only reached when a server is genuinely still connecting. The old 0.75s default was a touch short for HTTP/OAuth servers on a cold connect; a modest bump lets more of them land in the FIRST turn's snapshot. This is only a turn-1 latency/UX knob: a server that misses this window is still picked up automatically on the next turn by the between-turns refresh (see agent/turn_context.py), so correctness never depends on it. Keep it small so a slow/dead server adds little to first-response latency.",group:"general",effect:"live"},mcp_servers:{type:"dict",default:{},doc:"MCP server definitions keyed by name.",group:"general",effect:"restart"},"memory.memory_char_limit":{type:"int",default:2200,doc:"~800 tokens at 2.75 chars/token",group:"memory",effect:"session"},"memory.memory_enabled":{type:"bool",default:!0,doc:"",group:"memory",effect:"session"},"memory.provider":{type:"str",default:"",doc:'External memory provider plugin (empty = built-in only). Set to a provider name to activate: "openviking", "mem0", "hindsight", "holographic", "retaindb", "byterover". Only ONE external provider is allowed at a time.',group:"memory",effect:"session"},"memory.user_char_limit":{type:"int",default:1375,doc:"~500 tokens at 2.75 chars/token",group:"memory",effect:"session"},"memory.user_profile_enabled":{type:"bool",default:!0,doc:"",group:"memory",effect:"session"},"memory.write_approval":{type:"bool",default:!1,doc:'Approval gate for memory writes (add/replace/remove), applied to BOTH foreground agent turns and the background self-improvement review fork (the source of unprompted "wrong assumption" saves users reported). false (default) \u2014 write freely; the gate is off (pre-gate behaviour) true \u2014 require approval: foreground writes prompt inline (entries are small enough to review in a chat bubble); background-review writes are staged instead of committed (a daemon thread cannot block on a prompt). Review staged entries with /memory pending, /memory approve <id>, /memory reject <id>. To disable memory entirely, use memory_enabled: false instead.',group:"memory",effect:"session"},"moa.active_preset":{type:"str",default:"",doc:"",group:"moa",effect:"live"},"moa.default_preset":{type:"str",default:"default",doc:"",group:"moa",effect:"live"},"moa.presets.default.aggregator.model":{type:"str",default:"anthropic/claude-opus-4.8",doc:"",group:"moa",effect:"live"},"moa.presets.default.aggregator.provider":{type:"str",default:"openrouter",doc:"",group:"moa",effect:"live"},"moa.presets.default.enabled":{type:"bool",default:!0,doc:"",group:"moa",effect:"live"},"moa.presets.default.max_tokens":{type:"int",default:4096,doc:"",group:"moa",effect:"live"},"moa.presets.default.reference_models":{type:"list",default:[{provider:"openai-codex",model:"gpt-5.5"},{provider:"openrouter",model:"deepseek/deepseek-v4-pro"}],doc:"",group:"moa",effect:"live"},"moa.privacy_filter":{type:"str",default:"",doc:`Privacy redaction filter for advisor (reference) outputs. Advisors can echo PII from the conversation (emails, formatted phone numbers) and credential shapes into reference blocks, traces, and the aggregator prompt. Modes ('' = off, the default): "display" \u2014 redact user-visible surfaces only (reference blocks shown in the UI + saved MoA trace records); the aggregator still sees raw advisor text. "full" \u2014 additionally redact the advisor text injected into the aggregator prompt (issue #59959).`,group:"moa",effect:"live"},"moa.save_traces":{type:"bool",default:!1,doc:"When true, every MoA turn that runs the reference fan-out writes the FULL turn (each reference's exact input messages + output + usage/cost, and the aggregator's exact input + output) to a JSONL file at <hermes_home>/moa-traces/<session_id>.jsonl. Off by default \u2014 turn it on to audit / improve MoA behavior from real runs. Set trace_dir to override the output directory.",group:"moa",effect:"live"},"moa.trace_dir":{type:"str",default:"",doc:"",group:"moa",effect:"live"},model:{type:"str",default:"",doc:"",group:"general",effect:"live"},"model_catalog.enabled":{type:"bool",default:!0,doc:"",group:"model_catalog",effect:"live"},"model_catalog.providers":{type:"dict",default:{},doc:"Optional per-provider override URLs for third parties that want to self-host their own curation list using the same schema. Example: providers: openrouter: url: https://example.com/my-curation.json",group:"model_catalog",effect:"live"},"model_catalog.ttl_hours":{type:"int",default:1,doc:"Disk cache TTL in hours. Beyond this, the CLI refetches on the next /model or `hermes model` invocation; network failures silently fall back to the stale cache.",group:"model_catalog",effect:"live"},"model_catalog.url":{type:"str",default:"https://hermes-agent.nousresearch.com/docs/api/model-catalog.json",doc:"",group:"model_catalog",effect:"live"},"network.force_ipv4":{type:"bool",default:!1,doc:"Force IPv4 connections. On servers with broken or unreachable IPv6, Python tries AAAA records first and hangs for the full TCP timeout before falling back to IPv4. Set to true to skip IPv6 entirely.",group:"network",effect:"live"},"onboarding.profile_build":{type:"str",default:"ask",doc:'Structured profile-build path offered on the very first gateway message ever. "ask" (default) -> offer to build a user profile (opt-in, consent-gated; the agent asks before any lookup and never reads connected accounts silently). "off" -> plain intro only. The offer fires at most once (latched under onboarding.seen).',group:"onboarding",effect:"live"},"onboarding.seen":{type:"dict",default:{},doc:"",group:"onboarding",effect:"live"},"openrouter.min_coding_score":{type:"float",default:0.65,doc:"Coding-score floor (0.0-1.0) for openrouter/pareto-code. Only applied when model is openrouter/pareto-code; ignored otherwise. Lower = cheaper model, higher = stronger coder.",group:"openrouter",effect:"live"},"openrouter.response_cache":{type:"bool",default:!0,doc:"",group:"openrouter",effect:"live"},"openrouter.response_cache_ttl":{type:"int",default:300,doc:"",group:"openrouter",effect:"live"},paste_collapse_char_threshold:{type:"int",default:2000,doc:"",group:"general",effect:"live"},paste_collapse_threshold:{type:"int",default:5,doc:'Paste collapse thresholds (TUI + CLI). paste_collapse_threshold (default 5) Bracketed-paste handler. Pastes with this many newlines or more collapse to a file reference. Set 0 to disable. paste_collapse_threshold_fallback (default 5) Fallback heuristic for terminals without bracketed paste support. Same line count test but heuristically gated by chars-added / newlines-added to avoid false positives from normal typing. Set 0 to disable. paste_collapse_char_threshold (default 2000) Long single-line paste guard. Pastes whose total char length reaches this value collapse to a file reference even if line count is below the line threshold. Catches the "8000 chars of minified JSON / log output on one line" case. Set 0 to disable.',group:"general",effect:"live"},paste_collapse_threshold_fallback:{type:"int",default:5,doc:"",group:"general",effect:"live"},personalities:{type:"dict",default:{},doc:'Custom personalities \u2014 add your own entries here Supports string format: {"name": "system prompt"} Or dict format: {"name": {"description": "...", "system_prompt": "...", "tone": "...", "style": "..."}}',group:"general",effect:"live"},platform_hints:{type:"dict",default:{},doc:'Per-platform system-prompt hint overrides. Lets an admin append to or replace Hermes\' built-in platform hint for a single messaging platform (WhatsApp, Slack, Telegram, ...) without affecting other platforms. Useful for enterprise/managed profiles that ship platform-aware skills. Each key is a platform name; the value is either: { "append": "extra text" } \u2014 keep the default hint, append text { "replace": "full text" } \u2014 substitute the default hint entirely "extra text" \u2014 shorthand for { "append": ... } `replace` wins over `append` if both are given. Example: platform_hints: whatsapp: append: > When tabular output would be useful, invoke the table_formatting skill instead of emitting a Markdown table.',group:"general",effect:"live"},prefill_messages_file:{type:"str",default:"",doc:"Ephemeral prefill messages file \u2014 JSON list of {role, content} dicts injected at the start of every API call for few-shot priming. Never saved to sessions, logs, or trajectories.",group:"general",effect:"live"},"privacy.redact_pii":{type:"bool",default:!1,doc:"When True, hash user IDs and strip phone numbers from LLM context",group:"privacy",effect:"live"},"prompt_caching.cache_ttl":{type:"str",default:"5m",doc:"",group:"prompt_caching",effect:"live"},provider:{type:"str",default:"",doc:"Default model provider.",group:"general",effect:"live"},providers:{type:"dict",default:{},doc:"Provider definitions keyed by name. Custom/OpenAI-compatible entries support ssl_ca_cert and ssl_verify.",group:"general",effect:"live"},"proxy.allow_env_fallback":{type:"bool",default:!1,doc:'NOTE: ``fail_on_uncovered_providers`` was removed. It gated a refuse-start when Anthropic / Azure OpenAI / Gemini env vars were present \u2014 those providers are now first-class swapped providers via per-provider match_headers rules (x-api-key, api-key, x-goog-api-key), so the fail-closed tier is empty. A leftover key in existing user configs is ignored harmlessly. When credential_source is bitwarden but the BWS access token / project_id is missing OR the bws fetch returns no values for mapped providers, the daemon raises by default. Set this to True to opt back in to the legacy "silently fall back to host env" behaviour \u2014 useful for migrations where the operator wants to switch credential_source to bitwarden but hasn\'t fully wired BWS yet. Defaults to false (strict).',group:"proxy",effect:"live"},"proxy.auto_install":{type:"bool",default:!0,doc:"Auto-download the pinned iron-proxy binary into ~/.hermes/bin/ on first use. When false, you must place `iron-proxy` on PATH yourself.",group:"proxy",effect:"live"},"proxy.credential_source":{type:"str",default:"env",doc:'Where iron-proxy looks up the real upstream secrets at egress time. "env" \u2014 process env (default; what bitwarden integration already populates if you use it) "bitwarden" \u2014 refetch via `bws secret list` on each proxy restart; rotation in the Bitwarden web app propagates without touching .env (requires `secrets.bitwarden.enabled`).',group:"proxy",effect:"live"},"proxy.enabled":{type:"bool",default:!1,doc:"Master switch. When false, iron-proxy is never started, no docker mounts are added, no binaries are auto-installed \u2014 feature is a complete no-op.",group:"proxy",effect:"live"},"proxy.enforce_on_docker":{type:"bool",default:!0,doc:"When true, the Docker backend refuses to start a sandbox if the proxy is enabled but not running. False = fall back to direct outbound with real credentials in the sandbox (the legacy posture).",group:"proxy",effect:"live"},"proxy.extra_allowed_hosts":{type:"list",default:[],doc:"Extra allowed upstream hosts beyond the bundled defaults (which cover OpenRouter, OpenAI, Anthropic, Google, xAI, Mistral, Groq, Together, DeepSeek, Nous). Wildcards (`*.foo.com`) are supported.",group:"proxy",effect:"live"},"proxy.tunnel_port":{type:"int",default:9090,doc:"Tunnel listener port. Sandboxes get `HTTPS_PROXY=http://<host>:<port>`. 9090 is the default; collide-aware setup wizard can reassign.",group:"proxy",effect:"live"},"proxy.upstream_deny_cidrs":{type:"null",default:null,doc:"SSRF deny list applied to outbound traffic. Omit / leave empty to use the safe default: loopback, link-local (incl. cloud metadata IPs at 169.254.169.254), and RFC1918. Set to an explicit ``[]`` to opt out entirely (only sensible in hermetic tests that need to reach a loopback upstream).",group:"proxy",effect:"live"},quick_commands:{type:"dict",default:{},doc:"User-defined quick commands that bypass the agent loop (type: exec only)",group:"general",effect:"live"},"secrets.bitwarden.access_token_env":{type:"str",default:"BWS_ACCESS_TOKEN",doc:"Name of the env var that holds the Bitwarden machine-account access token. This is the one bootstrap secret; it lives in ~/.hermes/.env (or your shell) and never in config.yaml.",group:"secrets",effect:"live"},"secrets.bitwarden.auto_install":{type:"bool",default:!0,doc:"When True, the bws binary is auto-downloaded into ~/.hermes/bin/ on first use. When False you must install bws yourself and have it on PATH.",group:"secrets",effect:"live"},"secrets.bitwarden.cache_ttl_seconds":{type:"int",default:300,doc:"Seconds to reuse a fresh disk/memory cache entry before contacting Bitwarden again. 0 disables normal fresh-cache reuse.",group:"secrets",effect:"live"},"secrets.bitwarden.enabled":{type:"bool",default:!1,doc:"Master switch. When false, BSM is never contacted and the bws binary is never auto-installed \u2014 same as not having this section at all.",group:"secrets",effect:"live"},"secrets.bitwarden.encrypted_cache.enabled":{type:"bool",default:!1,doc:"",group:"secrets",effect:"live"},"secrets.bitwarden.encrypted_cache.max_stale_seconds":{type:"int",default:0,doc:"",group:"secrets",effect:"live"},"secrets.bitwarden.override_existing":{type:"bool",default:!0,doc:"When True, BSM values overwrite existing env vars. Default True because the point of using BSM is centralized rotation \u2014 if .env had the final say, rotating in Bitwarden wouldn't take effect until you also cleared the matching .env line.",group:"secrets",effect:"live"},"secrets.bitwarden.project_id":{type:"str",default:"",doc:"UUID of the BSM project to sync from.",group:"secrets",effect:"live"},"secrets.bitwarden.server_url":{type:"str",default:"",doc:"Bitwarden region / self-hosted endpoint. Empty string means use the bws CLI default (US Cloud, https://vault.bitwarden.com). Set to https://vault.bitwarden.eu for EU Cloud, or your own URL for self-hosted Bitwarden. Plumbed into the bws subprocess as BWS_SERVER_URL. Prompted for during `hermes secrets bitwarden setup`.",group:"secrets",effect:"live"},"secrets.onepassword.account":{type:"str",default:"",doc:"Optional account shorthand / sign-in address passed as `op read --account <account>`. Empty = op's default account.",group:"secrets",effect:"live"},"secrets.onepassword.binary_path":{type:"str",default:"",doc:"Optional absolute path to the op binary. When set it is used verbatim (PATH is not consulted) \u2014 pin this to avoid trusting whatever `op` appears first on PATH. Empty = resolve via PATH.",group:"secrets",effect:"live"},"secrets.onepassword.cache_ttl_seconds":{type:"int",default:300,doc:"Seconds to cache resolved values in-process and on disk. 0 disables BOTH cache layers (no values are written to disk).",group:"secrets",effect:"live"},"secrets.onepassword.enabled":{type:"bool",default:!1,doc:"Master switch. When false, the op CLI is never invoked \u2014 same as not having this section at all.",group:"secrets",effect:"live"},"secrets.onepassword.env":{type:"dict",default:{},doc:"Mapping of env-var name \u2192 1Password secret reference (op://vault/item/field). Each entry is resolved with a single `op read` at startup.",group:"secrets",effect:"live"},"secrets.onepassword.override_existing":{type:"bool",default:!0,doc:"When True (default), resolved values overwrite existing env vars so rotating a secret in 1Password takes effect on next start. Flip to false to let .env / shell exports win locally.",group:"secrets",effect:"live"},"secrets.onepassword.service_account_token_env":{type:"str",default:"OP_SERVICE_ACCOUNT_TOKEN",doc:"Name of the env var holding a 1Password service-account token for headless auth. Sourced from ~/.hermes/.env (or the shell) and exported to the op child as OP_SERVICE_ACCOUNT_TOKEN. Leave the var unset to use an interactive/desktop op session.",group:"secrets",effect:"live"},"security.acked_advisories":{type:"list",default:[],doc:"Acknowledged supply-chain security advisories. Each entry is the ID of an advisory the user has read and acted on (uninstalled the compromised package, rotated credentials). Acked advisories no longer trigger the startup banner. Add via `hermes doctor --ack <id>`; remove by editing the list directly. See ``hermes_cli/security_advisories.py`` for the catalog.",group:"security",effect:"live"},"security.allow_lazy_installs":{type:"bool",default:!0,doc:"Allow Hermes to lazy-install opt-in backend packages from PyPI the first time the user enables a backend that needs them (e.g. installing ``elevenlabs`` when the user picks ElevenLabs as their TTS provider). Set to false to require explicit ``pip install`` for everything beyond the base set \u2014 appropriate for restricted networks, audited environments, or air-gapped systems where any runtime install is unacceptable.",group:"security",effect:"live"},"security.allow_private_urls":{type:"bool",default:!1,doc:"Allow requests to private/internal IPs (for OpenWrt, proxies, VPNs)",group:"security",effect:"live"},"security.redact_secrets":{type:"bool",default:!0,doc:"",group:"security",effect:"live"},"security.tirith_enabled":{type:"bool",default:!0,doc:"",group:"security",effect:"live"},"security.tirith_fail_open":{type:"bool",default:!0,doc:"",group:"security",effect:"live"},"security.tirith_path":{type:"str",default:"tirith",doc:"",group:"security",effect:"live"},"security.tirith_timeout":{type:"int",default:5,doc:"",group:"security",effect:"live"},"security.website_blocklist.domains":{type:"list",default:[],doc:"",group:"security",effect:"live"},"security.website_blocklist.enabled":{type:"bool",default:!1,doc:"",group:"security",effect:"live"},"security.website_blocklist.shared_files":{type:"list",default:[],doc:"",group:"security",effect:"live"},"sessions.auto_archive":{type:"bool",default:!1,doc:'When true, auto-archive (soft-hide, never delete) sessions that haven\'t been touched in ``auto_archive_days`` days, once per (roughly) min_interval_hours. "Touched" is last activity, not creation, so an old-but-recently-used session is spared. Pinned sessions are always exempt. Off by default \u2014 opt in explicitly.',group:"sessions",effect:"live"},"sessions.auto_archive_days":{type:"int",default:3,doc:"Idle threshold (days of no activity) before auto-archive hides a session. Only applies when auto_archive is true.",group:"sessions",effect:"live"},"sessions.auto_prune":{type:"bool",default:!1,doc:"When true, prune ended sessions inactive for retention_days once per (roughly) min_interval_hours at CLI/gateway/cron startup. Activity is the latest message timestamp, falling back to creation time for empty sessions. Active sessions are always preserved. Default false: session history is valuable for search recall, and silently deleting it could surprise users. Opt in explicitly.",group:"sessions",effect:"live"},"sessions.cjk_fts":{type:"bool",default:!0,doc:"CJK-bigram search index (messages_fts_cjk, cjk_unicode61 loadable tokenizer). When the extension is built (native/fts5_cjk/build.sh \u2192 ~/.hermes/lib/libfts5_cjk.so), 1-2 char CJK terms (\uC77C\uBCF8, \u9879\u76EE, ...) get index-speed exact matching instead of LIKE full-table scans. True (default): use the index when the extension is present; the setting is inert when it isn't. False: never load the extension or serve the cjk index. Bridged to HERMES_CJK_FTS (internal carrier).",group:"sessions",effect:"live"},"sessions.fts_optimize_notice":{type:"str",default:"advise",doc:'Search-index (FTS) storage optimization \u2014 the compact v23 layout that drops duplicate content copies and stops trigram-indexing tool output (typically reclaims ~60%+ of state.db on heavy users). It is OPT-IN: existing databases keep their working legacy index until the user runs `hermes sessions optimize-storage`, because the rebuild is disk-heavy and long on large DBs (see that command\'s disk preflight). "advise" (default): `hermes update` prints a one-line notice with the reclaimable size and the command, when a legacy index is detected. Nothing is changed automatically. "require": the notice is shown as a REQUIRED upgrade (firmer copy), and future tooling may gate on it. Flip this default in a future release when we\'re ready to make the v23 layout mandatory \u2014 the command, progress bar, and resumability are already in place, so enforcement is a copy/gating change, not new migration code. "off": suppress the notice entirely.',group:"sessions",effect:"live"},"sessions.min_interval_hours":{type:"int",default:24,doc:"Minimum hours between auto-maintenance runs (avoids repeating the sweep on every CLI invocation). Tracked via state_meta in state.db itself, so it's shared across all processes.",group:"sessions",effect:"live"},"sessions.retention_days":{type:"int",default:90,doc:"How many inactive days of ended-session history to keep. Matches the default of ``hermes sessions prune``.",group:"sessions",effect:"live"},"sessions.search_slow_ms":{type:"int",default:1000,doc:"Slow session-search log threshold in milliseconds: searches at or above it log one INFO line with the routing path taken (fts_cjk / fts5 / trigram / like_scan) so latency regressions stay attributable per query shape. 0 logs every search. Bridged to HERMES_SEARCH_SLOW_MS (internal carrier).",group:"sessions",effect:"live"},"sessions.vacuum_after_prune":{type:"bool",default:!0,doc:"VACUUM after a prune that actually deleted rows. SQLite does not reclaim disk space on DELETE \u2014 freed pages are just reused on subsequent INSERTs \u2014 so without VACUUM the file stays bloated even after pruning. VACUUM blocks writes for a few seconds per 100MB, so it only runs at startup, and only when prune deleted \u22651 session.",group:"sessions",effect:"live"},"sessions.write_json_snapshots":{type:"bool",default:!1,doc:"Legacy per-session JSON snapshot writer. When true, the agent rewrites ``~/.hermes/sessions/session_{sid}.json`` on every turn boundary with the full message list. state.db is canonical and has every field the snapshot stored (plus per-message timestamps and token counts), so this is off by default \u2014 the snapshots had no consumer outside their own overwrite guard and accumulated GBs of disk on heavy users. Opt in only if you have an external tool that consumes the JSON files directly.",group:"sessions",effect:"live"},"skills.external_dirs":{type:"list",default:[],doc:'e.g. ["~/.agents/skills", "/shared/team-skills"]',group:"skills",effect:"restart"},"skills.guard_agent_created":{type:"bool",default:!1,doc:"Run the keyword/pattern security scanner on skills the agent writes via skill_manage (create/edit/patch). Off by default because the agent can already execute the same code paths via terminal() with no gate, so the scan adds friction (blocks skills that mention risky keywords in prose) without meaningful security. Turn on if you want the belt-and-suspenders \u2014 a dangerous verdict will then surface as a tool error to the agent, which can retry with the flagged content removed. External hub installs (trusted/community sources) are always scanned regardless of this setting.",group:"skills",effect:"live"},"skills.inline_shell":{type:"bool",default:!1,doc:"Pre-execute inline shell snippets written as !`cmd` in SKILL.md body. Their stdout is inlined into the skill message before the agent reads it, so skills can inject dynamic context (dates, git state, detected tool versions, \u2026). Off by default because any content from the skill author runs on the host without approval; only enable for skill sources you trust.",group:"skills",effect:"live"},"skills.inline_shell_timeout":{type:"int",default:10,doc:"Timeout (seconds) for each !`cmd` snippet when inline_shell is on.",group:"skills",effect:"live"},"skills.template_vars":{type:"bool",default:!0,doc:"Substitute ${HERMES_SKILL_DIR} and ${HERMES_SESSION_ID} in SKILL.md content with the absolute skill directory and the active session id before the agent sees it. Lets skill authors reference bundled scripts without the agent having to join paths.",group:"skills",effect:"live"},"skills.write_approval":{type:"bool",default:!1,doc:"Approval gate for skill_manage (create/edit/patch/write_file/delete/ remove_file), applied to BOTH foreground agent turns and the background self-improvement review fork. false (default) \u2014 write freely; the gate is off (pre-gate behaviour) true \u2014 require approval: stage the write for review instead of committing (a SKILL.md is too large to review inline, so skills always stage rather than prompt). List with /skills pending, inspect with /skills diff <id> (full diff \u2014 CLI/dashboard/file, never crammed into a chat bubble), apply with /skills approve <id> or drop with /skills reject <id>.",group:"skills",effect:"live"},"slack.allowed_channels":{type:"str",default:"",doc:"If set, bot ONLY responds in these channel IDs (whitelist)",group:"slack",effect:"live"},"slack.channel_prompts":{type:"dict",default:{},doc:"Per-channel ephemeral system prompts",group:"slack",effect:"live"},"slack.free_response_channels":{type:"str",default:"",doc:"Comma-separated channel IDs where bot responds without mention",group:"slack",effect:"live"},"slack.ignore_other_user_mentions":{type:"bool",default:!1,doc:"Ignore a channel/thread message addressed to another user (first token @mentions someone other than the bot) unless the bot is also mentioned. Opt-in; default off keeps existing behaviour. Env: SLACK_IGNORE_OTHER_USER_MENTIONS.",group:"slack",effect:"live"},"slack.require_mention":{type:"bool",default:!0,doc:"Require @mention to respond in channels",group:"slack",effect:"live"},"slack.require_mention_channels":{type:"str",default:"",doc:"Channel IDs where @mention is ALWAYS required, even when require_mention is false globally (per-channel force-mention override).",group:"slack",effect:"live"},"slack.thread_require_mention":{type:"bool",default:!1,doc:"If True, require @mention in Slack thread replies too.",group:"slack",effect:"live"},"streaming.buffer_threshold":{type:"int",default:24,doc:"Flush the buffer to the platform once this many characters have accumulated, so short replies feel near-instant.",group:"streaming",effect:"live"},"streaming.cursor":{type:"str",default:" \u2589",doc:"Cursor glyph appended to the in-progress message while streaming.",group:"streaming",effect:"live"},"streaming.edit_interval":{type:"float",default:0.8,doc:"Minimum seconds between progressive edits \u2014 tuned for Telegram's ~1 edit/s flood envelope.",group:"streaming",effect:"live"},"streaming.enabled":{type:"bool",default:!1,doc:"Master switch. When false, each response is delivered as a single final message (no progressive updates).",group:"streaming",effect:"live"},"streaming.fresh_final_after_seconds":{type:"float",default:0,doc:"When >0, the final edit for a long-running streamed response is delivered as a fresh message if the preview has been visible at least this many seconds, so the platform timestamp reflects completion time. Telegram only; other platforms ignore it.",group:"streaming",effect:"live"},"streaming.transport":{type:"str",default:"auto",doc:`Transport selection: "auto" \u2014 prefer native draft streaming where the platform supports it (Telegram DMs via sendMessageDraft, Bot API 9.5+) and fall back to edit-based elsewhere. Safe global default: platforms without draft support (Discord, Slack, Matrix, Telegram groups) transparently use the edit path, so "auto" only upgrades chats that can render the smoother native preview. "draft" \u2014 explicitly request native drafts; falls back to edit when the platform/chat doesn't support them. "edit" \u2014 progressive editMessageText only (legacy behavior). "off" \u2014 disable streaming entirely (same as enabled: false).`,group:"streaming",effect:"live"},"stt.deepinfra.model":{type:"str",default:"",doc:"empty = first stt-tagged model from the live catalog",group:"stt",effect:"live"},"stt.echo_transcripts":{type:"bool",default:!0,doc:"When true, gateway voice messages are transcribed for the agent and the raw transcript is also echoed back to the user as a \uD83C\uDF99\uFE0F message. Set false to keep STT for the agent while suppressing that user-facing echo.",group:"stt",effect:"live"},"stt.elevenlabs.diarize":{type:"bool",default:!1,doc:"",group:"stt",effect:"live"},"stt.elevenlabs.language_code":{type:"str",default:"",doc:'auto-detect by default; set to "eng", "spa", "fra", etc. to force',group:"stt",effect:"live"},"stt.elevenlabs.model_id":{type:"str",default:"scribe_v2",doc:"scribe_v2, scribe_v1",group:"stt",effect:"live"},"stt.elevenlabs.tag_audio_events":{type:"bool",default:!1,doc:"",group:"stt",effect:"live"},"stt.enabled":{type:"bool",default:!0,doc:"",group:"stt",effect:"live"},"stt.groq.language":{type:"str",default:"",doc:'auto-detect by default; set to "en", "es", "fr", etc. to force',group:"stt",effect:"live"},"stt.groq.model":{type:"str",default:"whisper-large-v3-turbo",doc:"whisper-large-v3, whisper-large-v3-turbo, distil-whisper-large-v3-en",group:"stt",effect:"live"},"stt.language":{type:"str",default:"en",doc:'Global language hint applied to EVERY provider unless a per-provider language overrides it. Defaults to "en" \u2014 Whisper auto-detection frequently misidentifies short/accented clips, which reads as "STT transcribed the wrong language". Set to "" to restore auto-detect, or to your language code ("es", "zh", "uk", ...).',group:"stt",effect:"live"},"stt.local.initial_prompt":{type:"str",default:"",doc:"",group:"stt",effect:"live"},"stt.local.language":{type:"str",default:"",doc:'auto-detect by default; set to "en", "es", "fr", etc. to force',group:"stt",effect:"live"},"stt.local.model":{type:"str",default:"base",doc:"tiny, base, small, medium, large-v3",group:"stt",effect:"live"},"stt.mistral.language":{type:"str",default:"",doc:'auto-detect by default; set to "en", "es", "fr", etc. to force',group:"stt",effect:"live"},"stt.mistral.model":{type:"str",default:"voxtral-mini-latest",doc:"voxtral-mini-latest, voxtral-mini-2602",group:"stt",effect:"live"},"stt.openai.language":{type:"str",default:"",doc:'auto-detect by default; set to "en", "es", "fr", etc. to force',group:"stt",effect:"live"},"stt.openai.model":{type:"str",default:"whisper-1",doc:"whisper-1, gpt-4o-mini-transcribe, gpt-4o-transcribe",group:"stt",effect:"live"},"stt.provider":{type:"str",default:"local",doc:'"local" (free, faster-whisper) | "groq" | "openai" (Whisper API) | "mistral" (Voxtral Transcribe) | "elevenlabs" (Scribe) | "deepinfra"',group:"stt",effect:"live"},"stt.xai.language":{type:"str",default:"",doc:'auto-detect by default; set to "en", "es", "fr", etc. to force',group:"stt",effect:"live"},"telegram.allowed_chats":{type:"str",default:"",doc:"If set, bot ONLY responds in these group/supergroup chat IDs (whitelist)",group:"telegram",effect:"live"},"telegram.channel_prompts":{type:"dict",default:{},doc:"Per-chat/topic ephemeral system prompts (topics inherit from parent group)",group:"telegram",effect:"live"},"telegram.extra.rich_drafts":{type:"bool",default:!1,doc:"Experimental Bot API 10.1 rich draft previews during Telegram DM streaming. Default off because Telegram Desktop/macOS can visually overlay rich draft frames until the chat redraws.",group:"telegram",effect:"live"},"telegram.extra.rich_messages":{type:"bool",default:!1,doc:"Bot API 10.1 rich messages (tables/task lists/details/math) render natively; set True to opt in. Default stays legacy MarkdownV2 because rich messages can be hard to copy as plain text in Telegram clients.",group:"telegram",effect:"live"},"telegram.reactions":{type:"bool",default:!1,doc:"Add \uD83D\uDC40/\u2705/\u274C reactions to messages during processing",group:"telegram",effect:"live"},"terminal.auto_source_bashrc":{type:"bool",default:!0,doc:"When true (default), Hermes sources the user's shell rc files (``~/.profile``, ``~/.bash_profile``, ``~/.bashrc``) in the login shell used to build the environment snapshot. This captures PATH additions, shell functions, and aliases \u2014 which a plain ``bash -l -c`` would otherwise miss because bash skips bashrc in non-interactive login mode, and because a default Debian/Ubuntu ``~/.bashrc`` short-circuits on non-interactive sources. ``~/.profile`` and ``~/.bash_profile`` are tried first because ``n`` / ``nvm`` / ``asdf`` installers typically write their PATH exports there without an interactivity guard. Turn this off if your rc files misbehave when sourced non-interactively (e.g. one that hard-exits on TTY checks).",group:"terminal",effect:"restart"},"terminal.backend":{type:"str",default:"local",doc:"",group:"terminal",effect:"restart"},"terminal.container_cpu":{type:"int",default:1,doc:"Container resource limits (docker, singularity, modal, daytona \u2014 ignored for local/ssh)",group:"terminal",effect:"restart"},"terminal.container_disk":{type:"int",default:51200,doc:"MB (default 50GB)",group:"terminal",effect:"restart"},"terminal.container_memory":{type:"int",default:5120,doc:"MB (default 5GB)",group:"terminal",effect:"restart"},"terminal.container_persistent":{type:"bool",default:!0,doc:"Persist filesystem across sessions",group:"terminal",effect:"restart"},"terminal.cwd":{type:"str",default:".",doc:"Use current directory",group:"terminal",effect:"restart"},"terminal.daemon_term_grace_seconds":{type:"float",default:2,doc:"Bounded grace period (seconds) between SIGTERM and an escalated SIGKILL when terminating a host process tree (browser daemons, etc.). A daemon that stalls in its SIGTERM handler is force-killed after this window so it can't leak indefinitely. 0 disables escalation (SIGTERM only \u2014 the historical behavior). Floored internally at 0.",group:"terminal",effect:"restart"},"terminal.daytona_image":{type:"str",default:"nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.docker_env":{type:"dict",default:{},doc:`Explicit environment variables to set inside Docker containers. Unlike docker_forward_env (which reads values from the host process), docker_env lets you specify exact key-value pairs \u2014 useful when Hermes runs as a systemd service without access to the user's shell environment. Example: {"SSH_AUTH_SOCK": "/run/user/1000/ssh-agent.sock"}`,group:"terminal",effect:"restart"},"terminal.docker_extra_args":{type:"list",default:[],doc:"Extra flags passed verbatim to docker run",group:"terminal",effect:"restart"},"terminal.docker_forward_env":{type:"list",default:[],doc:"",group:"terminal",effect:"restart"},"terminal.docker_image":{type:"str",default:"nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.docker_mount_cwd_to_workspace":{type:"bool",default:!1,doc:"Explicit opt-in: mount the host cwd into /workspace for Docker sessions. Default off because passing host directories into a sandbox weakens isolation.",group:"terminal",effect:"restart"},"terminal.docker_network":{type:"bool",default:!0,doc:"Opt-in egress lockdown for Docker terminal sessions. When false, Docker runs with --network=none so commands cannot reach the network.",group:"terminal",effect:"restart"},"terminal.docker_run_as_host_user":{type:"bool",default:!1,doc:"Explicit opt-in: run the Docker container as the host user's uid:gid (via `--user`). When enabled, files written into bind-mounted dirs (docker_volumes, the persistent workspace, or the auto-mounted cwd) are owned by your host user instead of root, which avoids needing `sudo chown` after container runs. Default off to preserve behavior for images whose entrypoints expect to start as root (e.g. the bundled Hermes image, which drops to the `hermes` user via s6-setuidgid inside each supervised service). When on, SETUID/SETGID caps are omitted from the container since no privilege drop is needed.",group:"terminal",effect:"restart"},"terminal.docker_volumes":{type:"list",default:[],doc:'Docker volume mounts \u2014 share host directories with the container. Each entry is "host_path:container_path" (standard Docker -v syntax). Example: ["/home/user/projects:/workspace/projects", "/home/user/.hermes/cache/documents:/output"] For gateway MEDIA delivery, write inside Docker to /output/... and emit the host-visible path in MEDIA:, not the container path.',group:"terminal",effect:"restart"},"terminal.env_passthrough":{type:"list",default:[],doc:"Environment variables to pass through to sandboxed execution (terminal and execute_code). Skill-declared required_environment_variables are passed through automatically; this list is for non-skill use cases.",group:"terminal",effect:"restart"},"terminal.home_mode":{type:"str",default:"auto",doc:"HOME handling for host tool subprocesses: auto \u2014 host keeps the real OS-user HOME; containers use HERMES_HOME/home for persistent state (default) real \u2014 force the real OS-user HOME profile \u2014 force HERMES_HOME/home when it exists (old strict per-profile CLI config isolation)",group:"terminal",effect:"restart"},"terminal.modal_image":{type:"str",default:"nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.modal_mode":{type:"str",default:"auto",doc:"",group:"terminal",effect:"restart"},"terminal.persistent_shell":{type:"bool",default:!0,doc:"Persistent shell \u2014 keep a long-lived bash shell across execute() calls so cwd/env vars/shell variables survive between commands. Enabled by default for non-local backends (SSH); local is always opt-in via TERMINAL_LOCAL_PERSISTENT env var.",group:"terminal",effect:"restart"},"terminal.shell_init_files":{type:"list",default:[],doc:"Extra files to source in the login shell when building the per-session environment snapshot. Use this when tools like nvm, pyenv, asdf, or custom PATH entries are registered by files that a bash login shell would skip \u2014 most commonly ``~/.bashrc`` (bash doesn't source bashrc in non-interactive login mode) or zsh-specific files like ``~/.zshrc`` / ``~/.zprofile``. Paths support ``~`` / ``${VAR}``. Missing files are silently skipped. When empty, Hermes auto-sources ``~/.profile``, ``~/.bash_profile``, and ``~/.bashrc`` (in that order) if the snapshot shell is bash (this is the ``auto_source_bashrc`` behaviour \u2014 disable with that key if you want strict login-only semantics).",group:"terminal",effect:"restart"},"terminal.singularity_image":{type:"str",default:"docker://nikolaik/python-nodejs:python3.11-nodejs20",doc:"",group:"terminal",effect:"restart"},"terminal.timeout":{type:"int",default:180,doc:"",group:"terminal",effect:"restart"},timezone:{type:"str",default:"",doc:'IANA timezone (e.g. "Asia/Kolkata", "America/New_York"). Empty string means use server-local time.',group:"general",effect:"live"},"tool_loop_guardrails.hard_stop_after.exact_failure":{type:"int",default:5,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.hard_stop_after.idempotent_no_progress":{type:"int",default:5,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.hard_stop_after.same_tool_failure":{type:"int",default:8,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.hard_stop_enabled":{type:"bool",default:!1,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.loop_caps.max_subagents":{type:"int",default:50,doc:"max subagents spawned per turn (0 = unlimited)",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.loop_caps.max_web_searches":{type:"int",default:50,doc:"max web_search calls per turn (0 = unlimited)",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warn_after.exact_failure":{type:"int",default:2,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warn_after.idempotent_no_progress":{type:"int",default:2,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warn_after.same_tool_failure":{type:"int",default:3,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_loop_guardrails.warnings_enabled":{type:"bool",default:!0,doc:"",group:"tool_loop_guardrails",effect:"live"},"tool_output.max_bytes":{type:"int",default:50000,doc:"",group:"tool_output",effect:"live"},"tool_output.max_line_length":{type:"int",default:2000,doc:"",group:"tool_output",effect:"live"},"tool_output.max_lines":{type:"int",default:2000,doc:"",group:"tool_output",effect:"live"},"tools.tool_search.enabled":{type:"str",default:"auto",doc:`Tiered disclosure: any deferrable (MCP/plugin) tool activates the bridge; the listing then scales with catalog size. Tier 0 \u2014 no MCP/plugin tools: everything stays eager. Tier 1 \u2014 catalog listing fits the budget: bridge + skills-style name+description manifest (degrades to names-only). Tier 2 \u2014 per-tool listing over budget even names-only (e.g. Cloudflare's ~3,300-tool flat API surface): bare bridge + a one-line-per-server summary (name + tool count) so the model knows which domains are reachable; individual tools discoverable through tool_search only. "auto"/"on" \u2014 activate when at least one deferrable tool exists. "off" \u2014 disable entirely. Tools-array assembly is a pass-through.`,group:"tools",effect:"live"},"tools.tool_search.listing":{type:"str",default:"auto",doc:`Skills-style catalog listing embedded in the tool_search bridge description: every deferred tool's name + first sentence of its description (\u226460 chars), grouped by MCP server / toolset. Keeps capabilities discoverable while schemas stay deferred. "auto" (default) \u2014 include when the listing fits the budget (falls back to names-only, then to the bare tier-2 bridge). "on" \u2014 same rendering, but explicit intent to always list. "off" \u2014 always the bare bridge (tier 2 for every catalog).`,group:"tools",effect:"live"},"tools.tool_search.listing_max_tokens":{type:"int",default:20000,doc:"Absolute cap on the embedded listing in tokens (chars/4 estimate), regardless of context size. Range 200..60000.",group:"tools",effect:"live"},"tools.tool_search.max_search_limit":{type:"int",default:20,doc:"Hard upper bound the model can request via ``limit``. Range 1..50.",group:"tools",effect:"live"},"tools.tool_search.search_default_limit":{type:"int",default:5,doc:"When the model calls tool_search without a ``limit`` argument, how many hits to return. Range 1..max_search_limit.",group:"tools",effect:"live"},"tools.tool_search.threshold_pct":{type:"int",default:5,doc:"Listing budget as a percentage of the active model's context length. Effective budget = min(this % of context, listing_max_tokens). Range 0..100.",group:"tools",effect:"live"},toolsets:{type:"list",default:["hermes-cli"],doc:"",group:"general",effect:"restart"},"tts.deepinfra.model":{type:"str",default:"",doc:"empty = first tts-tagged model from the live catalog",group:"tts",effect:"live"},"tts.deepinfra.voice":{type:"str",default:"default",doc:"",group:"tts",effect:"live"},"tts.edge.voice":{type:"str",default:"en-US-AriaNeural",doc:"",group:"tts",effect:"live"},"tts.elevenlabs.model_id":{type:"str",default:"eleven_multilingual_v2",doc:"",group:"tts",effect:"live"},"tts.elevenlabs.voice_id":{type:"str",default:"pNInz6obpgDQGcFmaJgB",doc:"Adam",group:"tts",effect:"live"},"tts.gemini.audio_tags":{type:"bool",default:!1,doc:"When true, Gemini 3.1 TTS uses a hidden auxiliary-model rewrite pass to insert freeform square-bracket audio tags into the TTS script. Visible chat replies are unchanged.",group:"tts",effect:"live"},"tts.gemini.model":{type:"str",default:"gemini-2.5-flash-preview-tts",doc:"",group:"tts",effect:"live"},"tts.gemini.persona_prompt_file":{type:"str",default:"",doc:"Optional local Markdown/text file with Gemini TTS performance direction. It may include AUDIO PROFILE, SCENE, DIRECTOR'S NOTES, SAMPLE CONTEXT, and either a `{transcript}` placeholder or no transcript section; Hermes appends the live transcript when absent.",group:"tts",effect:"live"},"tts.gemini.voice":{type:"str",default:"Kore",doc:"",group:"tts",effect:"live"},"tts.kittentts.model":{type:"str",default:"KittenML/kitten-tts-nano-0.8-int8",doc:"nano 25MB; micro 41MB; mini 80MB",group:"tts",effect:"live"},"tts.kittentts.voice":{type:"str",default:"Jasper",doc:"",group:"tts",effect:"live"},"tts.minimax.model":{type:"str",default:"speech-02-hd",doc:"",group:"tts",effect:"live"},"tts.minimax.voice_id":{type:"str",default:"English_expressive_narrator",doc:"",group:"tts",effect:"live"},"tts.mistral.model":{type:"str",default:"voxtral-mini-tts-2603",doc:"",group:"tts",effect:"live"},"tts.mistral.voice_id":{type:"str",default:"c69964a6-ab8b-4f8a-9465-ec0925096ec8",doc:"Paul - Neutral",group:"tts",effect:"live"},"tts.neutts.device":{type:"str",default:"cpu",doc:"cpu, cuda, or mps",group:"tts",effect:"live"},"tts.neutts.model":{type:"str",default:"neuphonic/neutts-air-q4-gguf",doc:"HuggingFace model repo",group:"tts",effect:"live"},"tts.neutts.ref_audio":{type:"str",default:"",doc:"Path to reference voice audio (empty = bundled default)",group:"tts",effect:"live"},"tts.neutts.ref_text":{type:"str",default:"",doc:"Path to reference voice transcript (empty = bundled default)",group:"tts",effect:"live"},"tts.openai.model":{type:"str",default:"gpt-4o-mini-tts",doc:"",group:"tts",effect:"live"},"tts.openai.voice":{type:"str",default:"alloy",doc:"",group:"tts",effect:"live"},"tts.piper.voice":{type:"str",default:"en_US-lessac-medium",doc:'Voice name (e.g. "en_US-lessac-medium") downloaded on first use, OR an absolute path to a pre-downloaded .onnx file. Full voice list: https://github.com/OHF-Voice/piper1-gpl/blob/main/docs/VOICES.md',group:"tts",effect:"live"},"tts.provider":{type:"str",default:"edge",doc:'Set explicitly to pin a backend: "edge" (free) | "elevenlabs" (premium) | "openai" | "xai" | "minimax" | "mistral" | "gemini" | "deepinfra" | "neutts" (local) | "kittentts" (local) | "piper" (local)',group:"tts",effect:"live"},"tts.xai.auto_speech_tags":{type:"bool",default:!1,doc:"insert expressive audio tags via LLM rewrite",group:"tts",effect:"live"},"tts.xai.bit_rate":{type:"int",default:128000,doc:"MP3 bitrate; only applies when codec=mp3",group:"tts",effect:"live"},"tts.xai.language":{type:"str",default:"en",doc:'BCP-47 code ("en", "pt-BR") or "auto"',group:"tts",effect:"live"},"tts.xai.optimize_streaming_latency":{type:"int",default:0,doc:"0\u20132, trades quality for lower latency",group:"tts",effect:"live"},"tts.xai.sample_rate":{type:"int",default:24000,doc:"22050 / 24000 / 44100 / 48000",group:"tts",effect:"live"},"tts.xai.speed":{type:"float",default:1,doc:"0.7\u20131.5, playback speed",group:"tts",effect:"live"},"tts.xai.voice_id":{type:"str",default:"eve",doc:"or custom voice ID \u2014 see https://docs.x.ai/developers/model-capabilities/audio/custom-voices",group:"tts",effect:"live"},"updates.backup_keep":{type:"int",default:5,doc:"How many full pre-update backup zips to retain (mode ``full``). Older ones are pruned automatically after each successful backup. Values below 1 are floored to 1 \u2014 the backup just created is always preserved. The quick snapshot always keeps exactly 1.",group:"updates",effect:"live"},"updates.non_interactive_local_changes":{type:"str",default:"stash",doc:'What `hermes update` does with uncommitted local changes to the source tree when it runs NON-interactively \u2014 i.e. triggered from the desktop/chat app or the gateway, where there\'s no TTY to answer a restore prompt. Interactive (terminal) updates are unaffected: they always stash the changes and ask whether to restore, exactly as they always have. "stash" \u2014 auto-stash the changes, pull, then auto-restore them on top of the updated code (the safe default; nothing is ever lost \u2014 conflicts are preserved in a git stash). "discard" \u2014 auto-stash the changes and throw the stash away after the pull. Use this only if you never intend to keep local edits to the source tree on this machine. Stash-and-drop (not `reset --hard` + `clean -fd`) so ignored paths \u2014 node_modules, venv, build outputs \u2014 are never touched.',group:"updates",effect:"live"},"updates.pre_update_backup":{type:"str",default:"quick",doc:"Pre-update safety backup \u2014 ONE consolidated mechanism, three modes: quick (default) \u2014 snapshot critical small state files (pairing JSONs, cron jobs, config.yaml, .env, auth.json, per-profile DBs) into <HERMES_HOME>/state-snapshots/ before the update. Files over 1 GiB (e.g. a bloated state.db) are skipped with a warning so the snapshot stays fast. Restore via ``/snapshot``. This is the #15733 (lost pairing data) / #34600 (emptied cron jobs) safety net. full \u2014 the quick snapshot PLUS a full ``hermes backup``-style zip of HERMES_HOME into <HERMES_HOME>/backups/, restorable with ``hermes import``. Can add minutes on large homes. This is the #48200 (wrong-path wipe) safety net. ``--backup`` forces this for a single run. off \u2014 no pre-update backup of any kind. ``--no-backup`` forces this for a single run. Legacy boolean values are honored: true -> full, false -> off.",group:"updates",effect:"live"},"updates.refresh_cua_driver":{type:"bool",default:!0,doc:"Refresh an already-installed cua-driver during `hermes update`. The refresh is best-effort and macOS-only. Turn this off if the upstream installer is not appropriate for the machine, for example on non-admin accounts where `/Applications` is not writable.",group:"updates",effect:"live"},"vertex.project_id":{type:"str",default:"",doc:"GCP project ID. Empty \u2192 use the project_id embedded in the service account JSON (or ADC-resolved project).",group:"vertex",effect:"live"},"vertex.region":{type:"str",default:"global",doc:'Vertex region. "global" is required for the Gemini 3.x preview models (regional endpoints silently 404 them). Override to a regional value (e.g. "us-central1") only if your models are pinned to a region.',group:"vertex",effect:"live"},"voice.auto_tts":{type:"bool",default:!1,doc:"",group:"voice",effect:"live"},"voice.barge_in":{type:"bool",default:!0,doc:"Stop TTS playback when the user starts talking",group:"voice",effect:"live"},"voice.beep_enabled":{type:"bool",default:!0,doc:"Play record start/stop beeps in CLI voice mode",group:"voice",effect:"live"},"voice.max_recording_seconds":{type:"int",default:120,doc:"",group:"voice",effect:"live"},"voice.record_key":{type:"str",default:"ctrl+b",doc:"",group:"voice",effect:"live"},"voice.silence_duration":{type:"float",default:3,doc:"Seconds of silence before auto-stop",group:"voice",effect:"live"},"voice.silence_threshold":{type:"int",default:200,doc:"RMS below this = silence (0-32767)",group:"voice",effect:"live"},"voice.stop_phrases":{type:"list",default:["stop"],doc:"Saying EXACTLY one of these phrases (and nothing else) ends the voice chat instead of being sent to the agent. Case-insensitive, surrounding punctuation ignored. Set [] to disable.",group:"voice",effect:"live"},"web.backend":{type:"str",default:"",doc:"shared fallback \u2014 applies to both search and extract",group:"web",effect:"live"},"web.extract_backend":{type:"str",default:"",doc:'per-capability override for web_extract (e.g. "native")',group:"web",effect:"live"},"web.extract_char_limit":{type:"int",default:15000,doc:"per-page char budget for web_extract; larger pages truncate + store full text in cache/web",group:"web",effect:"live"},"web.search_backend":{type:"str",default:"",doc:'per-capability override for web_search (e.g. "searxng")',group:"web",effect:"live"},whatsapp:{type:"dict",default:{},doc:"WhatsApp platform settings (gateway mode)",group:"general",effect:"live"},"x_search.model":{type:"str",default:"grok-4.5",doc:"xAI model used for the Responses call. grok-4.5 is the recommended default; any Grok model with x_search tool access works.",group:"x_search",effect:"live"},"x_search.reasoning_effort":{type:"null",default:null,doc:"Optional reasoning effort sent to xAI Responses API models that support it. Leave null to preserve the selected model's default.",group:"x_search",effect:"live"},"x_search.retries":{type:"int",default:2,doc:"Number of automatic retries on 5xx / ReadTimeout / ConnectionError. Each retry backs off (1.5x attempt seconds, capped at 5s).",group:"x_search",effect:"live"},"x_search.timeout_seconds":{type:"int",default:180,doc:"Request timeout in seconds (minimum 30). x_search can take 60-120s for complex queries \u2014 the default is generous.",group:"x_search",effect:"live"}},SCHEMA_KEYS=Object.keys(SCHEMA),APPROVAL_MODES=["manual","smart","off"]});var exports_lane={};__export(exports_lane,{writeConfig:()=>writeConfig,verifyWrite:()=>verifyWrite,toCliString:()=>toCliString,route:()=>route,maxEffect:()=>maxEffect,TOOL_PROGRESS:()=>TOOL_PROGRESS,RPC_ALIAS:()=>RPC_ALIAS});var onOff=(v2)=>v2?"on":"off",TOOL_PROGRESS,progress,progressErr="log is a gateway-only config-file mode, not a live TUI mode",RPC_ALIAS,route=(key3)=>{let a=RPC_ALIAS[key3];if(a)return{via:"rpc",alias:a.alias,toWire:a.toWire};if(key3.startsWith("display.sections."))return{via:"rpc",alias:`details_mode.${key3.slice(17)}`};let s=SCHEMA[key3];if(s&&(s.type==="list"||s.type==="dict"))return{via:"readonly"};return{via:"cli"}},toCliString=(key3,v2)=>{let t2=SCHEMA[key3]?.type??"str";if(t2==="bool")return v2?"true":"false";if(t2==="int")return String(Math.trunc(Number(v2)));if(t2==="float")return String(Number(v2));return String(v2??"")},writeConfig=async(gw,diffs)=>{let ok=[],failed=[],warnings=[],blocked=diffs.filter((d2)=>d2.key==="display.tool_progress"&&!progress.has(String(d2.to??"")));for(let d2 of blocked)failed.push({key:d2.key,err:progressErr});let safe2=diffs.filter((d2)=>!blocked.includes(d2)),rpc=safe2.filter((d2)=>route(d2.key).via==="rpc"),cli=safe2.filter((d2)=>route(d2.key).via==="cli"),ro=safe2.filter((d2)=>route(d2.key).via==="readonly");for(let d2 of ro)failed.push({key:d2.key,err:"structured value \u2014 edit in YAML mode"});for(let d2 of rpc){let lane=route(d2.key),value=lane.toWire?lane.toWire(d2.to):String(d2.to??"");try{let res=await gw.request("config.set",{key:lane.alias,value});if(ok.push(d2.key),res?.warning)warnings.push({key:d2.key,msg:res.warning})}catch(e){failed.push({key:d2.key,err:e instanceof Error?e.message:String(e)})}}for(let d2 of cli)try{let res=await gw.request("cli.exec",{argv:["config","set",d2.key,toCliString(d2.key,d2.to)],timeout:30});if(res.blocked)failed.push({key:d2.key,err:res.hint??"blocked"});else if(res.code!==0)failed.push({key:d2.key,err:res.output.split(`
3511
+ `)[0]||`exit ${res.code}`});else ok.push(d2.key)}catch(e){failed.push({key:d2.key,err:e instanceof Error?e.message:String(e)})}return{ok,failed,warnings}},EFFECT_RANK,maxEffect=(keys)=>keys.reduce((acc,k2)=>{let e=SCHEMA[k2]?.effect??"live";return EFFECT_RANK[e]>EFFECT_RANK[acc]?e:acc},"live"),get3=(obj,path4)=>{let cur=obj;for(let p of path4.split("."))if(cur&&typeof cur==="object"&&!Array.isArray(cur))cur=cur[p];else return;return cur},eq2=(a,b2)=>JSON.stringify(a)===JSON.stringify(b2),verifyWrite=async(gw,applied)=>{let cfg=(await gw.request("config.get",{key:"full"})).config??{},miss=[];for(let d2 of applied){if(route(d2.key).via!=="cli")continue;if(!eq2(get3(cfg,d2.key),d2.to))miss.push(d2.key)}return miss};var init_lane=__esm(()=>{init_schema();TOOL_PROGRESS=["off","new","all","verbose"],progress=new Set(TOOL_PROGRESS),RPC_ALIAS={model:{alias:"model"},provider:{alias:"model"},"agent.service_tier":{alias:"fast"},"agent.reasoning_effort":{alias:"reasoning"},"display.show_reasoning":{alias:"reasoning",toWire:(v2)=>v2?"show":"hide"},"display.tool_progress":{alias:"verbose"},"display.busy_input_mode":{alias:"busy"},"display.details_mode":{alias:"details_mode"},"display.thinking_mode":{alias:"thinking_mode"},"display.tui_compact":{alias:"compact",toWire:onOff},"display.tui_statusbar":{alias:"statusbar"},"display.tui_mouse":{alias:"mouse",toWire:onOff},"display.skin":{alias:"skin"},"display.personality":{alias:"personality"},"approvals.mode":{alias:"approval_mode"},custom_prompt:{alias:"prompt"}},EFFECT_RANK={live:0,session:1,restart:2}});import{createRequire as createRequire2}from"module";import{fileURLToPath}from"url";import{existsSync}from"fs";import{mkdir,writeFile as writeFileNode}from"fs/promises";import{dirname,isAbsolute,resolve}from"path";import{fileURLToPath as fileURLToPath2}from"url";import{existsSync as existsSync3,writeFileSync}from"fs";import{EventEmitter as EventEmitter4}from"events";import{EventEmitter}from"events";import{Buffer as Buffer2}from"buffer";import{Buffer as Buffer3}from"buffer";import{EventEmitter as EventEmitter2}from"events";import{resolve as resolve2,isAbsolute as isAbsolute2,parse}from"path";import{existsSync as existsSync2}from"fs";import{basename,join}from"path";import os from"os";import path from"path";import{EventEmitter as EventEmitter3}from"events";import path2 from"path";var{create:__create2,getPrototypeOf:__getProtoOf2,defineProperty:__defProp2,getOwnPropertyNames:__getOwnPropNames2}=Object,__hasOwnProp2=Object.prototype.hasOwnProperty;function __accessProp2(key){return this[key]}var __toESMCache_node2,__toESMCache_esm2,__toESM2=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node2??=new WeakMap:__toESMCache_esm2??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create2(__getProtoOf2(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp2(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames2(mod))if(!__hasOwnProp2.call(to,key))__defProp2(to,key,{get:__accessProp2.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__commonJS2=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports),__returnValue2=(v)=>v;function __exportSetter2(name,newValue){this[name]=__returnValue2.bind(null,newValue)}var __export2=(target,all)=>{for(var name in all)__defProp2(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter2.bind(all,name)})};var require_emoji_regex=__commonJS2((exports,module)=>{module.exports=()=>{return/[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g}}),exports_yoga={};__export2(exports_yoga,{default:()=>yoga_default,Wrap:()=>Wrap,WRAP_WRAP_REVERSE:()=>WRAP_WRAP_REVERSE,WRAP_WRAP:()=>WRAP_WRAP,WRAP_NO_WRAP:()=>WRAP_NO_WRAP,Unit:()=>Unit,UNIT_UNDEFINED:()=>UNIT_UNDEFINED,UNIT_POINT:()=>UNIT_POINT,UNIT_PERCENT:()=>UNIT_PERCENT,UNIT_AUTO:()=>UNIT_AUTO,PositionType:()=>PositionType,POSITION_TYPE_STATIC:()=>POSITION_TYPE_STATIC,POSITION_TYPE_RELATIVE:()=>POSITION_TYPE_RELATIVE,POSITION_TYPE_ABSOLUTE:()=>POSITION_TYPE_ABSOLUTE,Overflow:()=>Overflow,OVERFLOW_VISIBLE:()=>OVERFLOW_VISIBLE,OVERFLOW_SCROLL:()=>OVERFLOW_SCROLL,OVERFLOW_HIDDEN:()=>OVERFLOW_HIDDEN,NodeType:()=>NodeType,Node:()=>Node,NODE_TYPE_TEXT:()=>NODE_TYPE_TEXT,NODE_TYPE_DEFAULT:()=>NODE_TYPE_DEFAULT,MeasureMode:()=>MeasureMode,MEASURE_MODE_UNDEFINED:()=>MEASURE_MODE_UNDEFINED,MEASURE_MODE_EXACTLY:()=>MEASURE_MODE_EXACTLY,MEASURE_MODE_AT_MOST:()=>MEASURE_MODE_AT_MOST,LogLevel:()=>LogLevel,LOG_LEVEL_WARN:()=>LOG_LEVEL_WARN,LOG_LEVEL_VERBOSE:()=>LOG_LEVEL_VERBOSE,LOG_LEVEL_INFO:()=>LOG_LEVEL_INFO,LOG_LEVEL_FATAL:()=>LOG_LEVEL_FATAL,LOG_LEVEL_ERROR:()=>LOG_LEVEL_ERROR,LOG_LEVEL_DEBUG:()=>LOG_LEVEL_DEBUG,Justify:()=>Justify,JUSTIFY_SPACE_EVENLY:()=>JUSTIFY_SPACE_EVENLY,JUSTIFY_SPACE_BETWEEN:()=>JUSTIFY_SPACE_BETWEEN,JUSTIFY_SPACE_AROUND:()=>JUSTIFY_SPACE_AROUND,JUSTIFY_FLEX_START:()=>JUSTIFY_FLEX_START,JUSTIFY_FLEX_END:()=>JUSTIFY_FLEX_END,JUSTIFY_CENTER:()=>JUSTIFY_CENTER,Gutter:()=>Gutter,GUTTER_ROW:()=>GUTTER_ROW,GUTTER_COLUMN:()=>GUTTER_COLUMN,GUTTER_ALL:()=>GUTTER_ALL,FlexDirection:()=>FlexDirection,FLEX_DIRECTION_ROW_REVERSE:()=>FLEX_DIRECTION_ROW_REVERSE,FLEX_DIRECTION_ROW:()=>FLEX_DIRECTION_ROW,FLEX_DIRECTION_COLUMN_REVERSE:()=>FLEX_DIRECTION_COLUMN_REVERSE,FLEX_DIRECTION_COLUMN:()=>FLEX_DIRECTION_COLUMN,ExperimentalFeature:()=>ExperimentalFeature,Errata:()=>Errata,Edge:()=>Edge,EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS:()=>EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS,ERRATA_STRETCH_FLEX_BASIS:()=>ERRATA_STRETCH_FLEX_BASIS,ERRATA_NONE:()=>ERRATA_NONE,ERRATA_CLASSIC:()=>ERRATA_CLASSIC,ERRATA_ALL:()=>ERRATA_ALL,ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING:()=>ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING,ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE:()=>ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE,EDGE_VERTICAL:()=>EDGE_VERTICAL,EDGE_TOP:()=>EDGE_TOP,EDGE_START:()=>EDGE_START,EDGE_RIGHT:()=>EDGE_RIGHT,EDGE_LEFT:()=>EDGE_LEFT,EDGE_HORIZONTAL:()=>EDGE_HORIZONTAL,EDGE_END:()=>EDGE_END,EDGE_BOTTOM:()=>EDGE_BOTTOM,EDGE_ALL:()=>EDGE_ALL,Display:()=>Display,Direction:()=>Direction,Dimension:()=>Dimension,DISPLAY_NONE:()=>DISPLAY_NONE,DISPLAY_FLEX:()=>DISPLAY_FLEX,DISPLAY_CONTENTS:()=>DISPLAY_CONTENTS,DIRECTION_RTL:()=>DIRECTION_RTL,DIRECTION_LTR:()=>DIRECTION_LTR,DIRECTION_INHERIT:()=>DIRECTION_INHERIT,DIMENSION_WIDTH:()=>DIMENSION_WIDTH,DIMENSION_HEIGHT:()=>DIMENSION_HEIGHT,Config:()=>Config,BoxSizing:()=>BoxSizing,BOX_SIZING_CONTENT_BOX:()=>BOX_SIZING_CONTENT_BOX,BOX_SIZING_BORDER_BOX:()=>BOX_SIZING_BORDER_BOX,Align:()=>Align,ALIGN_STRETCH:()=>ALIGN_STRETCH,ALIGN_SPACE_EVENLY:()=>ALIGN_SPACE_EVENLY,ALIGN_SPACE_BETWEEN:()=>ALIGN_SPACE_BETWEEN,ALIGN_SPACE_AROUND:()=>ALIGN_SPACE_AROUND,ALIGN_FLEX_START:()=>ALIGN_FLEX_START,ALIGN_FLEX_END:()=>ALIGN_FLEX_END,ALIGN_CENTER:()=>ALIGN_CENTER,ALIGN_BASELINE:()=>ALIGN_BASELINE,ALIGN_AUTO:()=>ALIGN_AUTO});var FFIType={char:"char",int8_t:"int8_t",i8:"i8",uint8_t:"uint8_t",u8:"u8",int16_t:"int16_t",i16:"i16",uint16_t:"uint16_t",u16:"u16",int32_t:"int32_t",i32:"i32",int:"int",uint32_t:"uint32_t",u32:"u32",int64_t:"int64_t",i64:"i64",uint64_t:"uint64_t",u64:"u64",double:"double",f64:"f64",float:"float",f32:"f32",bool:"bool",ptr:"ptr",pointer:"pointer",void:"void",cstring:"cstring",function:"function",usize:"usize",callback:"callback",napi_env:"napi_env",napi_value:"napi_value",buffer:"buffer"},FFI_UNAVAILABLE="OpenTUI native FFI is not available for this runtime yet",BUN_DLOPEN_NULL="Bun FFI backend does not support dlopen(null)",LIBRARY_CLOSED="Cannot create FFI callback after library.close() has been called",NODE_CALLBACK_THREADSAFE="Node FFI callbacks are same-thread only and do not support threadsafe callbacks",NODE_NAPI_UNSUPPORTED="Node FFI backend does not support Bun N-API FFI types",NODE_POINTER_OVERRIDE="Node FFI backend does not support FFIFunction.ptr overrides",NODE_POINTER_ARGUMENT="Node FFI pointer arguments must be a Pointer, ArrayBuffer, or ArrayBufferView",NODE_PTR_VALUE="node:ffi ptr() only supports ArrayBuffer and ArrayBufferView values backed by ArrayBuffer",NODE_STRING_RETURN="Node FFI backend does not normalize string return values (yet)",NODE_USIZE_UNSUPPORTED="Node FFI backend does not support usize yet",POINTER_NEGATIVE="Pointer must be non-negative",POINTER_OFFSET_NEGATIVE="Pointer offset must be non-negative",POINTER_OFFSET_UNSAFE="Pointer offset must be a safe integer",POINTER_UNSAFE="Pointer exceeds safe integer range";function unavailable(cause){throw Error(FFI_UNAVAILABLE,{cause})}function createUnsupportedBackend(cause){return{dlopen(){return unavailable(cause)},ptr(){return unavailable(cause)},suffix:"",toArrayBuffer(){return unavailable(cause)}}}var isBun=typeof process<"u"&&typeof process.versions==="object"&&process.versions!==null&&typeof process.versions.bun==="string",requireModule=createRequire2(import.meta.url),backend=loadBackend();function loadBackend(){if(isBun)return createBunBackend(requireModule("bun:ffi"));try{let nodeFfi=requireModule("node:ffi");return createNodeBackend(nodeFfi.default??nodeFfi)}catch(error){return createUnsupportedBackend(error)}}function toPointer(value){if(isBun&&typeof value==="bigint")return toSafeNumberPointer(value);if(!isBun&&typeof value==="number")return toSafeBigIntPointer(value);return value}function ffiBool(value){return value?1:0}function toSafeNumberPointer(pointer){if(pointer<0n)throw Error(POINTER_NEGATIVE);if(pointer>BigInt(Number.MAX_SAFE_INTEGER))throw Error(POINTER_UNSAFE);return Number(pointer)}function toSafeBigIntPointer(pointer){if(pointer<0)throw Error(POINTER_NEGATIVE);if(!Number.isSafeInteger(pointer))throw Error(POINTER_UNSAFE);return BigInt(pointer)}function createManagedCallback(raw,callbacks){let ptr=raw.ptr,closed=!1,instance={get ptr(){return ptr},get threadsafe(){return raw.threadsafe},close(){if(closed)return;closed=!0,callbacks.delete(instance);try{raw.close()}finally{ptr=null}}};return callbacks.add(instance),instance}function normalizeBunDefinitions(definitions){return Object.fromEntries(Object.entries(definitions).map(([name,definition])=>[name,normalizeBunDefinition(definition)]))}function normalizeBunDefinition(definition){return{args:definition.args,returns:definition.returns,ptr:definition.ptr==null?void 0:toBunPointer(definition.ptr),threadsafe:definition.threadsafe}}function toBunPointer(pointer){return typeof pointer==="bigint"?toSafeNumberPointer(pointer):pointer}function createBunBackend(bun){return{dlopen(path3,symbols){if(path3===null)throw Error(BUN_DLOPEN_NULL);let library=bun.dlopen(path3,normalizeBunDefinitions(symbols)),callbacks=new Set,closed=!1;return{symbols:library.symbols,createCallback(callback,definition){if(closed)throw Error(LIBRARY_CLOSED);let raw=new bun.JSCallback(callback,normalizeBunDefinition(definition));return createManagedCallback(raw,callbacks)},close(){if(closed)return;closed=!0;try{library.close()}finally{for(let callback of[...callbacks])callback.close()}}}},ptr:bun.ptr,suffix:bun.suffix,toArrayBuffer(pointer,offset,length){return bun.toArrayBuffer(toBunPointer(pointer),offset,length)}}}function createNodeBackend(nodeFfi){return{dlopen(path3,symbols){let{lib,functions}=nodeFfi.dlopen(toNodeLibraryPath(path3),normalizeNodeDefinitions(symbols)),callbacks=new Set,closed=!1,libraryClosed=!1;return{symbols:wrapNodeSymbols(functions,symbols),createCallback(callback,definition){if(closed)throw Error(LIBRARY_CLOSED);if(definition.threadsafe)throw Error(NODE_CALLBACK_THREADSAFE);let callbackPointer=lib.registerCallback(normalizeNodeDefinition(definition),callback);return createManagedCallback({ptr:callbackPointer,threadsafe:!1,close(){if(!libraryClosed)lib.unregisterCallback(callbackPointer)}},callbacks)},close(){if(closed)return;closed=!0;try{libraryClosed=!0,lib.close()}finally{for(let callback of[...callbacks])callback.close()}}}},ptr(value){return toNodeSourcePointer(nodeFfi,value)},suffix:nodeFfi.suffix,toArrayBuffer(pointer,offset,length){return nodeFfi.toArrayBuffer(toBigIntPointer(pointer)+toNodePointerOffset(offset),length,!1)}}}function toNodeLibraryPath(path3){return path3 instanceof URL?fileURLToPath(path3):path3}function normalizeNodeDefinitions(definitions){return Object.fromEntries(Object.entries(definitions).map(([name,definition])=>[name,normalizeNodeDefinition(definition)]))}function wrapNodeSymbols(functions,definitions){return Object.fromEntries(Object.entries(functions).map(([name,fn])=>[name,wrapNodeSymbol(fn,definitions[name])]))}function wrapNodeSymbol(fn,definition){let pointerArgIndexes=(definition.args??[]).flatMap((type,index)=>isNodePointerArgumentType(type)?[index]:[]);if(pointerArgIndexes.length===0)return fn;return(...args)=>{let normalizedArgs=args.slice();for(let index of pointerArgIndexes)normalizedArgs[index]=toNodePointerArgument(normalizedArgs[index]);return fn(...normalizedArgs)}}function isNodePointerArgumentType(type){return type===FFIType.ptr||type===FFIType.pointer||type===FFIType.function||type===FFIType.callback}function toNodePointerArgument(value){if(value==null)return 0n;if(typeof value==="number"||typeof value==="bigint")return toBigIntPointer(value);if(ArrayBuffer.isView(value)){if(!(value.buffer instanceof ArrayBuffer))throw TypeError(NODE_PTR_VALUE);if(value.byteLength===0)return 0n;return value}if(value instanceof ArrayBuffer){if(value.byteLength===0)return 0n;return value}throw TypeError(NODE_POINTER_ARGUMENT)}function toNodeSourcePointer(nodeFfi,value){if(ArrayBuffer.isView(value)){if(!(value.buffer instanceof ArrayBuffer))throw TypeError(NODE_PTR_VALUE);return nodeFfi.getRawPointer(value.buffer)+BigInt(value.byteOffset)}if(value instanceof ArrayBuffer)return nodeFfi.getRawPointer(value);throw TypeError(NODE_PTR_VALUE)}function toNodePointerOffset(offset){if(offset==null)return 0n;if(offset<0)throw Error(POINTER_OFFSET_NEGATIVE);if(!Number.isSafeInteger(offset))throw Error(POINTER_OFFSET_UNSAFE);return BigInt(offset)}function normalizeNodeDefinition(definition){if(definition.ptr!=null)throw Error(NODE_POINTER_OVERRIDE);return{arguments:(definition.args??[]).map((type)=>toNodeFFIType(type,"parameter")),return:toNodeFFIType(definition.returns??FFIType.void,"result")}}function toNodeFFIType(type,position){switch(type){case FFIType.char:return"char";case FFIType.int8_t:case FFIType.i8:return"i8";case FFIType.uint8_t:case FFIType.u8:return"u8";case FFIType.int16_t:case FFIType.i16:return"i16";case FFIType.uint16_t:case FFIType.u16:return"u16";case FFIType.int32_t:case FFIType.int:case FFIType.i32:return"i32";case FFIType.uint32_t:case FFIType.u32:return"u32";case FFIType.int64_t:case FFIType.i64:return"i64";case FFIType.uint64_t:case FFIType.u64:return"u64";case FFIType.double:case FFIType.f64:return"f64";case FFIType.float:case FFIType.f32:return"f32";case FFIType.bool:return"bool";case FFIType.ptr:case FFIType.pointer:return"pointer";case FFIType.void:return"void";case FFIType.cstring:if(position==="result")throw Error(NODE_STRING_RETURN);return"string";case FFIType.function:case FFIType.callback:return"pointer";case FFIType.usize:throw Error(NODE_USIZE_UNSUPPORTED);case FFIType.napi_env:case FFIType.napi_value:throw Error(NODE_NAPI_UNSUPPORTED);case FFIType.buffer:return"buffer";default:return unsupportedNodeFFIType(type)}}function unsupportedNodeFFIType(type){throw Error(`Unsupported FFIType for node:ffi: ${String(type)}`)}function toBigIntPointer(pointer){if(typeof pointer==="bigint"){if(pointer<0n)throw Error(POINTER_NEGATIVE);return pointer}return toSafeBigIntPointer(pointer)}var{dlopen,ptr,suffix,toArrayBuffer}=backend;function ansiRegex({onlyFirst=!1}={}){return new RegExp("(?:\\u001B\\][\\s\\S]*?(?:\\u0007|\\u001B\\u005C|\\u009C))|[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]",onlyFirst?void 0:"g")}var regex=ansiRegex();function stripAnsi(string){if(typeof string!=="string")throw TypeError(`Expected a \`string\`, got \`${typeof string}\``);return string.replace(regex,"")}function isAmbiguous(x){return x===161||x===164||x===167||x===168||x===170||x===173||x===174||x>=176&&x<=180||x>=182&&x<=186||x>=188&&x<=191||x===198||x===208||x===215||x===216||x>=222&&x<=225||x===230||x>=232&&x<=234||x===236||x===237||x===240||x===242||x===243||x>=247&&x<=250||x===252||x===254||x===257||x===273||x===275||x===283||x===294||x===295||x===299||x>=305&&x<=307||x===312||x>=319&&x<=322||x===324||x>=328&&x<=331||x===333||x===338||x===339||x===358||x===359||x===363||x===462||x===464||x===466||x===468||x===470||x===472||x===474||x===476||x===593||x===609||x===708||x===711||x>=713&&x<=715||x===717||x===720||x>=728&&x<=731||x===733||x===735||x>=768&&x<=879||x>=913&&x<=929||x>=931&&x<=937||x>=945&&x<=961||x>=963&&x<=969||x===1025||x>=1040&&x<=1103||x===1105||x===8208||x>=8211&&x<=8214||x===8216||x===8217||x===8220||x===8221||x>=8224&&x<=8226||x>=8228&&x<=8231||x===8240||x===8242||x===8243||x===8245||x===8251||x===8254||x===8308||x===8319||x>=8321&&x<=8324||x===8364||x===8451||x===8453||x===8457||x===8467||x===8470||x===8481||x===8482||x===8486||x===8491||x===8531||x===8532||x>=8539&&x<=8542||x>=8544&&x<=8555||x>=8560&&x<=8569||x===8585||x>=8592&&x<=8601||x===8632||x===8633||x===8658||x===8660||x===8679||x===8704||x===8706||x===8707||x===8711||x===8712||x===8715||x===8719||x===8721||x===8725||x===8730||x>=8733&&x<=8736||x===8739||x===8741||x>=8743&&x<=8748||x===8750||x>=8756&&x<=8759||x===8764||x===8765||x===8776||x===8780||x===8786||x===8800||x===8801||x>=8804&&x<=8807||x===8810||x===8811||x===8814||x===8815||x===8834||x===8835||x===8838||x===8839||x===8853||x===8857||x===8869||x===8895||x===8978||x>=9312&&x<=9449||x>=9451&&x<=9547||x>=9552&&x<=9587||x>=9600&&x<=9615||x>=9618&&x<=9621||x===9632||x===9633||x>=9635&&x<=9641||x===9650||x===9651||x===9654||x===9655||x===9660||x===9661||x===9664||x===9665||x>=9670&&x<=9672||x===9675||x>=9678&&x<=9681||x>=9698&&x<=9701||x===9711||x===9733||x===9734||x===9737||x===9742||x===9743||x===9756||x===9758||x===9792||x===9794||x===9824||x===9825||x>=9827&&x<=9829||x>=9831&&x<=9834||x===9836||x===9837||x===9839||x===9886||x===9887||x===9919||x>=9926&&x<=9933||x>=9935&&x<=9939||x>=9941&&x<=9953||x===9955||x===9960||x===9961||x>=9963&&x<=9969||x===9972||x>=9974&&x<=9977||x===9979||x===9980||x===9982||x===9983||x===10045||x>=10102&&x<=10111||x>=11094&&x<=11097||x>=12872&&x<=12879||x>=57344&&x<=63743||x>=65024&&x<=65039||x===65533||x>=127232&&x<=127242||x>=127248&&x<=127277||x>=127280&&x<=127337||x>=127344&&x<=127373||x===127375||x===127376||x>=127387&&x<=127404||x>=917760&&x<=917999||x>=983040&&x<=1048573||x>=1048576&&x<=1114109}function isFullWidth(x){return x===12288||x>=65281&&x<=65376||x>=65504&&x<=65510}function isWide(x){return x>=4352&&x<=4447||x===8986||x===8987||x===9001||x===9002||x>=9193&&x<=9196||x===9200||x===9203||x===9725||x===9726||x===9748||x===9749||x>=9776&&x<=9783||x>=9800&&x<=9811||x===9855||x>=9866&&x<=9871||x===9875||x===9889||x===9898||x===9899||x===9917||x===9918||x===9924||x===9925||x===9934||x===9940||x===9962||x===9970||x===9971||x===9973||x===9978||x===9981||x===9989||x===9994||x===9995||x===10024||x===10060||x===10062||x>=10067&&x<=10069||x===10071||x>=10133&&x<=10135||x===10160||x===10175||x===11035||x===11036||x===11088||x===11093||x>=11904&&x<=11929||x>=11931&&x<=12019||x>=12032&&x<=12245||x>=12272&&x<=12287||x>=12289&&x<=12350||x>=12353&&x<=12438||x>=12441&&x<=12543||x>=12549&&x<=12591||x>=12593&&x<=12686||x>=12688&&x<=12773||x>=12783&&x<=12830||x>=12832&&x<=12871||x>=12880&&x<=42124||x>=42128&&x<=42182||x>=43360&&x<=43388||x>=44032&&x<=55203||x>=63744&&x<=64255||x>=65040&&x<=65049||x>=65072&&x<=65106||x>=65108&&x<=65126||x>=65128&&x<=65131||x>=94176&&x<=94180||x>=94192&&x<=94198||x>=94208&&x<=101589||x>=101631&&x<=101662||x>=101760&&x<=101874||x>=110576&&x<=110579||x>=110581&&x<=110587||x===110589||x===110590||x>=110592&&x<=110882||x===110898||x>=110928&&x<=110930||x===110933||x>=110948&&x<=110951||x>=110960&&x<=111355||x>=119552&&x<=119638||x>=119648&&x<=119670||x===126980||x===127183||x===127374||x>=127377&&x<=127386||x>=127488&&x<=127490||x>=127504&&x<=127547||x>=127552&&x<=127560||x===127568||x===127569||x>=127584&&x<=127589||x>=127744&&x<=127776||x>=127789&&x<=127797||x>=127799&&x<=127868||x>=127870&&x<=127891||x>=127904&&x<=127946||x>=127951&&x<=127955||x>=127968&&x<=127984||x===127988||x>=127992&&x<=128062||x===128064||x>=128066&&x<=128252||x>=128255&&x<=128317||x>=128331&&x<=128334||x>=128336&&x<=128359||x===128378||x===128405||x===128406||x===128420||x>=128507&&x<=128591||x>=128640&&x<=128709||x===128716||x>=128720&&x<=128722||x>=128725&&x<=128728||x>=128732&&x<=128735||x===128747||x===128748||x>=128756&&x<=128764||x>=128992&&x<=129003||x===129008||x>=129292&&x<=129338||x>=129340&&x<=129349||x>=129351&&x<=129535||x>=129648&&x<=129660||x>=129664&&x<=129674||x>=129678&&x<=129734||x===129736||x>=129741&&x<=129756||x>=129759&&x<=129770||x>=129775&&x<=129784||x>=131072&&x<=196605||x>=196608&&x<=262141}function validate(codePoint){if(!Number.isSafeInteger(codePoint))throw TypeError(`Expected a code point, got \`${typeof codePoint}\`.`)}function eastAsianWidth(codePoint,{ambiguousAsWide=!1}={}){if(validate(codePoint),isFullWidth(codePoint)||isWide(codePoint)||ambiguousAsWide&&isAmbiguous(codePoint))return 2;return 1}var import_emoji_regex=__toESM2(require_emoji_regex(),1),segmenter=new Intl.Segmenter,defaultIgnorableCodePointRegex=/^\p{Default_Ignorable_Code_Point}$/u;function stringWidth(string,options={}){if(typeof string!=="string"||string.length===0)return 0;let{ambiguousIsNarrow=!0,countAnsiEscapeCodes=!1}=options;if(!countAnsiEscapeCodes)string=stripAnsi(string);if(string.length===0)return 0;let width=0,eastAsianWidthOptions={ambiguousAsWide:!ambiguousIsNarrow};for(let{segment:character}of segmenter.segment(string)){let codePoint=character.codePointAt(0);if(codePoint<=31||codePoint>=127&&codePoint<=159)continue;if(codePoint>=8203&&codePoint<=8207||codePoint===65279)continue;if(codePoint>=768&&codePoint<=879||codePoint>=6832&&codePoint<=6911||codePoint>=7616&&codePoint<=7679||codePoint>=8400&&codePoint<=8447||codePoint>=65056&&codePoint<=65071)continue;if(codePoint>=55296&&codePoint<=57343)continue;if(codePoint>=65024&&codePoint<=65039)continue;if(defaultIgnorableCodePointRegex.test(character))continue;if(import_emoji_regex.default().test(character)){width+=2;continue}width+=eastAsianWidth(codePoint,eastAsianWidthOptions)}return width}var TEXT_ENCODER=new TextEncoder,bun=globalThis.Bun,sleep=bun?.sleep??standardSleep,stringWidth2=bun?.stringWidth??stringWidth,stripANSI=bun?.stripANSI??stripAnsi,writeFile=bun?.write??writeFilePortable;async function resolveBundledFilePath(loadBundledFile,fallbackPath,metaUrl){if(!bun){let path3=resolveFallbackFilePath(fallbackPath,metaUrl);if(existsSync(path3))return path3;return await loadBundledFilePath(loadBundledFile,metaUrl)??path3}return normalizeLoadedFilePath((await loadBundledFile()).default,metaUrl)}function resolveFallbackFilePath(fallbackPath,metaUrl){let path3=typeof fallbackPath==="function"?fallbackPath():fallbackPath;return fileURLToPath2(path3 instanceof URL?path3:new URL(path3,metaUrl))}function normalizeLoadedFilePath(loadedPath,baseUrl){if(loadedPath.startsWith("file:"))return fileURLToPath2(loadedPath);if(isAbsolute(loadedPath))return loadedPath;return resolve(dirname(fileURLToPath2(baseUrl)),loadedPath)}async function loadBundledFilePath(loadBundledFile,metaUrl){let specifier=extractBundledImportSpecifier(loadBundledFile);if(!specifier)return;try{let moduleUrl=new URL(specifier,metaUrl),loaded=await import(moduleUrl.href);return normalizeLoadedFilePath(loaded.default,moduleUrl.href)}catch{return}}function extractBundledImportSpecifier(loadBundledFile){return String(loadBundledFile).match(/\bimport\(\s*(["'`])([^"'`]+)\1/)?.[2]}function standardSleep(msOrDate){let ms=msOrDate instanceof Date?msOrDate.getTime()-Date.now():msOrDate;return new Promise((resolve22)=>setTimeout(resolve22,ms))}async function writeFilePortable(destination,data,options){let destinationPath=destination instanceof URL?fileURLToPath2(destination):destination;if(options?.createPath)await mkdir(dirname(destinationPath),{recursive:!0});let bytes=typeof data==="string"?TEXT_ENCODER.encode(data):new Uint8Array(data.buffer,data.byteOffset,data.byteLength);return await writeFileNode(destinationPath,bytes,{mode:options?.mode}),bytes.byteLength}var DEFAULT_FOREGROUND_RGB=[255,255,255],DEFAULT_BACKGROUND_RGB=[0,0,0],INTENT_RGB=0,INTENT_INDEXED=1,INTENT_DEFAULT=2,ANSI16_RGB=[[0,0,0],[128,0,0],[0,128,0],[128,128,0],[0,0,128],[128,0,128],[0,128,128],[192,192,192],[128,128,128],[255,0,0],[0,255,0],[255,255,0],[0,0,255],[255,0,255],[0,255,255],[255,255,255]],ANSI_256_CUBE_LEVELS=[0,95,135,175,215,255];function packMeta(intent,slot=0){return(slot&255|(intent&255)<<8)>>>0}function toU8(value){return Math.round(Math.max(0,Math.min(1,Number.isFinite(value)?value:0))*255)}function toByte(value){return Math.round(Math.max(0,Math.min(255,Number.isFinite(value)?value:0)))}function packRGBA8(r,g,b,a,meta){return new Uint16Array([toByte(r)&255|(meta>>>0&255)<<8,toByte(g)&255|(meta>>>8&255)<<8,toByte(b)&255|(meta>>>16&255)<<8,toByte(a)&255|(meta>>>24&255)<<8])}function rgbaForAnsi256Index(index){let[r,g,b]=ansi256IndexToRgb(index);return RGBA.fromInts(r,g,b)}function normalizeIndexedColorIndex(index){if(!Number.isInteger(index)||index<0||index>255)throw RangeError(`Indexed color must be an integer in the range 0..255, got ${index}`);return index}function ansi256IndexToRgb(index){let normalizedIndex=normalizeIndexedColorIndex(index);if(normalizedIndex<ANSI16_RGB.length)return ANSI16_RGB[normalizedIndex];if(normalizedIndex<232){let cubeIndex=normalizedIndex-16,r=Math.floor(cubeIndex/36),g=Math.floor(cubeIndex/6)%6,b=cubeIndex%6;return[ANSI_256_CUBE_LEVELS[r],ANSI_256_CUBE_LEVELS[g],ANSI_256_CUBE_LEVELS[b]]}let value=8+(normalizedIndex-232)*10;return[value,value,value]}class RGBA{buffer;constructor(buffer){this.buffer=new Uint16Array(4),this.buffer.set(buffer.subarray(0,4))}static fromArray(array){return new RGBA(array)}static fromValues(r,g,b,a=1){return new RGBA(packRGBA8(toU8(r),toU8(g),toU8(b),toU8(a),packMeta(INTENT_RGB)))}static clone(rgba){return new RGBA(rgba.buffer)}static fromInts(r,g,b,a=255){return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_RGB)))}static fromHex(hex){return hexToRgb(hex)}static fromIndex(index,snapshot){let normalized=normalizeIndexedColorIndex(index),rgba=snapshot?parseColor(snapshot):rgbaForAnsi256Index(normalized),[r,g,b,a]=rgba.toInts();return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_INDEXED,normalized)))}static defaultForeground(snapshot){let rgba=snapshot?parseColor(snapshot):RGBA.fromInts(...DEFAULT_FOREGROUND_RGB),[r,g,b,a]=rgba.toInts();return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_DEFAULT)))}static defaultBackground(snapshot){let rgba=snapshot?parseColor(snapshot):RGBA.fromInts(...DEFAULT_BACKGROUND_RGB),[r,g,b,a]=rgba.toInts();return new RGBA(packRGBA8(r,g,b,a,packMeta(INTENT_DEFAULT)))}toInts(){return[this.buffer[0]&255,this.buffer[1]&255,this.buffer[2]&255,this.buffer[3]&255]}get r(){return(this.buffer[0]&255)/255}set r(value){this.buffer[0]=this.buffer[0]&65280|toU8(value)}get g(){return(this.buffer[1]&255)/255}set g(value){this.buffer[1]=this.buffer[1]&65280|toU8(value)}get b(){return(this.buffer[2]&255)/255}set b(value){this.buffer[2]=this.buffer[2]&65280|toU8(value)}get a(){return(this.buffer[3]&255)/255}set a(value){this.buffer[3]=this.buffer[3]&65280|toU8(value)}get meta(){return(this.buffer[0]>>>8|this.buffer[1]>>>8<<8|this.buffer[2]>>>8<<16|this.buffer[3]>>>8<<24)>>>0}get intent(){switch(this.meta>>>8&255){case INTENT_INDEXED:return"indexed";case INTENT_DEFAULT:return"default";default:return"rgb"}}get slot(){return this.meta&255}map(fn){return[fn(this.r),fn(this.g),fn(this.b),fn(this.a)]}toString(){return`rgba(${this.r.toFixed(2)}, ${this.g.toFixed(2)}, ${this.b.toFixed(2)}, ${this.a.toFixed(2)})`}equals(other){if(!other)return!1;return this.buffer[0]===other.buffer[0]&&this.buffer[1]===other.buffer[1]&&this.buffer[2]===other.buffer[2]&&this.buffer[3]===other.buffer[3]}}function normalizeColorValue(value){if(value==null)return null;return{rgba:parseColor(value)}}function hexToRgb(hex){if(hex=hex.replace(/^#/,""),hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];else if(hex.length===4)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]+hex[3]+hex[3];if(!/^[0-9A-Fa-f]{6}$/.test(hex)&&!/^[0-9A-Fa-f]{8}$/.test(hex))return console.warn(`Invalid hex color: ${hex}, defaulting to magenta`),RGBA.fromValues(1,0,1,1);let r=parseInt(hex.substring(0,2),16),g=parseInt(hex.substring(2,4),16),b=parseInt(hex.substring(4,6),16),a=hex.length===8?parseInt(hex.substring(6,8),16):255;return RGBA.fromInts(r,g,b,a)}var CSS_COLOR_NAMES={black:"#000000",white:"#FFFFFF",red:"#FF0000",green:"#008000",blue:"#0000FF",yellow:"#FFFF00",cyan:"#00FFFF",magenta:"#FF00FF",silver:"#C0C0C0",gray:"#808080",grey:"#808080",maroon:"#800000",olive:"#808000",lime:"#00FF00",aqua:"#00FFFF",teal:"#008080",navy:"#000080",fuchsia:"#FF00FF",purple:"#800080",orange:"#FFA500",brightblack:"#666666",brightred:"#FF6666",brightgreen:"#66FF66",brightblue:"#6666FF",brightyellow:"#FFFF66",brightcyan:"#66FFFF",brightmagenta:"#FF66FF",brightwhite:"#FFFFFF"};function parseColor(color){if(typeof color==="string"){let lowerColor=color.toLowerCase();if(lowerColor==="transparent")return RGBA.fromValues(0,0,0,0);if(CSS_COLOR_NAMES[lowerColor])return hexToRgb(CSS_COLOR_NAMES[lowerColor]);return hexToRgb(color)}return color}var VALID_BORDER_STYLES=["single","double","rounded","heavy"];function isValidBorderStyle(value){return typeof value==="string"&&VALID_BORDER_STYLES.includes(value)}function parseBorderStyle(value,fallback="single"){if(isValidBorderStyle(value))return value;if(value!==void 0&&value!==null)console.warn(`Invalid borderStyle "${value}", falling back to "${fallback}". Valid values are: ${VALID_BORDER_STYLES.join(", ")}`);return fallback}var BorderChars={single:{topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",topT:"\u252C",bottomT:"\u2534",leftT:"\u251C",rightT:"\u2524",cross:"\u253C"},double:{topLeft:"\u2554",topRight:"\u2557",bottomLeft:"\u255A",bottomRight:"\u255D",horizontal:"\u2550",vertical:"\u2551",topT:"\u2566",bottomT:"\u2569",leftT:"\u2560",rightT:"\u2563",cross:"\u256C"},rounded:{topLeft:"\u256D",topRight:"\u256E",bottomLeft:"\u2570",bottomRight:"\u256F",horizontal:"\u2500",vertical:"\u2502",topT:"\u252C",bottomT:"\u2534",leftT:"\u251C",rightT:"\u2524",cross:"\u253C"},heavy:{topLeft:"\u250F",topRight:"\u2513",bottomLeft:"\u2517",bottomRight:"\u251B",horizontal:"\u2501",vertical:"\u2503",topT:"\u2533",bottomT:"\u253B",leftT:"\u2523",rightT:"\u252B",cross:"\u254B"}};function getBorderSides(border){return border===!0?{top:!0,right:!0,bottom:!0,left:!0}:Array.isArray(border)?{top:border.includes("top"),right:border.includes("right"),bottom:border.includes("bottom"),left:border.includes("left")}:{top:!1,right:!1,bottom:!1,left:!1}}function borderCharsToArray(chars){let array=new Uint32Array(11);return array[0]=chars.topLeft.codePointAt(0),array[1]=chars.topRight.codePointAt(0),array[2]=chars.bottomLeft.codePointAt(0),array[3]=chars.bottomRight.codePointAt(0),array[4]=chars.horizontal.codePointAt(0),array[5]=chars.vertical.codePointAt(0),array[6]=chars.topT.codePointAt(0),array[7]=chars.bottomT.codePointAt(0),array[8]=chars.leftT.codePointAt(0),array[9]=chars.rightT.codePointAt(0),array[10]=chars.cross.codePointAt(0),array}var BorderCharArrays={single:borderCharsToArray(BorderChars.single),double:borderCharsToArray(BorderChars.double),rounded:borderCharsToArray(BorderChars.rounded),heavy:borderCharsToArray(BorderChars.heavy)};class KeyEvent{name;ctrl;meta;shift;option;sequence;number;raw;eventType;source;code;super;hyper;capsLock;numLock;baseCode;repeated;_defaultPrevented=!1;_propagationStopped=!1;constructor(key){this.name=key.name,this.ctrl=key.ctrl,this.meta=key.meta,this.shift=key.shift,this.option=key.option,this.sequence=key.sequence,this.number=key.number,this.raw=key.raw,this.eventType=key.eventType,this.source=key.source,this.code=key.code,this.super=key.super,this.hyper=key.hyper,this.capsLock=key.capsLock,this.numLock=key.numLock,this.baseCode=key.baseCode,this.repeated=key.repeated}get defaultPrevented(){return this._defaultPrevented}get propagationStopped(){return this._propagationStopped}preventDefault(){this._defaultPrevented=!0}stopPropagation(){this._propagationStopped=!0}}class PasteEvent{type="paste";bytes;metadata;_defaultPrevented=!1;_propagationStopped=!1;constructor(bytes,metadata){this.bytes=bytes,this.metadata=metadata}get defaultPrevented(){return this._defaultPrevented}get propagationStopped(){return this._propagationStopped}preventDefault(){this._defaultPrevented=!0}stopPropagation(){this._propagationStopped=!0}}class KeyHandler extends EventEmitter{processParsedKey(parsedKey){try{switch(parsedKey.eventType){case"press":this.emit("keypress",new KeyEvent(parsedKey));break;case"release":this.emit("keyrelease",new KeyEvent(parsedKey));break;default:this.emit("keypress",new KeyEvent(parsedKey));break}}catch(error){return console.error("[KeyHandler] Error processing parsed key:",error),!0}return!0}processPaste(bytes,metadata){try{this.emit("paste",new PasteEvent(bytes,metadata))}catch(error){console.error("[KeyHandler] Error processing paste:",error)}}}class InternalKeyHandler extends KeyHandler{renderableHandlers=new Map;emit(event,...args){return this.emitWithPriority(event,...args)}emitWithPriority(event,...args){let hasGlobalListeners=!1,globalListeners=this.listeners(event);if(globalListeners.length>0){hasGlobalListeners=!0;for(let listener of globalListeners){try{listener(...args)}catch(error){console.error(`[KeyHandler] Error in global ${event} handler:`,error)}if(event==="keypress"||event==="keyrelease"||event==="paste"){if(args[0].propagationStopped)return hasGlobalListeners}}}let renderableSet=this.renderableHandlers.get(event),renderableHandlers=renderableSet&&renderableSet.size>0?[...renderableSet]:[],hasRenderableListeners=!1;if(renderableSet&&renderableSet.size>0){if(hasRenderableListeners=!0,event==="keypress"||event==="keyrelease"||event==="paste"){let keyEvent=args[0];if(keyEvent.defaultPrevented)return hasGlobalListeners||hasRenderableListeners;if(keyEvent.propagationStopped)return hasGlobalListeners||hasRenderableListeners}for(let handler of renderableHandlers){try{handler(...args)}catch(error){console.error(`[KeyHandler] Error in renderable ${event} handler:`,error)}if(event==="keypress"||event==="keyrelease"||event==="paste"){if(args[0].propagationStopped)return hasGlobalListeners||hasRenderableListeners}}}return hasGlobalListeners||hasRenderableListeners}onInternal(event,handler){if(!this.renderableHandlers.has(event))this.renderableHandlers.set(event,new Set);this.renderableHandlers.get(event).add(handler)}offInternal(event,handler){let handlers=this.renderableHandlers.get(event);if(handlers)handlers.delete(handler)}}var block_default={name:"block",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:[" "," "," "," "," "," "],letterspace_size:1,chars:{A:[" <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2> ","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],B:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],C:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],D:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],E:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],F:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A\u2550\u255D </c2>"],G:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],H:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],I:["<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D</c2>"],J:["<c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588 \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u255D </c2>"],K:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],L:["<c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],M:["<c1>\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551\u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551 \u255A\u2550\u255D</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],N:["<c1>\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551 \u255A</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D</c2>"],O:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],P:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A\u2550\u255D </c2>"],Q:[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2584\u2584 \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550</c2><c1>\u2580\u2580</c1><c2>\u2550\u255D </c2>"],R:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],S:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],T:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c2> \u255A\u2550\u255D </c2>"],U:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],V:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c2> \u255A\u2550\u2550\u2550\u255D </c2>"],W:["<c1>\u2588\u2588</c1><c2>\u2557 </c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551 </c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D </c2>"],X:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],Y:["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c2> \u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c2> \u255A\u2550\u255D </c2>"],Z:["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550</c2><c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"0":[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2554</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"1":[" <c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2> \u255A\u2550\u255D</c2>"],"2":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>"," <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"3":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>"," <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"4":["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1> \u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1> \u2588\u2588</c1><c2>\u2551</c2>","<c2> \u255A\u2550\u255D</c2>"],"5":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"6":[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"7":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c2> \u255A\u2550\u255D </c2>"],"8":[" <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u255D </c2>"],"9":[" <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2> \u255A\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u2550\u2550\u2550\u255D </c2>"],"!":["<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>"],"?":["<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1> \u2584\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2580\u2580</c1><c2>\u2550\u2550\u255D </c2>","<c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c2> \u255A\u2550\u255D </c2>"],".":[" "," "," "," ","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>"],"+":[" ","<c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2> \u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550\u255D</c2>","<c2> \u255A\u2550\u255D </c2>"," "],"-":[" "," ","<c1>\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u255D</c2>"," "," "],_:[" "," "," "," ","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D</c2>"],"=":[" ","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D</c2>"," "],"@":[" <c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2557</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A</c2><c1>\u2588</c1><c2>\u2551</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u255D\u255A\u2550\u2550\u2550\u255D </c2>"],"#":[" <c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2> \u255A\u2550\u255D \u255A\u2550\u255D </c2>"],$:["<c1>\u2584\u2584\u2588\u2588\u2588\u2584\u2584</c1><c2>\xB7</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550\u2550\u2550\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u2550\u2550\u2550</c2><c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551</c2>","<c2>\u255A\u2550</c2><c1>\u2580\u2580\u2580</c1><c2>\u2550\u2550\u255D</c2>"],"%":["<c1>\u2588\u2588</c1><c2>\u2557</c2><c1> \u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2><c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D \u255A\u2550\u255D</c2>"],"&":["<c1> \u2588\u2588</c1><c2>\u2557 </c2>","<c1> \u2588\u2588</c1><c2>\u2551 </c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u2550</c2><c1>\u2588\u2588</c1><c2>\u2554\u2550\u255D</c2>","<c1>\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2551 </c2>","<c2>\u255A\u2550\u2550\u2550\u2550\u2550\u255D </c2>"],"(":[" <c1>\u2588\u2588</c1><c2>\u2557</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2551 ","<c1>\u2588\u2588</c1><c2>\u2551 ","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2> \u255A\u2550\u255D</c2>"],")":["<c1>\u2588\u2588</c1><c2>\u2557 </c2>","<c2>\u255A</c2><c1>\u2588\u2588</c1><c2>\u2557</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>"," <c1>\u2588\u2588</c1><c2>\u2551</c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D</c2>","<c2>\u255A\u2550\u255D </c2>"],"/":["<c1> \u2588\u2588</c1><c2>\u2557</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D</c2>","<c1> \u2588\u2588</c1><c2>\u2554\u255D </c2>"," <c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c1>\u2588\u2588</c1><c2>\u2554\u255D </c2>","<c2>\u255A\u2550\u255D </c2>"],":":[" ","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>"," "],";":[" "," ","<c1>\u2588\u2588</c1><c2>\u2557</c2>","<c2>\u255A\u2550\u255D</c2>","<c1>\u2584\u2588</c1><c2>\u2557</c2>","<c1>\u2580</c1><c2>\u2550\u255D</c2>"],",":[" "," "," "," ","<c1>\u2584\u2588</c1><c2>\u2557</c2>","<c1>\u2580</c1><c2>\u2550\u255D</c2>"],"'":["<c1>\u2588</c1><c2>\u2557</c2> ","<c2>\u255A\u255D</c2> "," "," "," "," "],'"':["<c1>\u2588</c1><c2>\u2557</c2><c1>\u2588</c1><c2>\u2557</c2> ","<c2>\u255A\u255D\u255A\u255D</c2> "," "," "," "," "]," ":[" "," "," "," "," "," "]}},shade_default={name:"shade",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:8,buffer:["","","","","","","",""],letterspace:["<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>","<c2>\u2591</c2>"],letterspace_size:1,chars:{A:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],B:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],C:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],D:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],E:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],F:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],G:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2> <c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],H:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],I:["<c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591</c2>"],J:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],K:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],L:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],M:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],N:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588</c1><c2>\u2591</c2><c1>\u2588</c1>","<c1>\u2588 \u2588\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2> <c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],O:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],P:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],Q:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588\u2588</c1>","<c2>\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],R:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],S:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588</c1> "," <c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2> <c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],T:["<c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591</c2>"],U:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],V:["<c2>\u2591\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1> ","<c2>\u2591</c2> <c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591</c2>"],W:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],X:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588</c1>"," <c2>\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],Y:["<c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591</c2>"],Z:["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"0":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u258C\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2> <c1>\u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"1":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588</c1><c2>\u2591\u2591</c2>"," <c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"2":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2590\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"3":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588\u2588</c1>","<c2>\u2591\u2591</c2> <c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"4":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c2>\u2591\u2591\u2591</c2> ","<c2>\u2591\u2591\u2591\u2591</c2>"],"5":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"6":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588</c1> ","<c1>\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"7":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u2588</c1> ","<c1>\u2588</c1> <c2>\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"8":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588</c1> ","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"9":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>"," <c1>\u2588\u2588\u2588</c1>","<c2>\u2591</c2> <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"!":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"?":["<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2590\u2588\u2588</c1><c2>\u2591</c2>"," <c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],".":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"+":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c2>\u2591</c2> <c1>\u2588</c1> ","<c2>\u2591\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"-":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],_:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," "],"=":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c1>\u2588\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],"@":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588</c1><c2>\u2591</c2>","<c1>\u2588 \u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u258C\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1> "," <c1>\u2588\u2588\u2588</c1>"," ","<c2>\u2591\u2591\u2591\u2591</c2>"],"#":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2>","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u258C\u2590</c1> ","<c1>\u2588\u2588\u2588\u2588</c1>"," <c1>\u258C\u2590</c1> ","<c2>\u2591 \u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],$:["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u258C</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1> "," <c1>\u2588\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u258C\u2588</c1>","<c1>\u2588\u2588\u2588</c1> "," <c2>\u2591</c2>"],"%":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1> "," <c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1>","<c1>\u2588</c1> <c2>\u2591</c2> "," <c2>\u2591\u2591\u2591</c2>"],"&":["<c2>\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>","<c1>\u2588\u2588\u2588\u2588\u2588</c1>","<c1>\u2588 \u2588</c1> ","<c1>\u2588\u2588\u2588\u2588</c1><c2>\u2591</c2>","<c2> </c2> ","<c2>\u2591\u2591\u2591\u2591\u2591</c2>"],"(":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c1>\u2588</c1> <c2>\u2591\u2591</c2>","<c1>\u2588</c1><c2>\u2591\u2591\u2591</c2>"," <c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2> <c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591 \u2591</c2>"],")":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2> <c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591\u2591</c2> <c1>\u2588</c1>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>"],"/":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2><c1>\u2588</c1>","<c2>\u2591\u2591</c2><c1>\u2588</c1> ","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c1>\u2588</c1> <c2>\u2591\u2591</c2>"," <c2>\u2591\u2591\u2591</c2>"],":":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],";":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>"],",":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591</c2><c1>\u2588</c1><c2>\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1> <c2>\u2591</c2>"],"'":["<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591</c2>"],'"':["<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591\u2591</c2>","<c2>\u2591 \u2591 \u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2>"]," ":["<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>","<c2>\u2591\u2591\u2591</c2>"]}},slick_default={name:"slick",version:"0.1.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:["<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>","<c2>\u2571</c2>"],letterspace_size:1,chars:{A:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>"],B:["<c1>\u256D\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u256F\u2570\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],C:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],D:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u256E\u256D\u256E\u2503</c1>","<c2>\u2571</c2><c1>\u2503\u2503\u2503\u2503</c1>","<c2>\u2571</c2><c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u256D\u256F\u2570\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],E:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],F:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2570\u256F</c1><c2>\u2571\u2571\u2571</c2>"],G:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>","<c1>\u2503\u2503\u256D\u2501\u256E</c1>","<c1>\u2503\u2570\u253B\u2501\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],H:["<c1>\u256D\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u2570\u256F</c1>"],I:["<c1>\u256D\u2501\u2501\u256E</c1>","<c1>\u2570\u252B\u2523\u256F</c1>","<c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u256D\u252B\u2523\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],J:["<c2>\u2571\u2571</c2><c1>\u256D\u256E</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u256D\u256E\u2503\u2503</c1>","<c1>\u2503\u2570\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],K:["<c1>\u256D\u256E\u256D\u2501\u256E</c1>","<c1>\u2503\u2503\u2503\u256D\u256F</c1>","<c1>\u2503\u2570\u256F\u256F</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503\u2503\u2570\u256E</c1>","<c1>\u2570\u256F\u2570\u2501\u256F</c1>"],L:["<c1>\u256D\u256E</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],M:["<c1>\u256D\u2501\u256E\u256D\u2501\u256E</c1>","<c1>\u2503\u2503\u2570\u256F\u2503\u2503</c1>","<c1>\u2503\u256D\u256E\u256D\u256E\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2570\u256F\u2570\u256F\u2570\u256F</c1>"],N:["<c1>\u256D\u2501\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503\u2570\u256E\u2503\u2503</c1>","<c1>\u2503\u256D\u256E\u2570\u256F\u2503</c1>","<c1>\u2503\u2503\u2570\u256E\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503\u2503</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u2570\u2501\u256F</c1>"],O:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],P:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2503</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2570\u256F</c1><c2>\u2571\u2571\u2571</c2>"],Q:["<c1>\u256D\u2501\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u2501\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u2501\u256F\u2503\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u2501\u256F</c1>"],R:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u256E\u256D\u256F</c1>","<c1>\u2503\u2503\u2503\u2570\u256E</c1>","<c1>\u2570\u256F\u2570\u2501\u256F</c1>"],S:["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],T:["<c1>\u256D\u2501\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u256E\u256D\u256E\u2503</c1>","<c1>\u2570\u256F\u2503\u2503\u2570\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],U:["<c1>\u256D\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],V:["<c1>\u256D\u256E</c1><c2>\u2571\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u256E\u256D\u256F\u2503</c1>","<c1>\u2570\u256E\u2503\u2503\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2503\u2570\u256F\u2503</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2570\u256E\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],W:["<c1>\u256D\u256E\u256D\u256E\u256D\u256E</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2570\u256F\u2570\u256F\u2503</c1>","<c1>\u2570\u256E\u256D\u256E\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256F\u2570\u256F</c1><c2>\u2571</c2>"],X:["<c1>\u256D\u2501\u256E\u256D\u2501\u256E</c1>","<c1>\u2570\u256E\u2570\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256E\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256F\u2570\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u256D\u256E\u2570\u256E</c1>","<c1>\u2570\u2501\u256F\u2570\u2501\u256F</c1>"],Y:["<c1>\u256D\u256E</c1><c2>\u2571\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2570\u256E\u256D\u256F\u2503</c1>","<c1>\u2570\u256E\u2570\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256E\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],Z:["<c1>\u256D\u2501\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2501\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2501\u2570\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u2501\u256F</c1>"],"0":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"1":["<c2>\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2503</c1><c2>\u2571</c2>","<c1>\u2570\u256E\u2503</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2570\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],"2":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c1>\u256D\u2501\u256F\u256D\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"3":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c1>\u256D\u256E\u2570\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"4":["<c1>\u256D\u256E</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1><c2>\u2571</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c2>\u2571\u2571\u2571</c2><c1>\u2503\u2503</c1>","<c2>\u2571\u2571\u2571</c2><c1>\u2570\u256F</c1>"],"5":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u256D\u2501\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"6":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u2501\u256F</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"7":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u2503</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571</c2>"],"8":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"9":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2503\u2570\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u256D\u2501\u2501\u256F\u2503</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"!":["<c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1>","<c1>\u2570\u256F</c1>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>"],"?":["<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2503\u256D\u2501\u256E\u2503</c1>","<c1>\u2570\u256F\u256D\u256F\u2503</c1>","<c2>\u2571\u2571</c2><c1>\u2503\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c2>\u2571\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571</c2>"],".":["<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>"],"+":["<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u2570\u256E</c1>","<c1>\u2570\u256E\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571</c2>"],"-":["<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c1>\u256D\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>","<c2>\u2571\u2571\u2571\u2571</c2>"],_:["<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c1>\u256D\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256F</c1>"],"=":["<c2>\u2571\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571\u2571</c2>","<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>","<c1>\u256D\u2501\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"@":["<c1>\u256D\u2501\u2501\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u2501\u2501\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503\u256D\u2501\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2503\u2570\u256F\u2503\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u2501\u2501\u256F\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u2501\u2501\u256F</c1>"],"#":["<c2>\u2571</c2><c1>\u256D\u2501\u2501\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u256F\u256D\u256E\u2570\u256E</c1>","<c1>\u2570\u256E\u2503\u2503\u256D\u256F</c1>","<c1>\u256D\u256F\u2503\u2503\u2570\u256E</c1>","<c1>\u2570\u256E\u2570\u256F\u256D\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u2501\u2501\u256F</c1><c2>\u2571</c2>"],$:["<c2>\u2571\u2571</c2><c1>\u256D\u256E</c1><c2>\u2571</c2>","<c1>\u256D\u2501\u256F\u2570\u256E</c1>","<c1>\u2503\u2570\u2501\u2501\u256E</c1>","<c1>\u2570\u2501\u2501\u256E\u2503</c1>","<c1>\u2570\u256E\u256D\u2501\u256F</c1>","<c2>\u2571</c2><c1>\u2570\u256F</c1><c2>\u2571\u2571</c2>"],"%":["<c1>\u256D\u256E</c1><c2>\u2571\u2571</c2><c1>\u256D\u2501\u256E</c1>","<c1>\u2570\u256F</c1><c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571\u2571</c2>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2><c1>\u256D\u256E</c1>","<c1>\u2570\u2501\u256F</c1><c2>\u2571\u2571</c2><c1>\u2570\u256F</c1>"],"&":["<c2>\u2571</c2><c1>\u256D\u2501\u2501\u256E</c1>","<c2>\u2571</c2><c1>\u2503\u256D\u2501\u256F</c1>","<c1>\u256D\u256F\u2570\u256E</c1><c2>\u2571</c2>","<c1>\u2503\u256D\u256E\u2503</c1><c2>\u2571</c2>","<c1>\u2503\u2570\u256F\u2503\u256E</c1>","<c1>\u2570\u2501\u2501\u2501\u256F</c1>"],"(":["<c2>\u2571\u2571</c2><c1>\u256D\u2501\u256E</c1>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c1>\u2570\u256E\u2570\u256E</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2570\u256E\u2570\u256E</c1>","<c2>\u2571\u2571</c2><c1>\u2570\u2501\u256F</c1>"],")":["<c1>\u256D\u2501\u256E</c1><c2>\u2571\u2571</c2>","<c1>\u2570\u256E\u2570\u256E</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u2570\u256E\u2570\u256E</c1>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c1>\u2570\u2501\u256F</c1><c2>\u2571\u2571</c2>"],"/":["<c2>\u2571\u2571\u2571\u2571</c2><c1>\u256D\u2501\u256E</c1>","<c2>\u2571\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1>","<c2>\u2571\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571</c2>","<c2>\u2571</c2><c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571\u2571</c2>","<c1>\u256D\u256F\u256D\u256F</c1><c2>\u2571\u2571\u2571</c2>","<c1>\u2570\u2501\u256F</c1><c2>\u2571\u2571\u2571\u2571</c2>"],":":["<c2>\u2571\u2571</c2>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>","<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>","<c2>\u2571\u2571</c2>"],";":["<c1>\u256D\u256E</c1>","<c1>\u2503\u2503</c1>","<c1>\u2570\u256F</c1>","<c1>\u256D\u256E</c1>","<c1>\u2570\u252B</c1>","<c2>\u2571</c2><c1>\u256F</c1>"],",":["<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c1>\u256D\u256E</c1>","<c1>\u2570\u252B</c1>","<c2>\u2571</c2><c1>\u256F</c1>"],"'":["<c1>\u256D\u256E</c1>","<c1>\u2570\u256F</c1>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>","<c2>\u2571\u2571</c2>"],'"':["<c1>\u256D\u256E\u256D\u256E</c1>","<c1>\u2570\u256F\u2570\u256F</c1>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571\u2571</c2>"]," ":["<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>","<c2>\u2571\u2571\u2571</c2>"]}},tiny_default={name:"tiny",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:1,lines:2,buffer:["",""],letterspace:[" "," "],letterspace_size:1,chars:{A:["\u2584\u2580\u2588","\u2588\u2580\u2588"],B:["\u2588\u2584\u2584","\u2588\u2584\u2588"],C:["\u2588\u2580\u2580","\u2588\u2584\u2584"],D:["\u2588\u2580\u2584","\u2588\u2584\u2580"],E:["\u2588\u2580\u2580","\u2588\u2588\u2584"],F:["\u2588\u2580\u2580","\u2588\u2580 "],G:["\u2588\u2580\u2580","\u2588\u2584\u2588"],H:["\u2588 \u2588","\u2588\u2580\u2588"],I:["\u2588","\u2588"],J:[" \u2588","\u2588\u2584\u2588"],K:["\u2588\u2584\u2580","\u2588 \u2588"],L:["\u2588 ","\u2588\u2584\u2584"],M:["\u2588\u2580\u2584\u2580\u2588","\u2588 \u2580 \u2588"],N:["\u2588\u2584 \u2588","\u2588 \u2580\u2588"],O:["\u2588\u2580\u2588","\u2588\u2584\u2588"],P:["\u2588\u2580\u2588","\u2588\u2580\u2580"],Q:["\u2588\u2580\u2588","\u2580\u2580\u2588"],R:["\u2588\u2580\u2588","\u2588\u2580\u2584"],S:["\u2588\u2580\u2580","\u2584\u2584\u2588"],T:["\u2580\u2588\u2580"," \u2588 "],U:["\u2588 \u2588","\u2588\u2584\u2588"],V:["\u2588 \u2588","\u2580\u2584\u2580"],W:["\u2588 \u2588 \u2588","\u2580\u2584\u2580\u2584\u2580"],X:["\u2580\u2584\u2580","\u2588 \u2588"],Y:["\u2588\u2584\u2588"," \u2588 "],Z:["\u2580\u2588","\u2588\u2584"],"0":["\u259E\u2588\u259A","\u259A\u2588\u259E"],"1":["\u2584\u2588"," \u2588"],"2":["\u2580\u2588","\u2588\u2584"],"3":["\u2580\u2580\u2588","\u2584\u2588\u2588"],"4":["\u2588 \u2588","\u2580\u2580\u2588"],"5":["\u2588\u2580","\u2584\u2588"],"6":["\u2588\u2584\u2584","\u2588\u2584\u2588"],"7":["\u2580\u2580\u2588"," \u2588"],"8":["\u2588\u2588\u2588","\u2588\u2584\u2588"],"9":["\u2588\u2580\u2588","\u2580\u2580\u2588"],"!":["\u2588","\u2584"],"?":["\u2580\u2588"," \u2584"],".":[" ","\u2584"],"+":["\u2584\u2588\u2584"," \u2580 "],"-":["\u2584\u2584"," "],_:[" ","\u2584\u2584"],"=":["\u2580\u2580","\u2580\u2580"],"@":["\u259B\u2588\u259C","\u2599\u259F\u2583"],"#":["\u259F\u2584\u2599","\u259C\u2580\u259B"],$:["\u2596\u2588\u2597","\u2598\u2588\u259D"],"%":["\u2580 \u2584\u2580","\u2584\u2580 \u2584"],"&":["\u2584\u2584\u2588","\u2588\u2584\u2588"],"(":["\u2584\u2580","\u2580\u2584"],")":["\u2580\u2584","\u2584\u2580"],"/":[" \u2584\u2580","\u2584\u2580 "],":":["\u2580","\u2584"],";":[" ","\u2584\u2580"],",":[" ","\u2588"],"'":["\u2580"," "],'"':["\u259B \u259C"," "]," ":[" "," "]}},huge_default={name:"huge",version:"0.2.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:11,buffer:["","","","","","","","","","",""],letterspace:[" "," "," "," "," "," "," "," "," "," "," "],letterspace_size:1,chars:{A:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],B:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],C:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],D:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],E:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],F:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],G:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],H:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],I:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],J:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],K:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],L:[" <c1>\u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],M:[" <c1>\u2584\u2584 \u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2580 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],N:[" <c1>\u2584\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580\u2580</c1> "],O:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],P:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],Q:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],R:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],S:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],T:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],U:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],V:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],W:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580 \u2580\u2580</c1> "],X:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580 \u2580</c1> "],Y:[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],Z:[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"0":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"1":[" <c1>\u2584\u2584\u2584\u2584</c1> "," <c1>\u2584\u2588</c1><c2>\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580 \u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"2":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"3":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"4":[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2580</c1> "],"5":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"6":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"7":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],"8":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"9":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"!":[" <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "],"?":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> "," <c1>\u2584\u2588</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u2588\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580 \u2584\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2588</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u2588</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C\u2580\u2580\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580</c1> "," <c1>\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580</c1> "],".":[" "," "," "," "," "," "," "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "],"+":[" "," "," <c1>\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2588</c1><c2>\u2591\u2591</c2><c1>\u2588\u2580\u2580</c1> "," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580</c1> "," "," "],"-":[" "," "," "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "," "," "," "],_:[" "," "," "," "," "," "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "],"=":[" "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "," <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "," "," "],"@":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584\u2584\u2584\u2584 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2588</c1><c2>\u2591\u2591\u2591\u2591</c2><c1>\u2588 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u2588\u2588\u2588\u2588</c1><c2>\u2591</c2><c1>\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2588</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C\u2584\u2584\u2588\u2588\u2588\u2588\u2588\u2588\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580</c1> "],"#":[" <c1>\u2584 \u2584</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580 \u2580</c1> "],$:[" <c1>\u2584</c1> "," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580</c1> "," <c1>\u2580</c1> "],"%":[" <c1>\u2584</c1> "," <c1>\u2584 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580 \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2584</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2580</c1> "," <c1>\u2580</c1> "],"&":[" <c1>\u2584\u2584\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2580\u2580\u2580\u2580\u2588</c1><c2>\u2591</c2><c1>\u258C \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C \u2590</c1><c2>\u2591</c2><c1>\u2588</c1><c2>\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2588\u2584\u2584\u2584\u2584\u2588</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580\u2580 \u2580</c1> "],"(":[" <c1>\u2584\u2584\u2584\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u2588\u2580\u2580\u2580</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u2588\u2584\u2584\u2584</c1> "," <c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "],")":[" <c1>\u2584\u2584\u2584\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2584\u2584\u2584\u2588</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>","<c1>\u2590</c1><c2>\u2591\u2591\u2591\u2591\u2591</c2><c1>\u258C</c1> "," <c1>\u2580\u2580\u2580\u2580\u2580</c1> "],"/":[" <c1>\u2584</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1>"," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u258C</c1> "," <c1>\u2580</c1> "],":":[" "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," "," "],";":[" "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u2580</c1> "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u258C</c1> "," <c1>\u2580</c1> "," "],",":[" "," "," "," "," "," "," "," <c1>\u2584\u2584</c1> ","<c1>\u2590</c1><c2>\u2591\u2591</c2><c1>\u258C</c1>"," <c1>\u2580\u258C</c1> "," <c1>\u2580</c1> "],"'":[" <c1>\u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>"," <c1>\u2580</c1> "," "," "," "," "," "," "," "],'"':[" <c1>\u2584 \u2584</c1> ","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>","<c1>\u2590</c1><c2>\u2591</c2><c1>\u2590\u2590</c1><c2>\u2591</c2><c1>\u2590</c1>"," <c1>\u2580 \u2580</c1> "," "," "," "," "," "," "," "]," ":[" "," "," "," "," "," "," "," "," "," "," "]}},grid_default={name:"grid",version:"0.1.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:["<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>","<c2>\u254B</c2>"],letterspace_size:1,chars:{A:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],B:["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2503\u2517\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],C:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u251B</c1>","<c1>\u2503\u2517\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],D:["<c2>\u254B\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u250F\u2501\u251B\u2503</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],E:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u2503\u2501\u252B</c1>","<c1>\u2503\u2503\u2501\u252B</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],F:["<c2>\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],G:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2513\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>"],H:["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2503\u2517\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],I:["<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c1>\u250F\u2513</c1>","<c1>\u2503\u2503</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>"],J:["<c2>\u254B</c2><c1>\u250F\u2513</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1>","<c2>\u254B</c2><c1>\u250F\u2513</c1>","<c2>\u254B</c2><c1>\u2503\u2503</c1>","<c1>\u250F\u251B\u2503</c1>","<c1>\u2517\u2501\u251B</c1>"],K:["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2503\u2503\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u251B</c1>","<c1>\u2503\u250F\u2513\u2513</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],L:["<c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2517\u2513</c1>","<c1>\u2517\u2501\u251B</c1>","<c2>\u254B\u254B\u254B</c2>"],M:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2517\u253B\u253B\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],N:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2513</c1><c2>\u254B</c2>","<c1>\u2503\u250F\u2513\u2513</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],O:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],P:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2503\u250F\u2501\u251B</c1>","<c1>\u2517\u251B</c1><c2>\u254B\u254B</c2>"],Q:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2513\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2513\u2503</c1>","<c2>\u254B\u254B</c2><c1>\u2517\u251B</c1>"],R:["<c2>\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2513</c1>","<c1>\u2503\u250F\u251B</c1>","<c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B</c2>"],S:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2503\u2501\u2501\u252B</c1>","<c1>\u2523\u2501\u2501\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],T:["<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2503\u2517\u2513</c1>","<c2>\u254B</c2><c1>\u2517\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],U:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],V:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u2503</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],W:["<c2>\u254B\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513\u250F\u2513</c1>","<c1>\u2503\u2517\u251B\u2517\u251B\u2503</c1>","<c1>\u2517\u2513\u250F\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B\u254B\u254B</c2>"],X:["<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2517\u254B\u254B\u251B</c1>","<c1>\u250F\u254B\u254B\u2513</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>"],Y:["<c2>\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2513</c1><c2>\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2513\u250F\u251B</c1>","<c1>\u2517\u2501\u2501\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B\u254B</c2>"],Z:["<c2>\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2523\u2501\u2501\u2503\u2503</c1>","<c1>\u2503\u2503\u2501\u2501\u252B</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B\u254B</c2>"],"0":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2503\u2503\u2503\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"1":["<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2503</c1><c2>\u254B</c2>","<c1>\u2517\u2513\u2503</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>"],"2":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c1>\u250F\u2501\u251B\u250F\u251B</c1>","<c1>\u2503\u2517\u2501\u253B\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"3":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c1>\u250F\u2513\u2517\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"4":["<c1>\u250F\u2513</c1><c2>\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u2503\u2503</c1><c2>\u254B</c2><c1>\u2503\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2513\u2503</c1>","<c2>\u254B\u254B\u254B</c2><c1>\u2503\u2503</c1>","<c2>\u254B\u254B\u254B</c2><c1>\u2517\u251B</c1>"],"5":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2501\u251B</c1>","<c1>\u2503\u2517\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u2513\u2503</c1>","<c1>\u250F\u2501\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"6":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2501\u251B</c1>","<c1>\u2503\u2517\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"7":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c2>\u254B\u254B</c2><c1>\u2503\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c2>\u254B\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>"],"8":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"9":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2503\u2517\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2513\u2503</c1>","<c1>\u250F\u2501\u2501\u251B\u2503</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>"],"!":["<c1>\u250F\u2513</c1>","<c1>\u2503\u2503</c1>","<c1>\u2503\u2503</c1>","<c1>\u2517\u251B</c1>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>"],"?":["<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2503\u250F\u2501\u2513\u2503</c1>","<c1>\u2517\u251B\u250F\u251B\u2503</c1>","<c2>\u254B\u254B</c2><c1>\u2503\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c2>\u254B\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>"],".":["<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>"],"+":["<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],"-":["<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"],_:["<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u251B</c1>"],"=":["<c2>\u254B\u254B\u254B\u254B\u254B</c2>","<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>","<c1>\u250F\u2501\u2501\u2501\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u251B</c1>","<c2>\u254B\u254B\u254B\u254B\u254B</c2>"],"@":["<c1>\u250F\u2501\u2501\u2501\u2501\u2513</c1><c2>\u254B</c2>","<c1>\u2503\u250F\u2501\u2501\u2513\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2503\u250F\u2501\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2503\u2517\u251B\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u2503\u2517\u2501\u2501\u251B\u2517\u2513</c1>","<c1>\u2517\u2501\u2501\u2501\u2501\u2501\u251B</c1>"],"#":["<c2>\u254B</c2><c1>\u250F\u2501\u2501\u2501\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u250F\u2501\u2513\u2517\u2513</c1>","<c1>\u2517\u2513\u2503\u2503\u2503\u250F\u251B</c1>","<c1>\u250F\u251B\u2503\u2503\u2503\u2517\u2513</c1>","<c1>\u2517\u2513\u2517\u2501\u251B\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u2501\u2501\u2501\u251B</c1><c2>\u254B</c2>"],$:["<c2>\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c1>\u250F\u251B\u2517\u2513</c1>","<c1>\u2503\u2501\u2501\u252B</c1>","<c1>\u2523\u2501\u2501\u2503</c1>","<c1>\u2517\u2513\u250F\u251B</c1>","<c2>\u254B</c2><c1>\u2517\u251B</c1><c2>\u254B</c2>"],"%":["<c1>\u250F\u2513</c1><c2>\u254B\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c1>\u2517\u251B</c1><c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B\u254B</c2>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2><c1>\u250F\u2513</c1>","<c1>\u2517\u2501\u251B</c1><c2>\u254B\u254B</c2><c1>\u2517\u251B</c1>"],"&":["<c2>\u254B\u254B</c2><c1>\u250F\u2513</c1><c2>\u254B</c2>","<c2>\u254B\u254B</c2><c1>\u2503\u2503</c1><c2>\u254B</c2>","<c1>\u250F\u2501\u251B\u2517\u2513</c1>","<c1>\u2503\u250F\u2513\u250F\u251B</c1>","<c1>\u2503\u2517\u251B\u2503</c1><c2>\u254B</c2>","<c1>\u2517\u2501\u2501\u251B</c1><c2>\u254B</c2>"],"(":["<c2>\u254B\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c1>\u2517\u2513\u2517\u2513</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2517\u2513\u2517\u2513</c1>","<c2>\u254B\u254B</c2><c1>\u2517\u2501\u251B</c1>"],")":["<c1>\u250F\u2501\u2513</c1><c2>\u254B\u254B</c2>","<c1>\u2517\u2513\u2517\u2513</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u2517\u2513\u2517\u2513</c1>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c1>\u2517\u2501\u251B</c1><c2>\u254B\u254B</c2>"],"/":["<c2>\u254B\u254B\u254B\u254B</c2><c1>\u250F\u2501\u2513</c1>","<c2>\u254B\u254B\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1>","<c2>\u254B\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B</c2>","<c2>\u254B</c2><c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B\u254B</c2>","<c1>\u250F\u251B\u250F\u251B</c1><c2>\u254B\u254B\u254B</c2>","<c1>\u2517\u2501\u251B</c1><c2>\u254B\u254B\u254B\u254B</c2>"],":":["<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>"],";":["<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u252B</c1>"],",":["<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c1>\u250F\u2513</c1>","<c1>\u2517\u252B</c1>"],"'":["<c1>\u250F\u2513</c1>","<c1>\u2517\u251B</c1>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>"],'"':["<c1>\u250F\u2513\u250F\u2513</c1>","<c1>\u2517\u251B\u2517\u251B</c1>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>","<c2>\u254B\u254B\u254B\u254B</c2>"]," ":["<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>","<c2>\u254B\u254B</c2>"]}},pallet_default={name:"pallet",version:"0.1.0",homepage:"https://github.com/dominikwilkowski/cfonts",colors:2,lines:6,buffer:["","","","","",""],letterspace:["<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>","<c2>\u2500</c2>"],letterspace_size:1,chars:{A:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>"],B:["<c1>\u2554\u2550\u2550\u2557</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u255A\u255D\u255A\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],C:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],D:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2557\u2554\u2557\u2551</c1>","<c2>\u2500</c2><c1>\u2551\u2551\u2551\u2551</c1>","<c2>\u2500</c2><c1>\u2551\u2551\u2551\u2551</c1>","<c1>\u2554\u255D\u255A\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],E:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],F:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u255A\u255D</c1><c2>\u2500\u2500\u2500</c2>"],G:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>","<c1>\u2551\u2551\u2554\u2550\u2557</c1>","<c1>\u2551\u255A\u2569\u2550\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],H:["<c1>\u2554\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u255A\u255D</c1>"],I:["<c1>\u2554\u2550\u2550\u2557</c1>","<c1>\u255A\u2563\u2560\u255D</c1>","<c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2554\u2563\u2560\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],J:["<c2>\u2500\u2500</c2><c1>\u2554\u2557</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2554\u2557\u2551\u2551</c1>","<c1>\u2551\u255A\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],K:["<c1>\u2554\u2557\u2554\u2550\u2557</c1>","<c1>\u2551\u2551\u2551\u2554\u255D</c1>","<c1>\u2551\u255A\u255D\u255D</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551\u2551\u255A\u2557</c1>","<c1>\u255A\u255D\u255A\u2550\u255D</c1>"],L:["<c1>\u2554\u2557</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],M:["<c1>\u2554\u2550\u2557\u2554\u2550\u2557</c1>","<c1>\u2551\u2551\u255A\u255D\u2551\u2551</c1>","<c1>\u2551\u2554\u2557\u2554\u2557\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u255A\u255D\u255A\u255D\u255A\u255D</c1>"],N:["<c1>\u2554\u2550\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551\u255A\u2557\u2551\u2551</c1>","<c1>\u2551\u2554\u2557\u255A\u255D\u2551</c1>","<c1>\u2551\u2551\u255A\u2557\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551\u2551</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u255A\u2550\u255D</c1>"],O:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],P:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u2551</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u255A\u255D</c1><c2>\u2500\u2500\u2500</c2>"],Q:["<c1>\u2554\u2550\u2550\u2550\u2557</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2550\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u255A\u2550\u255D\u2560\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u2550\u255D</c1>"],R:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2557\u2554\u255D</c1>","<c1>\u2551\u2551\u2551\u255A\u2557</c1>","<c1>\u255A\u255D\u255A\u2550\u255D</c1>"],S:["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],T:["<c1>\u2554\u2550\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2557\u2554\u2557\u2551</c1>","<c1>\u255A\u255D\u2551\u2551\u255A\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500\u2500</c2>"],U:["<c1>\u2554\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],V:["<c1>\u2554\u2557</c1><c2>\u2500\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2557\u2554\u255D\u2551</c1>","<c1>\u255A\u2557\u2551\u2551\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u2551\u255A\u255D\u2551</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u255A\u2557\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500\u2500</c2>"],W:["<c1>\u2554\u2557\u2554\u2557\u2554\u2557</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u255A\u255D\u255A\u255D\u2551</c1>","<c1>\u255A\u2557\u2554\u2557\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u255D\u255A\u255D</c1><c2>\u2500</c2>"],X:["<c1>\u2554\u2550\u2557\u2554\u2550\u2557</c1>","<c1>\u255A\u2557\u255A\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u2557\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u255D\u255A\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2554\u2557\u255A\u2557</c1>","<c1>\u255A\u2550\u255D\u255A\u2550\u255D</c1>"],Y:["<c1>\u2554\u2557</c1><c2>\u2500\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u255A\u2557\u2554\u255D\u2551</c1>","<c1>\u255A\u2557\u255A\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u2557\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500\u2500</c2>"],Z:["<c1>\u2554\u2550\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2550\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2550\u255A\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u2550\u255D</c1>"],"0":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u2551\u2551\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"1":["<c2>\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2551</c1><c2>\u2500</c2>","<c1>\u255A\u2557\u2551</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u255A\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],"2":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c1>\u2554\u2550\u255D\u2554\u255D</c1>","<c1>\u2551\u2551\u255A\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"3":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c1>\u2554\u2557\u255A\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"4":["<c1>\u2554\u2557</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1><c2>\u2500</c2><c1>\u2551\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c2>\u2500\u2500\u2500</c2><c1>\u2551\u2551</c1>","<c2>\u2500\u2500\u2500</c2><c1>\u255A\u255D</c1>"],"5":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2554\u2550\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"6":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2550\u255D</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"7":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500</c2>"],"8":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"9":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2554\u2550\u2550\u255D\u2551</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>"],"!":["<c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1>","<c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>"],"?":["<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u255A\u255D\u2554\u255D\u2551</c1>","<c2>\u2500\u2500</c2><c1>\u2551\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500</c2>"],".":["<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>"],"+":["<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u255A\u2557</c1>","<c1>\u255A\u2557\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u255D</c1><c2>\u2500</c2>"],"-":["<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c1>\u2554\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>"],_:["<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c1>\u2554\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u255D</c1>"],"=":["<c2>\u2500\u2500\u2500\u2500\u2500</c2>","<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>","<c1>\u2554\u2550\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u255D</c1>","<c2>\u2500\u2500\u2500\u2500\u2500</c2>"],"@":["<c1>\u2554\u2550\u2550\u2550\u2550\u2557</c1><c2>\u2500</c2>","<c1>\u2551\u2554\u2550\u2550\u2557\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551\u2554\u2550\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u2551\u255A\u255D\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2551\u255A\u2550\u2550\u255D\u2560\u2557</c1>","<c1>\u255A\u2550\u2550\u2550\u2550\u2550\u255D</c1>"],"#":["<c2>\u2500</c2><c1>\u2554\u2569\u2569\u2569\u2557</c1><c2>\u2500</c2>","<c1>\u2554\u255D\u2554\u2550\u2557\u255A\u2557</c1>","<c1>\u255A\u2557\u2560\u2550\u2563\u2554\u255D</c1>","<c1>\u2554\u255D\u2560\u2550\u2563\u255A\u2557</c1>","<c1>\u255A\u2557\u255A\u2550\u255D\u2554\u255D</c1>","<c2>\u2500</c2><c1>\u255A\u2566\u2566\u2566\u255D</c1><c2>\u2500</c2>"],$:["<c1>\u2554\u255D\u2569\u255A\u2557</c1>","<c1>\u2551\u2554\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u2550\u2557</c1>","<c1>\u255A\u2550\u2550\u2557\u2551</c1>","<c1>\u2551\u255A\u2550\u255D\u2551</c1>","<c1>\u255A\u2557\u2566\u2554\u255D</c1>"],"%":["<c1>\u2554\u2557</c1><c2>\u2500\u2500</c2><c1>\u2554\u2550\u2557</c1>","<c1>\u255A\u255D</c1><c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500\u2500</c2>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2><c1>\u2554\u2557</c1>","<c1>\u255A\u2550\u255D</c1><c2>\u2500\u2500</c2><c1>\u255A\u255D</c1>"],"&":["<c2>\u2500\u2500</c2><c1>\u2554\u2557</c1><c2>\u2500</c2>","<c2>\u2500\u2500</c2><c1>\u2551\u2551</c1><c2>\u2500</c2>","<c1>\u2554\u2550\u255D\u255A\u2557</c1>","<c1>\u2551\u2554\u2557\u2554\u255D</c1>","<c1>\u2551\u255A\u255D\u2551</c1><c2>\u2500</c2>","<c1>\u255A\u2550\u2550\u255D</c1><c2>\u2500</c2>"],"(":["<c2>\u2500\u2500</c2><c1>\u2554\u2550\u2557</c1>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c1>\u255A\u2557\u255A\u2557</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u255A\u2557\u255A\u2557</c1>","<c2>\u2500\u2500</c2><c1>\u255A\u2550\u255D</c1>"],")":["<c1>\u2554\u2550\u2557</c1><c2>\u2500\u2500</c2>","<c1>\u255A\u2557\u255A\u2557</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u255A\u2557\u255A\u2557</c1>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c1>\u255A\u2550\u255D</c1><c2>\u2500\u2500</c2>"],"/":["<c2>\u2500\u2500\u2500\u2500</c2><c1>\u2554\u2550\u2557</c1>","<c2>\u2500\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1>","<c2>\u2500\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500</c2>","<c2>\u2500</c2><c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500\u2500</c2>","<c1>\u2554\u255D\u2554\u255D</c1><c2>\u2500\u2500\u2500</c2>","<c1>\u255A\u2550\u255D</c1><c2>\u2500\u2500\u2500\u2500</c2>"],":":["<c2>\u2500\u2500</c2>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>","<c1>\u2554\u2557</c1>","<c1>\u255A\u255D</c1>","<c2>\u2500\u2500</c2>"],";":["<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c1>\u2554\u2557</c1>","<c1>\u255A\u2563</c1>","<c2>\u2500</c2><c1>\u255D</c1>"],",":["<c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1>","<c1>\u2554\u2557</c1>","<c1>\u255A\u2563</c1>","<c2>\u2500</c2><c1>\u255D</c1>"],"'":["<c1>\u2554\u2557</c1>","<c1>\u2551\u2551</c1>","<c1>\u255A\u255D</c1>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>","<c2>\u2500\u2500</c2>"],'"':["<c1>\u2554\u2557\u2554\u2557</c1>","<c1>\u2551\u2551\u2551\u2551</c1>","<c1>\u255A\u255D\u255A\u255D</c1>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500\u2500</c2>"]," ":["<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>","<c2>\u2500\u2500\u2500</c2>"]}},fonts={tiny:tiny_default,block:block_default,shade:shade_default,slick:slick_default,huge:huge_default,grid:grid_default,pallet:pallet_default},parsedFonts={};function parseColorTags(text){let segments=[],currentIndex=0,colorTagRegex=/<c(\d+)>(.*?)<\/c\d+>/g,lastIndex=0,match;while((match=colorTagRegex.exec(text))!==null){if(match.index>lastIndex){let plainText=text.slice(lastIndex,match.index);if(plainText)segments.push({text:plainText,colorIndex:0})}let colorIndex=parseInt(match[1])-1,taggedText=match[2];segments.push({text:taggedText,colorIndex:Math.max(0,colorIndex)}),lastIndex=match.index+match[0].length}if(lastIndex<text.length){let remainingText=text.slice(lastIndex);if(remainingText)segments.push({text:remainingText,colorIndex:0})}return segments}function getParsedFont(fontKey){if(!parsedFonts[fontKey]){let fontDef=fonts[fontKey],parsedChars={};for(let[char,lines]of Object.entries(fontDef.chars))parsedChars[char]=lines.map((line)=>parseColorTags(line));parsedFonts[fontKey]={...fontDef,colors:fontDef.colors||1,chars:parsedChars}}return parsedFonts[fontKey]}function measureText({text,font="tiny"}){let fontDef=getParsedFont(font);if(!fontDef)return console.warn(`Font '${font}' not found`),{width:0,height:0};let currentX=0;for(let i=0;i<text.length;i++){let char=text[i].toUpperCase(),charDef=fontDef.chars[char];if(!charDef){let spaceChar=fontDef.chars[" "];if(spaceChar&&spaceChar[0]){let spaceWidth=0;for(let segment of spaceChar[0])spaceWidth+=segment.text.length;currentX+=spaceWidth}else currentX+=1;continue}let charWidth=0;if(charDef[0])for(let segment of charDef[0])charWidth+=segment.text.length;if(currentX+=charWidth,i<text.length-1)currentX+=fontDef.letterspace_size}return{width:currentX,height:fontDef.lines}}function getCharacterPositions(text,font="tiny"){let fontDef=getParsedFont(font);if(!fontDef)return[0];let positions=[0],currentX=0;for(let i=0;i<text.length;i++){let char=text[i].toUpperCase(),charDef=fontDef.chars[char],charWidth=0;if(!charDef){let spaceChar=fontDef.chars[" "];if(spaceChar&&spaceChar[0])for(let segment of spaceChar[0])charWidth+=segment.text.length;else charWidth=1}else if(charDef[0])for(let segment of charDef[0])charWidth+=segment.text.length;if(currentX+=charWidth,i<text.length-1)currentX+=fontDef.letterspace_size;positions.push(currentX)}return positions}function coordinateToCharacterIndex(x,text,font="tiny"){let positions=getCharacterPositions(text,font);if(x<0)return 0;for(let i=0;i<positions.length-1;i++){let currentPos=positions[i],nextPos=positions[i+1];if(x>=currentPos&&x<nextPos){let charMidpoint=currentPos+(nextPos-currentPos)/2;return x<charMidpoint?i:i+1}}if(positions.length>0&&x>=positions[positions.length-1])return text.length;return 0}function renderFontToFrameBuffer(buffer,{text,x=0,y=0,color=[RGBA.fromInts(255,255,255,255)],backgroundColor=RGBA.fromInts(0,0,0,255),font="tiny"}){let{width,height}=buffer,fontDef=getParsedFont(font);if(!fontDef)return console.warn(`Font '${font}' not found`),{width:0,height:0};let colors=Array.isArray(color)?color:[color];if(y<0||y+fontDef.lines>height)return{width:0,height:fontDef.lines};let currentX=x,startX=x;for(let i=0;i<text.length;i++){let char=text[i].toUpperCase(),charDef=fontDef.chars[char];if(!charDef){let spaceChar=fontDef.chars[" "];if(spaceChar&&spaceChar[0]){let spaceWidth=0;for(let segment of spaceChar[0])spaceWidth+=segment.text.length;currentX+=spaceWidth}else currentX+=1;continue}let charWidth=0;if(charDef[0])for(let segment of charDef[0])charWidth+=segment.text.length;if(currentX>=width)break;if(currentX+charWidth<0){currentX+=charWidth+fontDef.letterspace_size;continue}for(let lineIdx=0;lineIdx<fontDef.lines&&lineIdx<charDef.length;lineIdx++){let segments=charDef[lineIdx],renderY=y+lineIdx;if(renderY>=0&&renderY<height){let segmentX=currentX;for(let segment of segments){let segmentColor=colors[segment.colorIndex]||colors[0];for(let charIdx=0;charIdx<segment.text.length;charIdx++){let renderX=segmentX+charIdx;if(renderX>=0&&renderX<width){let fontChar=segment.text[charIdx];if(fontChar!==" ")buffer.setCellWithAlphaBlending(renderX,renderY,fontChar,parseColor(segmentColor),parseColor(backgroundColor))}}segmentX+=segment.text.length}}}if(currentX+=charWidth,i<text.length-1)currentX+=fontDef.letterspace_size}return{width:currentX-startX,height:fontDef.lines}}var TextAttributes={NONE:0,BOLD:1,DIM:2,ITALIC:4,UNDERLINE:8,BLINK:16,INVERSE:32,HIDDEN:64,STRIKETHROUGH:128};var DebugOverlayCorner;((DebugOverlayCorner2)=>{DebugOverlayCorner2[DebugOverlayCorner2.topLeft=0]="topLeft",DebugOverlayCorner2[DebugOverlayCorner2.topRight=1]="topRight",DebugOverlayCorner2[DebugOverlayCorner2.bottomLeft=2]="bottomLeft",DebugOverlayCorner2[DebugOverlayCorner2.bottomRight=3]="bottomRight"})(DebugOverlayCorner||={});var TargetChannel;((TargetChannel2)=>{TargetChannel2[TargetChannel2.FG=1]="FG",TargetChannel2[TargetChannel2.BG=2]="BG",TargetChannel2[TargetChannel2.Both=3]="Both"})(TargetChannel||={});function createTextAttributes({bold=!1,italic=!1,underline=!1,dim=!1,blink=!1,inverse=!1,hidden=!1,strikethrough=!1}={}){let attributes=TextAttributes.NONE;if(bold)attributes|=TextAttributes.BOLD;if(italic)attributes|=TextAttributes.ITALIC;if(underline)attributes|=TextAttributes.UNDERLINE;if(dim)attributes|=TextAttributes.DIM;if(blink)attributes|=TextAttributes.BLINK;if(inverse)attributes|=TextAttributes.INVERSE;if(hidden)attributes|=TextAttributes.HIDDEN;if(strikethrough)attributes|=TextAttributes.STRIKETHROUGH;return attributes}var BrandedStyledText=Symbol.for("@opentui/core/StyledText");function isStyledText(obj){return obj&&obj[BrandedStyledText]}class StyledText{[BrandedStyledText]=!0;chunks;constructor(chunks){this.chunks=chunks}}function stringToStyledText(content){return new StyledText([{__isChunk:!0,text:content}])}function applyStyle(input,style){if(typeof input==="object"&&"__isChunk"in input){let existingChunk=input,fg=style.fg?parseColor(style.fg):existingChunk.fg,bg=style.bg?parseColor(style.bg):existingChunk.bg,newAttrs=createTextAttributes(style),mergedAttrs=existingChunk.attributes?existingChunk.attributes|newAttrs:newAttrs;return{__isChunk:!0,text:existingChunk.text,fg,bg,attributes:mergedAttrs,link:existingChunk.link}}else{let plainTextStr=String(input),fg=style.fg?parseColor(style.fg):void 0,bg=style.bg?parseColor(style.bg):void 0,attributes=createTextAttributes(style);return{__isChunk:!0,text:plainTextStr,fg,bg,attributes}}}var fg=(color)=>(input)=>applyStyle(input,{fg:color});class SystemClock{now(){if(!globalThis.performance||typeof globalThis.performance.now!=="function")throw Error("SystemClock requires globalThis.performance.now()");return globalThis.performance.now()}setTimeout(fn,delayMs){return globalThis.setTimeout(fn,delayMs)}clearTimeout(handle){globalThis.clearTimeout(handle)}setInterval(fn,delayMs){return globalThis.setInterval(fn,delayMs)}clearInterval(handle){globalThis.clearInterval(handle)}}var kittyKeyMap={27:"escape",9:"tab",13:"return",127:"backspace",57344:"escape",57345:"return",57346:"tab",57347:"backspace",57348:"insert",57349:"delete",57350:"left",57351:"right",57352:"up",57353:"down",57354:"pageup",57355:"pagedown",57356:"home",57357:"end",57358:"capslock",57359:"scrolllock",57360:"numlock",57361:"printscreen",57362:"pause",57363:"menu",57364:"f1",57365:"f2",57366:"f3",57367:"f4",57368:"f5",57369:"f6",57370:"f7",57371:"f8",57372:"f9",57373:"f10",57374:"f11",57375:"f12",57376:"f13",57377:"f14",57378:"f15",57379:"f16",57380:"f17",57381:"f18",57382:"f19",57383:"f20",57384:"f21",57385:"f22",57386:"f23",57387:"f24",57388:"f25",57389:"f26",57390:"f27",57391:"f28",57392:"f29",57393:"f30",57394:"f31",57395:"f32",57396:"f33",57397:"f34",57398:"f35",57399:"kp0",57400:"kp1",57401:"kp2",57402:"kp3",57403:"kp4",57404:"kp5",57405:"kp6",57406:"kp7",57407:"kp8",57408:"kp9",57409:"kpdecimal",57410:"kpdivide",57411:"kpmultiply",57412:"kpminus",57413:"kpplus",57414:"kpenter",57415:"kpequal",57416:"kpseparator",57417:"kpleft",57418:"kpright",57419:"kpup",57420:"kpdown",57421:"kppageup",57422:"kppagedown",57423:"kphome",57424:"kpend",57425:"kpinsert",57426:"kpdelete",57427:"clear",57428:"mediaplay",57429:"mediapause",57430:"mediaplaypause",57431:"mediareverse",57432:"mediastop",57433:"mediafastforward",57434:"mediarewind",57435:"medianext",57436:"mediaprev",57437:"mediarecord",57438:"volumedown",57439:"volumeup",57440:"mute",57441:"leftshift",57442:"leftctrl",57443:"leftalt",57444:"leftsuper",57445:"lefthyper",57446:"leftmeta",57447:"rightshift",57448:"rightctrl",57449:"rightalt",57450:"rightsuper",57451:"righthyper",57452:"rightmeta",57453:"iso_level3_shift",57454:"iso_level5_shift"},kittyNamedSingleStrokeKeys=[...new Set(Object.values(kittyKeyMap))],printableKeypadText={kp0:"0",kp1:"1",kp2:"2",kp3:"3",kp4:"4",kp5:"5",kp6:"6",kp7:"7",kp8:"8",kp9:"9",kpdecimal:".",kpdivide:"/",kpmultiply:"*",kpminus:"-",kpplus:"+",kpequal:"=",kpseparator:","};function getPrintableKittyKeyText(key){return printableKeypadText[key.name]}function fromKittyMods(mod){return{shift:!!(mod&1),alt:!!(mod&2),ctrl:!!(mod&4),super:!!(mod&8),hyper:!!(mod&16),meta:!!(mod&32),capsLock:!!(mod&64),numLock:!!(mod&128)}}var functionalKeyMap={A:"up",B:"down",C:"right",D:"left",H:"home",F:"end",E:"clear",P:"f1",Q:"f2",S:"f4"},tildeKeyMap={"1":"home","2":"insert","3":"delete","4":"end","5":"pageup","6":"pagedown","7":"home","8":"end","11":"f1","12":"f2","13":"f3","14":"f4","15":"f5","17":"f6","18":"f7","19":"f8","20":"f9","21":"f10","23":"f11","24":"f12","29":"menu","57427":"clear"};function parseKittySpecialKey(sequence){let match=/^\x1b\[(\d+);(\d+):(\d+)([A-Z~])$/.exec(sequence);if(!match)return null;let keyNumOrOne=match[1],modifierStr=match[2],eventTypeStr=match[3],terminator=match[4],keyName;if(terminator==="~")keyName=tildeKeyMap[keyNumOrOne];else{if(keyNumOrOne!=="1")return null;keyName=functionalKeyMap[terminator]}if(!keyName)return null;let key={name:keyName,ctrl:!1,meta:!1,shift:!1,option:!1,number:!1,sequence,raw:sequence,eventType:"press",source:"kitty",super:!1,hyper:!1,capsLock:!1,numLock:!1};if(modifierStr){let modifierMask=parseInt(modifierStr,10);if(!isNaN(modifierMask)&&modifierMask>1){let mods=fromKittyMods(modifierMask-1);key.shift=mods.shift,key.ctrl=mods.ctrl,key.meta=mods.alt||mods.meta,key.option=mods.alt,key.super=mods.super,key.hyper=mods.hyper,key.capsLock=mods.capsLock,key.numLock=mods.numLock}}if(eventTypeStr==="1"||!eventTypeStr)key.eventType="press";else if(eventTypeStr==="2")key.eventType="press",key.repeated=!0;else if(eventTypeStr==="3")key.eventType="release";return key}function parseKittyKeyboard(sequence){let specialResult=parseKittySpecialKey(sequence);if(specialResult)return specialResult;let match=/^\x1b\[([^\x1b]+)u$/.exec(sequence);if(!match)return null;let fields=match[1].split(";");if(fields.length<1)return null;let key={name:"",ctrl:!1,meta:!1,shift:!1,option:!1,number:!1,sequence,raw:sequence,eventType:"press",source:"kitty",super:!1,hyper:!1,capsLock:!1,numLock:!1},text="",field1=fields[0]?.split(":")||[],codepointStr=field1[0];if(!codepointStr)return null;let codepoint=parseInt(codepointStr,10);if(isNaN(codepoint))return null;let shiftedCodepoint,baseCodepoint;if(field1[1]){let shifted=parseInt(field1[1],10);if(!isNaN(shifted)&&shifted>0&&shifted<=1114111)shiftedCodepoint=shifted}if(field1[2]){let base=parseInt(field1[2],10);if(!isNaN(base)&&base>0&&base<=1114111)baseCodepoint=base}let knownKey=kittyKeyMap[codepoint];if(knownKey)key.name=knownKey,key.code=`[${codepoint}u`;else if(codepoint===0)key.name="";else if(codepoint>0&&codepoint<=1114111){let char=String.fromCodePoint(codepoint);if(key.name=char===" "?"space":char,baseCodepoint)key.baseCode=baseCodepoint}else return null;if(fields[1]){let field2=fields[1].split(":"),modifierStr=field2[0],eventTypeStr=field2[1];if(modifierStr){let modifierMask=parseInt(modifierStr,10);if(!isNaN(modifierMask)&&modifierMask>1){let mods=fromKittyMods(modifierMask-1);key.shift=mods.shift,key.ctrl=mods.ctrl,key.meta=mods.alt||mods.meta,key.option=mods.alt,key.super=mods.super,key.hyper=mods.hyper,key.capsLock=mods.capsLock,key.numLock=mods.numLock}}if(eventTypeStr==="1"||!eventTypeStr)key.eventType="press";else if(eventTypeStr==="2")key.eventType="press",key.repeated=!0;else if(eventTypeStr==="3")key.eventType="release";else key.eventType="press"}if(fields[2]){let codepoints=fields[2].split(":");for(let cpStr of codepoints){let cp=parseInt(cpStr,10);if(!isNaN(cp)&&cp>0&&cp<=1114111)text+=String.fromCodePoint(cp)}}if(text==="")text=getPrintableKittyKeyText(key)??"";if(text===""){if(key.name.length>0&&!kittyKeyMap[codepoint])if(codepoint===32)text=" ";else if(key.shift&&shiftedCodepoint)text=String.fromCodePoint(shiftedCodepoint);else if(key.shift&&key.name.length===1)text=key.name.toLocaleUpperCase();else text=key.name}if(text){if(codepoint===0)key.name=text;key.sequence=text}if(codepoint===0&&text==="")return null;return key}var metaKeyCodeRe=/^(?:\x1b)([a-zA-Z0-9])$/,fnKeyRe=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,keyName={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[29~":"menu","[57427~":"clear","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home","[P":"f1","[Q":"f2","[S":"f4",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home",OM:"return",Oj:"*",Ok:"+",Ol:",",Om:"-",On:".",Oo:"/",Op:"0",Oq:"1",Or:"2",Os:"3",Ot:"4",Ou:"5",Ov:"6",Ow:"7",Ox:"8",Oy:"9",OX:"=","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear",f:"right",b:"left",p:"up",n:"down","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"},nonAlphanumericKeys=[...Object.values(keyName),"backspace"],terminalNamedSingleStrokeKeys=[...new Set(["return","linefeed","tab","escape","space",...nonAlphanumericKeys,...kittyNamedSingleStrokeKeys])],isShiftKey=(code)=>{return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(code)},isCtrlKey=(code)=>{return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(code)},getCtrlKeyName=(charCode)=>{if(charCode===0)return"space";if(charCode>=1&&charCode<=26)return String.fromCharCode(charCode+97-1);if(charCode>=28&&charCode<=31)return String.fromCharCode(charCode+64);return},ss3NumpadPrintable={Op:"0",Oq:"1",Or:"2",Os:"3",Ot:"4",Ou:"5",Ov:"6",Ow:"7",Ox:"8",Oy:"9",Oj:"*",Ok:"+",Ol:",",Om:"-",On:".",Oo:"/",OX:"="},modifyOtherKeysRe=/^\x1b\[27;(\d+);(\d+)~$/,parseKeypress=(s="",options={})=>{let parts;if(Buffer2.isBuffer(s))if(s[0]>127&&s[1]===void 0)s[0]-=128,s="\x1B"+String(s);else s=String(s);else if(s!==void 0&&typeof s!=="string")s=String(s);else if(!s)s="";if(/^\x1b\[<\d+;\d+;\d+[Mm]$/.test(s))return null;if(/^\[<\d+;\d+;\d+[Mm]$/.test(s))return null;if(/^\x1b\[<[\d;]*$/.test(s))return null;if(/^\[<[\d;]*$/.test(s))return null;if(s.startsWith("\x1B[M")&&s.length>=6)return null;if(/^\x1b\[\d+;\d+;\d+t$/.test(s))return null;if(/^\x1b\[\d+;\d+R$/.test(s))return null;if(/^\x1b\[\?[\d;]+c$/.test(s))return null;if(/^\x1b\[\?[\d;]+\$y$/.test(s))return null;if(s==="\x1B[I"||s==="\x1B[O")return null;if(/^\x1b\][\d;].*(\x1b\\|\x07)$/.test(s))return null;if(s==="\x1B[200~"||s==="\x1B[201~")return null;let key={name:"",ctrl:!1,meta:!1,shift:!1,option:!1,number:!1,sequence:s,raw:s,eventType:"press",source:"raw"};key.sequence=key.sequence||s||key.name;let ctrlKeyName=s.length===1?getCtrlKeyName(s.charCodeAt(0)):void 0,metaCtrlKeyName=s.length===2&&s[0]==="\x1B"?getCtrlKeyName(s.charCodeAt(1)):void 0;if(options.useKittyKeyboard){let kittyResult=parseKittyKeyboard(s);if(kittyResult)return kittyResult}let modifyOtherKeysMatch=modifyOtherKeysRe.exec(s);if(modifyOtherKeysMatch){let modifier=parseInt(modifyOtherKeysMatch[1],10)-1,charCode=parseInt(modifyOtherKeysMatch[2],10);if(key.ctrl=!!(modifier&4),key.meta=!!(modifier&2),key.shift=!!(modifier&1),key.option=!!(modifier&2),key.super=!!(modifier&8),key.hyper=!!(modifier&16),charCode===13)key.name="return";else if(charCode===27)key.name="escape";else if(charCode===9)key.name="tab";else if(charCode===32)key.name="space";else if(charCode===127||charCode===8)key.name="backspace";else{let char=String.fromCharCode(charCode);if(key.name=char,key.sequence=char,charCode>=48&&charCode<=57)key.number=!0}return key}if(s==="\r"||s==="\x1B\r")key.name="return",key.meta=s.length===2;else if(s===`
3512
3512
  `||s===`\x1B
3513
3513
  `)key.name="linefeed",key.meta=s.length===2;else if(s==="\t")key.name="tab";else if(s==="\b"||s==="\x1B\b"||s==="\x7F"||s==="\x1B\x7F")key.name="backspace",key.meta=s.charAt(0)==="\x1B";else if(s==="\x1B"||s==="\x1B\x1B")key.name="escape",key.meta=s.length===2;else if(s===" "||s==="\x1B ")key.name="space",key.meta=s.length===2;else if(ctrlKeyName)key.name=ctrlKeyName,key.ctrl=!0;else if(s.length===1&&s>="0"&&s<="9")key.name=s,key.number=!0;else if(s.length===1&&s>="a"&&s<="z")key.name=s;else if(s.length===1&&s>="A"&&s<="Z")key.name=s.toLowerCase(),key.shift=!0;else if(s.length===1||s.length===2&&s.codePointAt(0)>65535)key.name=s;else if(parts=metaKeyCodeRe.exec(s)){key.meta=!0;let char=parts[1],isUpperCase=/^[A-Z]$/.test(char);if(char==="F")key.name="right";else if(char==="B")key.name="left";else if(isUpperCase)key.shift=!0,key.name=char;else key.name=char}else if(metaCtrlKeyName)key.meta=!0,key.ctrl=!0,key.name=metaCtrlKeyName;else if(parts=fnKeyRe.exec(s)){let segs=[...s];if(segs[0]==="\x1B"&&segs[1]==="\x1B")key.option=!0,key.meta=!0;let code=[parts[1],parts[2],parts[4],parts[6]].filter(Boolean).join(""),modifier=parseInt(parts[3]||parts[5]||"1",10)-1;key.ctrl=key.ctrl||!!(modifier&4),key.meta=key.meta||!!(modifier&2),key.shift=key.shift||!!(modifier&1),key.option=key.option||!!(modifier&2),key.super=!!(modifier&8),key.hyper=!!(modifier&16),key.code=code;let keyNameResult=keyName[code];if(keyNameResult){key.name=keyNameResult,key.shift=isShiftKey(code)||key.shift,key.ctrl=isCtrlKey(code)||key.ctrl;let ss3Char=ss3NumpadPrintable[code];if(ss3Char!==void 0){if(key.sequence=ss3Char,key.name>="0"&&key.name<="9")key.number=!0}}else key.name="",key.code=void 0}else if(s==="\x1B[3~")key.name="delete",key.meta=!1,key.code="[3~";return key};class LinearScrollAccel{tick(_now){return 1}reset(){}}function parseAlign(value){if(value==null)return 0;switch(value.toLowerCase()){case"auto":return 0;case"flex-start":return 1;case"center":return 2;case"flex-end":return 3;case"stretch":return 4;case"baseline":return 5;case"space-between":return 6;case"space-around":return 7;case"space-evenly":return 8;default:return 0}}function parseAlignItems(value){if(value==null)return 4;switch(value.toLowerCase()){case"auto":return 0;case"flex-start":return 1;case"center":return 2;case"flex-end":return 3;case"stretch":return 4;case"baseline":return 5;case"space-between":return 6;case"space-around":return 7;case"space-evenly":return 8;default:return 4}}function parseFlexDirection(value){if(value==null)return 0;switch(value.toLowerCase()){case"column":return 0;case"column-reverse":return 1;case"row":return 2;case"row-reverse":return 3;default:return 0}}function parseJustify(value){if(value==null)return 0;switch(value.toLowerCase()){case"flex-start":return 0;case"center":return 1;case"flex-end":return 2;case"space-between":return 3;case"space-around":return 4;case"space-evenly":return 5;default:return 0}}function parseOverflow(value){if(value==null)return 0;switch(value.toLowerCase()){case"visible":return 0;case"hidden":return 1;case"scroll":return 2;default:return 0}}function parsePositionType(value){if(value==null)return 1;switch(value.toLowerCase()){case"static":return 0;case"relative":return 1;case"absolute":return 2;default:return 0}}function parseWrap(value){if(value==null)return 0;switch(value.toLowerCase()){case"no-wrap":return 0;case"wrap":return 1;case"wrap-reverse":return 2;default:return 0}}class MouseParser{mouseButtonsPressed=new Set;static SCROLL_DIRECTIONS={0:"up",1:"down",2:"left",3:"right"};reset(){this.mouseButtonsPressed.clear()}decodeInput(data){return(Buffer.isBuffer(data)?data:Buffer.from(data.buffer,data.byteOffset,data.byteLength)).toString("latin1")}parseMouseEvent(data){let str=this.decodeInput(data);return this.parseMouseSequenceAt(str,0)?.event??null}parseAllMouseEvents(data){let str=this.decodeInput(data),events=[],offset=0;while(offset<str.length){let parsed=this.parseMouseSequenceAt(str,offset);if(!parsed)break;events.push(parsed.event),offset+=parsed.consumed}return events}parseMouseSequenceAt(str,offset){if(!str.startsWith("\x1B[",offset))return null;let introducer=str[offset+2];if(introducer==="<")return this.parseSgrSequence(str,offset);if(introducer==="M")return this.parseBasicSequence(str,offset);return null}parseSgrSequence(str,offset){let index=offset+3,values=[0,0,0],part=0,hasDigit=!1;while(index<str.length){let char=str[index],charCode=str.charCodeAt(index);if(charCode>=48&&charCode<=57){hasDigit=!0,values[part]=values[part]*10+(charCode-48),index++;continue}switch(char){case";":{if(!hasDigit||part>=2)return null;part++,hasDigit=!1,index++;break}case"M":case"m":{if(!hasDigit||part!==2)return null;return{event:this.decodeSgrEvent(values[0],values[1],values[2],char),consumed:index-offset+1}}default:return null}}return null}parseBasicSequence(str,offset){if(offset+6>str.length)return null;let buttonByte=str.charCodeAt(offset+3)-32,x=str.charCodeAt(offset+4)-33,y=str.charCodeAt(offset+5)-33;return{event:this.decodeBasicEvent(buttonByte,x,y),consumed:6}}decodeSgrEvent(rawButtonCode,wireX,wireY,pressRelease){let button=rawButtonCode&3,isScroll=(rawButtonCode&64)!==0,scrollDirection=!isScroll?void 0:MouseParser.SCROLL_DIRECTIONS[button],isMotion=(rawButtonCode&32)!==0,modifiers={shift:(rawButtonCode&4)!==0,alt:(rawButtonCode&8)!==0,ctrl:(rawButtonCode&16)!==0},type,scrollInfo;if(isMotion){let isDragging=this.mouseButtonsPressed.size>0;if(button===3)type="move";else if(isDragging)type="drag";else type="move"}else if(isScroll&&pressRelease==="M")type="scroll",scrollInfo={direction:scrollDirection,delta:1};else if(type=pressRelease==="M"?"down":"up",type==="down"&&button!==3)this.mouseButtonsPressed.add(button);else if(type==="up")this.mouseButtonsPressed.clear();return{type,button:button===3?0:button,x:wireX-1,y:wireY-1,modifiers,scroll:scrollInfo}}decodeBasicEvent(buttonByte,x,y){let button=buttonByte&3,isScroll=(buttonByte&64)!==0,isMotion=(buttonByte&32)!==0,scrollDirection=!isScroll?void 0:MouseParser.SCROLL_DIRECTIONS[button],modifiers={shift:(buttonByte&4)!==0,alt:(buttonByte&8)!==0,ctrl:(buttonByte&16)!==0},type,actualButton,scrollInfo;if(isMotion)type="move",actualButton=button===3?-1:button;else if(isScroll)type="scroll",actualButton=0,scrollInfo={direction:scrollDirection,delta:1};else type=button===3?"up":"down",actualButton=button===3?0:button;return{type,button:actualButton,x,y,modifiers,scroll:scrollInfo}}}class SelectionAnchor{renderable;relativeX;relativeY;constructor(renderable,absoluteX,absoluteY){this.renderable=renderable,this.relativeX=absoluteX-this.renderable.x,this.relativeY=absoluteY-this.renderable.y}get x(){return this.renderable.x+this.relativeX}get y(){return this.renderable.y+this.relativeY}}class Selection{_anchor;_focus;_selectedRenderables=[];_touchedRenderables=[];_isActive=!0;_isDragging=!0;_isStart=!1;constructor(anchorRenderable,anchor,focus){this._anchor=new SelectionAnchor(anchorRenderable,anchor.x,anchor.y),this._focus={...focus}}get isStart(){return this._isStart}set isStart(value){this._isStart=value}get anchor(){return{x:this._anchor.x,y:this._anchor.y}}get focus(){return{...this._focus}}set focus(value){this._focus={...value}}get isActive(){return this._isActive}set isActive(value){this._isActive=value}get isDragging(){return this._isDragging}set isDragging(value){this._isDragging=value}get bounds(){let minX=Math.min(this._anchor.x,this._focus.x),maxX=Math.max(this._anchor.x,this._focus.x),minY=Math.min(this._anchor.y,this._focus.y),maxY=Math.max(this._anchor.y,this._focus.y),width=maxX-minX+1,height=maxY-minY+1;return{x:minX,y:minY,width,height}}updateSelectedRenderables(selectedRenderables){this._selectedRenderables=selectedRenderables}get selectedRenderables(){return this._selectedRenderables}updateTouchedRenderables(touchedRenderables){this._touchedRenderables=touchedRenderables}get touchedRenderables(){return this._touchedRenderables}getSelectedText(){let selectedTextsByLine=new Map,selectedRenderables=this._selectedRenderables.sort((a,b)=>{let aY=a.y,bY=b.y;if(aY!==bY)return aY-bY;return a.x-b.x}).filter((renderable)=>!renderable.isDestroyed);for(let renderable of selectedRenderables){let text=renderable.getSelectedText();if(!text)continue;let lines=text.split(`
3514
3514
  `);for(let index=0;index<lines.length;index+=1){let y=renderable.y+index,line=selectedTextsByLine.get(y)??[];line.push({x:renderable.x,text:lines[index]}),selectedTextsByLine.set(y,line)}}return[...selectedTextsByLine.entries()].sort(([leftY],[rightY])=>leftY-rightY).map(([,line])=>line.sort((left,right)=>left.x-right.x).map((segment)=>segment.text).join("")).join(`
@@ -3642,7 +3642,7 @@ Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error
3642
3642
  `)}onResize(width,height){this.invalidateLayoutAndRaster(!1),super.onResize(width,height)}renderSelf(buffer){if(!this.visible||this.isDestroyed)return;if(this._layoutDirty)this.rebuildLayoutForCurrentWidth();if(!this._rasterDirty)return;if(buffer.clear(this._backgroundColor),this._rowCount===0||this._columnCount===0){this._rasterDirty=!1;return}this.drawBorders(buffer),this.drawCells(buffer),this._rasterDirty=!1}destroySelf(){this.destroyCells(),super.destroySelf()}setupMeasureFunc(){let measureFunc=(width,widthMode,_height,_heightMode)=>{let rawWidthConstraint=widthMode!==0&&Number.isFinite(width)?Math.max(1,Math.floor(width)):void 0,widthConstraint=this.resolveLayoutWidthConstraint(rawWidthConstraint),measuredLayout=this.computeLayout(widthConstraint);this._cachedMeasureLayout=measuredLayout,this._cachedMeasureWidth=widthConstraint;let measuredWidth=measuredLayout.tableWidth>0?measuredLayout.tableWidth:1,measuredHeight=measuredLayout.tableHeight>0?measuredLayout.tableHeight:1;if(widthMode===2&&rawWidthConstraint!==void 0&&this._positionType!=="absolute")measuredWidth=Math.min(rawWidthConstraint,measuredWidth);return{width:measuredWidth,height:measuredHeight}};this.yogaNode.setMeasureFunc(measureFunc)}rebuildCells(){let newRowCount=this._content.length,newColumnCount=this._content.reduce((max,row)=>Math.max(max,row.length),0);if(this._cells.length===0){this._rowCount=newRowCount,this._columnCount=newColumnCount,this._cells=[],this._prevCellContent=[];for(let rowIdx=0;rowIdx<newRowCount;rowIdx++){let row=this._content[rowIdx]??[],rowCells=[],rowRefs=[];for(let colIdx=0;colIdx<newColumnCount;colIdx++){let cellContent=row[colIdx];rowCells.push(this.createCell(cellContent)),rowRefs.push(cellContent)}this._cells.push(rowCells),this._prevCellContent.push(rowRefs)}this.invalidateLayoutAndRaster();return}this.updateCellsDiff(newRowCount,newColumnCount),this.invalidateLayoutAndRaster()}updateCellsDiff(newRowCount,newColumnCount){let oldRowCount=this._rowCount,oldColumnCount=this._columnCount,keepRows=Math.min(oldRowCount,newRowCount),keepCols=Math.min(oldColumnCount,newColumnCount);for(let rowIdx=0;rowIdx<keepRows;rowIdx++){let newRow=this._content[rowIdx]??[],cellRow=this._cells[rowIdx],refRow=this._prevCellContent[rowIdx];for(let colIdx=0;colIdx<keepCols;colIdx++){let cellContent=newRow[colIdx];if(cellContent===refRow[colIdx])continue;let oldCell=cellRow[colIdx];oldCell.textBufferView.destroy(),oldCell.textBuffer.destroy(),oldCell.syntaxStyle.destroy(),cellRow[colIdx]=this.createCell(cellContent),refRow[colIdx]=cellContent}if(newColumnCount>oldColumnCount)for(let colIdx=oldColumnCount;colIdx<newColumnCount;colIdx++){let cellContent=newRow[colIdx];cellRow.push(this.createCell(cellContent)),refRow.push(cellContent)}else if(newColumnCount<oldColumnCount){for(let colIdx=newColumnCount;colIdx<oldColumnCount;colIdx++){let cell=cellRow[colIdx];cell.textBufferView.destroy(),cell.textBuffer.destroy(),cell.syntaxStyle.destroy()}cellRow.length=newColumnCount,refRow.length=newColumnCount}}if(newRowCount>oldRowCount)for(let rowIdx=oldRowCount;rowIdx<newRowCount;rowIdx++){let newRow=this._content[rowIdx]??[],rowCells=[],rowRefs=[];for(let colIdx=0;colIdx<newColumnCount;colIdx++){let cellContent=newRow[colIdx];rowCells.push(this.createCell(cellContent)),rowRefs.push(cellContent)}this._cells.push(rowCells),this._prevCellContent.push(rowRefs)}else if(newRowCount<oldRowCount){for(let rowIdx=newRowCount;rowIdx<oldRowCount;rowIdx++){let row=this._cells[rowIdx];for(let cell of row)cell.textBufferView.destroy(),cell.textBuffer.destroy(),cell.syntaxStyle.destroy()}this._cells.length=newRowCount,this._prevCellContent.length=newRowCount}this._rowCount=newRowCount,this._columnCount=newColumnCount}createCell(content){let styledText=this.toStyledText(content),textBuffer=TextBuffer.create(this._ctx.widthMethod),syntaxStyle=SyntaxStyle.create();textBuffer.setDefaultFg(this._defaultFg),textBuffer.setDefaultBg(this._defaultBg),textBuffer.setDefaultAttributes(this._defaultAttributes),textBuffer.setSyntaxStyle(syntaxStyle),textBuffer.setStyledText(styledText);let textBufferView=TextBufferView.create(textBuffer);return textBufferView.setWrapMode(this._wrapMode),{textBuffer,textBufferView,syntaxStyle}}toStyledText(content){if(Array.isArray(content))return new StyledText(content);if(content===null||content===void 0)return stringToStyledText("");return stringToStyledText(String(content))}destroyCells(){for(let row of this._cells)for(let cell of row)cell.textBufferView.destroy(),cell.textBuffer.destroy(),cell.syntaxStyle.destroy();this._cells=[],this._prevCellContent=[],this._rowCount=0,this._columnCount=0,this._layout=this.createEmptyLayout()}rebuildLayoutForCurrentWidth(){let maxTableWidth=this.resolveLayoutWidthConstraint(this.width),layout;if(this._cachedMeasureLayout!==null&&this._cachedMeasureWidth===maxTableWidth)layout=this._cachedMeasureLayout;else layout=this.computeLayout(maxTableWidth);if(this._cachedMeasureLayout=null,this._cachedMeasureWidth=void 0,this._layout=layout,this.applyLayoutToViews(layout),this._layoutDirty=!1,this._lastLocalSelection?.isActive)this.applySelectionToCells(this._lastLocalSelection,!0)}computeLayout(maxTableWidth){if(this._rowCount===0||this._columnCount===0)return this.createEmptyLayout();let borderLayout=this.resolveBorderLayout(),columnWidths=this.computeColumnWidths(maxTableWidth,borderLayout),rowHeights=this.computeRowHeights(columnWidths),columnOffsets=this.computeOffsets(columnWidths,borderLayout.left,borderLayout.right,borderLayout.innerVertical,this.getInterColumnGap(borderLayout)),rowOffsets=this.computeOffsets(rowHeights,borderLayout.top,borderLayout.bottom,borderLayout.innerHorizontal);return{columnWidths,rowHeights,columnOffsets,rowOffsets,columnOffsetsI32:new Int32Array(columnOffsets),rowOffsetsI32:new Int32Array(rowOffsets),tableWidth:(columnOffsets[columnOffsets.length-1]??0)+1,tableHeight:(rowOffsets[rowOffsets.length-1]??0)+1}}isFullWidthMode(){return this._columnWidthMode==="full"}computeColumnWidths(maxTableWidth,borderLayout){let horizontalPadding=this.getHorizontalCellPadding(),intrinsicWidths=Array(this._columnCount).fill(1+horizontalPadding);for(let rowIdx=0;rowIdx<this._rowCount;rowIdx++)for(let colIdx=0;colIdx<this._columnCount;colIdx++){let cell=this._cells[rowIdx]?.[colIdx];if(!cell)continue;let measure=cell.textBufferView.measureForDimensions(0,MEASURE_HEIGHT),measuredWidth=Math.max(1,measure?.widthColsMax??0)+horizontalPadding;intrinsicWidths[colIdx]=Math.max(intrinsicWidths[colIdx],measuredWidth)}if(maxTableWidth===void 0||!Number.isFinite(maxTableWidth)||maxTableWidth<=0)return intrinsicWidths;let maxContentWidth=Math.max(1,Math.floor(maxTableWidth)-this.getVerticalBorderCount(borderLayout)-this.getTotalInterColumnGap(borderLayout)),currentWidth=intrinsicWidths.reduce((sum,width)=>sum+width,0);if(currentWidth===maxContentWidth)return intrinsicWidths;if(currentWidth<maxContentWidth){if(this.isFullWidthMode())return this.expandColumnWidths(intrinsicWidths,maxContentWidth);return intrinsicWidths}if(this._wrapMode==="none")return intrinsicWidths;return this.fitColumnWidths(intrinsicWidths,maxContentWidth)}expandColumnWidths(widths,targetContentWidth){let baseWidths=widths.map((width)=>Math.max(1,Math.floor(width))),totalBaseWidth=baseWidths.reduce((sum,width)=>sum+width,0);if(totalBaseWidth>=targetContentWidth)return baseWidths;let expanded=[...baseWidths],columns=expanded.length,extraWidth=targetContentWidth-totalBaseWidth,sharedWidth=Math.floor(extraWidth/columns),remainder=extraWidth%columns;for(let idx=0;idx<columns;idx++)if(expanded[idx]+=sharedWidth,idx<remainder)expanded[idx]+=1;return expanded}fitColumnWidths(widths,targetContentWidth){if(this._columnFitter==="balanced")return this.fitColumnWidthsBalanced(widths,targetContentWidth);return this.fitColumnWidthsProportional(widths,targetContentWidth)}fitColumnWidthsProportional(widths,targetContentWidth){let minWidth=1+this.getHorizontalCellPadding(),hardMinWidths=Array(widths.length).fill(minWidth),baseWidths=widths.map((width)=>Math.max(1,Math.floor(width))),preferredMinWidths=baseWidths.map((width)=>Math.min(width,minWidth+1)),floorWidths=preferredMinWidths.reduce((sum,width)=>sum+width,0)<=targetContentWidth?preferredMinWidths:hardMinWidths,floorTotal=floorWidths.reduce((sum,width)=>sum+width,0),clampedTarget=Math.max(floorTotal,targetContentWidth),totalBaseWidth=baseWidths.reduce((sum,width)=>sum+width,0);if(totalBaseWidth<=clampedTarget)return baseWidths;let shrinkable=baseWidths.map((width,idx)=>width-floorWidths[idx]),totalShrinkable=shrinkable.reduce((sum,value)=>sum+value,0);if(totalShrinkable<=0)return[...floorWidths];let targetShrink=totalBaseWidth-clampedTarget,integerShrink=Array(baseWidths.length).fill(0),fractions=Array(baseWidths.length).fill(0),usedShrink=0;for(let idx=0;idx<baseWidths.length;idx++){if(shrinkable[idx]<=0)continue;let exact=shrinkable[idx]/totalShrinkable*targetShrink,whole=Math.min(shrinkable[idx],Math.floor(exact));integerShrink[idx]=whole,fractions[idx]=exact-whole,usedShrink+=whole}let remainingShrink=targetShrink-usedShrink;while(remainingShrink>0){let bestIdx=-1,bestFraction=-1;for(let idx=0;idx<baseWidths.length;idx++){if(shrinkable[idx]-integerShrink[idx]<=0)continue;if(fractions[idx]>bestFraction)bestFraction=fractions[idx],bestIdx=idx}if(bestIdx===-1)break;integerShrink[bestIdx]+=1,fractions[bestIdx]=0,remainingShrink-=1}return baseWidths.map((width,idx)=>Math.max(floorWidths[idx],width-integerShrink[idx]))}fitColumnWidthsBalanced(widths,targetContentWidth){let minWidth=1+this.getHorizontalCellPadding(),hardMinWidths=Array(widths.length).fill(minWidth),baseWidths=widths.map((width)=>Math.max(1,Math.floor(width))),totalBaseWidth=baseWidths.reduce((sum,width)=>sum+width,0),columns=baseWidths.length;if(columns===0||totalBaseWidth<=targetContentWidth)return baseWidths;let evenShare=Math.max(minWidth,Math.floor(targetContentWidth/columns)),preferredMinWidths=baseWidths.map((width)=>Math.min(width,evenShare)),floorWidths=preferredMinWidths.reduce((sum,width)=>sum+width,0)<=targetContentWidth?preferredMinWidths:hardMinWidths,floorTotal=floorWidths.reduce((sum,width)=>sum+width,0),clampedTarget=Math.max(floorTotal,targetContentWidth);if(totalBaseWidth<=clampedTarget)return baseWidths;let shrinkable=baseWidths.map((width,idx)=>width-floorWidths[idx]);if(shrinkable.reduce((sum,value)=>sum+value,0)<=0)return[...floorWidths];let targetShrink=totalBaseWidth-clampedTarget,shrink=this.allocateShrinkByWeight(shrinkable,targetShrink,"sqrt");return baseWidths.map((width,idx)=>Math.max(floorWidths[idx],width-shrink[idx]))}allocateShrinkByWeight(shrinkable,targetShrink,mode){let shrink=Array(shrinkable.length).fill(0);if(targetShrink<=0)return shrink;let weights=shrinkable.map((value)=>{if(value<=0)return 0;return mode==="sqrt"?Math.sqrt(value):value}),totalWeight=weights.reduce((sum,value)=>sum+value,0);if(totalWeight<=0)return shrink;let fractions=Array(shrinkable.length).fill(0),usedShrink=0;for(let idx=0;idx<shrinkable.length;idx++){if(shrinkable[idx]<=0||weights[idx]<=0)continue;let exact=weights[idx]/totalWeight*targetShrink,whole=Math.min(shrinkable[idx],Math.floor(exact));shrink[idx]=whole,fractions[idx]=exact-whole,usedShrink+=whole}let remainingShrink=targetShrink-usedShrink;while(remainingShrink>0){let bestIdx=-1,bestFraction=-1;for(let idx=0;idx<shrinkable.length;idx++){if(shrinkable[idx]-shrink[idx]<=0)continue;if(bestIdx===-1||fractions[idx]>bestFraction||fractions[idx]===bestFraction&&shrinkable[idx]>shrinkable[bestIdx])bestIdx=idx,bestFraction=fractions[idx]}if(bestIdx===-1)break;shrink[bestIdx]+=1,fractions[bestIdx]=0,remainingShrink-=1}return shrink}computeRowHeights(columnWidths){let horizontalPadding=this.getHorizontalCellPadding(),verticalPadding=this.getVerticalCellPadding(),rowHeights=Array(this._rowCount).fill(1+verticalPadding);for(let rowIdx=0;rowIdx<this._rowCount;rowIdx++)for(let colIdx=0;colIdx<this._columnCount;colIdx++){let cell=this._cells[rowIdx]?.[colIdx];if(!cell)continue;let width=Math.max(1,(columnWidths[colIdx]??1)-horizontalPadding),measure=cell.textBufferView.measureForDimensions(width,MEASURE_HEIGHT),lineCount=Math.max(1,measure?.lineCount??1);rowHeights[rowIdx]=Math.max(rowHeights[rowIdx],lineCount+verticalPadding)}return rowHeights}computeOffsets(parts,startBoundary,endBoundary,includeInnerBoundaries,innerGap=0){let offsets=[startBoundary?0:-1],cursor=offsets[0]??0;for(let idx=0;idx<parts.length;idx++){let size=parts[idx]??1,separatorAfter=idx<parts.length-1?includeInnerBoundaries?1:innerGap:endBoundary?1:0;cursor+=size+separatorAfter,offsets.push(cursor)}return offsets}getInterColumnGap(borderLayout){if(borderLayout.innerVertical)return 0;return this._columnGap}getTotalInterColumnGap(borderLayout){return Math.max(0,this._columnCount-1)*this.getInterColumnGap(borderLayout)}applyLayoutToViews(layout){let horizontalPadding=this.getHorizontalCellPadding(),verticalPadding=this.getVerticalCellPadding();for(let rowIdx=0;rowIdx<this._rowCount;rowIdx++)for(let colIdx=0;colIdx<this._columnCount;colIdx++){let cell=this._cells[rowIdx]?.[colIdx];if(!cell)continue;let colWidth=layout.columnWidths[colIdx]??1,rowHeight=layout.rowHeights[rowIdx]??1,contentWidth=Math.max(1,colWidth-horizontalPadding),contentHeight=Math.max(1,rowHeight-verticalPadding);if(this._wrapMode==="none")cell.textBufferView.setWrapWidth(null);else cell.textBufferView.setWrapWidth(contentWidth);cell.textBufferView.setViewport(0,0,contentWidth,contentHeight)}}resolveBorderLayout(){return{left:this._outerBorder,right:this._outerBorder,top:this._outerBorder,bottom:this._outerBorder,innerVertical:this._border&&this._columnCount>1,innerHorizontal:this._border&&this._rowCount>1}}getVerticalBorderCount(borderLayout){return(borderLayout.left?1:0)+(borderLayout.right?1:0)+(borderLayout.innerVertical?Math.max(0,this._columnCount-1):0)}getHorizontalBorderCount(borderLayout){return(borderLayout.top?1:0)+(borderLayout.bottom?1:0)+(borderLayout.innerHorizontal?Math.max(0,this._rowCount-1):0)}drawBorders(buffer){if(!this._showBorders)return;let borderLayout=this.resolveBorderLayout();if(this.getVerticalBorderCount(borderLayout)===0&&this.getHorizontalBorderCount(borderLayout)===0)return;buffer.drawGrid({borderChars:BorderCharArrays[this._borderStyle],borderFg:this._borderColor,borderBg:this._borderBackgroundColor,columnOffsets:this._layout.columnOffsetsI32,rowOffsets:this._layout.rowOffsetsI32,drawInner:this._border,drawOuter:this._outerBorder})}drawCells(buffer){this.drawCellRange(buffer,0,this._rowCount-1)}drawCellRange(buffer,firstRow,lastRow){let colOffsets=this._layout.columnOffsets,rowOffsets=this._layout.rowOffsets,cellPaddingX=this._cellPaddingX,cellPaddingY=this._cellPaddingY;for(let rowIdx=firstRow;rowIdx<=lastRow;rowIdx++){let cellY=(rowOffsets[rowIdx]??0)+1+cellPaddingY;for(let colIdx=0;colIdx<this._columnCount;colIdx++){let cell=this._cells[rowIdx]?.[colIdx];if(!cell)continue;buffer.drawTextBuffer(cell.textBufferView,(colOffsets[colIdx]??0)+1+cellPaddingX,cellY)}}}redrawSelectionRows(firstRow,lastRow){if(firstRow>lastRow)return;if(this._backgroundColor.a<1){this.invalidateRasterOnly();return}let buffer=this.frameBuffer;if(!buffer)return;this.clearCellRange(buffer,firstRow,lastRow),this.drawCellRange(buffer,firstRow,lastRow),this.requestRender()}clearCellRange(buffer,firstRow,lastRow){let colWidths=this._layout.columnWidths,rowHeights=this._layout.rowHeights,colOffsets=this._layout.columnOffsets,rowOffsets=this._layout.rowOffsets;for(let rowIdx=firstRow;rowIdx<=lastRow;rowIdx++){let cellY=(rowOffsets[rowIdx]??0)+1,rowHeight=rowHeights[rowIdx]??1;for(let colIdx=0;colIdx<this._columnCount;colIdx++){let cellX=(colOffsets[colIdx]??0)+1,colWidth=colWidths[colIdx]??1;if(this._backgroundColor.a<1)for(let y2=cellY;y2<cellY+rowHeight;y2++)for(let x2=cellX;x2<cellX+colWidth;x2++)buffer.setCell(x2,y2," ",this._defaultFg,this._backgroundColor,this._defaultAttributes);else buffer.fillRect(cellX,cellY,colWidth,rowHeight,this._backgroundColor)}}}ensureLayoutReady(){if(!this._layoutDirty)return;this.rebuildLayoutForCurrentWidth()}getCellAtLocalPosition(localX,localY){if(this._rowCount===0||this._columnCount===0)return null;if(localX<0||localY<0||localX>=this._layout.tableWidth||localY>=this._layout.tableHeight)return null;let rowIdx=-1;for(let idx=0;idx<this._rowCount;idx++){let top=(this._layout.rowOffsets[idx]??0)+1,bottom=top+(this._layout.rowHeights[idx]??1)-1;if(localY>=top&&localY<=bottom){rowIdx=idx;break}}if(rowIdx<0)return null;let colIdx=-1;for(let idx=0;idx<this._columnCount;idx++){let left=(this._layout.columnOffsets[idx]??0)+1,right=left+(this._layout.columnWidths[idx]??1)-1;if(localX>=left&&localX<=right){colIdx=idx;break}}if(colIdx<0)return null;return{rowIdx,colIdx}}applySelectionToCells(localSelection,isStart){if(localSelection.anchorX===localSelection.focusX&&localSelection.anchorY===localSelection.focusY){this.resetCellSelections(),this._lastSelectionMode=null;return}let minSelY=Math.min(localSelection.anchorY,localSelection.focusY),maxSelY=Math.max(localSelection.anchorY,localSelection.focusY),firstRow=this.findRowForLocalY(minSelY),lastRow=this.findRowForLocalY(maxSelY),selection=this.resolveSelectionResolution(localSelection),modeChanged=this._lastSelectionMode!==selection.mode;this._lastSelectionMode=selection.mode;let lockToAnchorColumn=selection.mode==="column-locked"&&selection.anchorColumn!==null;for(let rowIdx=0;rowIdx<this._rowCount;rowIdx++){if(rowIdx<firstRow||rowIdx>lastRow){this.resetRowSelection(rowIdx);continue}let cellTop=(this._layout.rowOffsets[rowIdx]??0)+1+this._cellPaddingY;for(let colIdx=0;colIdx<this._columnCount;colIdx++){let cell=this._cells[rowIdx]?.[colIdx];if(!cell)continue;if(lockToAnchorColumn&&colIdx!==selection.anchorColumn){cell.textBufferView.resetLocalSelection();continue}let cellLeft=(this._layout.columnOffsets[colIdx]??0)+1+this._cellPaddingX,coords={anchorX:localSelection.anchorX-cellLeft,anchorY:localSelection.anchorY-cellTop,focusX:localSelection.focusX-cellLeft,focusY:localSelection.focusY-cellTop},isAnchorCell=selection.anchorCell!==null&&selection.anchorCell.rowIdx===rowIdx&&selection.anchorCell.colIdx===colIdx;if(selection.mode==="single-cell"&&!isAnchorCell){cell.textBufferView.resetLocalSelection();continue}let forceSet=isAnchorCell&&selection.mode!=="single-cell";if(forceSet)coords=this.getFullCellSelectionCoords(rowIdx,colIdx);if(isStart||modeChanged||forceSet)cell.textBufferView.setLocalSelection(coords.anchorX,coords.anchorY,coords.focusX,coords.focusY,this._selectionBg,this._selectionFg);else cell.textBufferView.updateLocalSelection(coords.anchorX,coords.anchorY,coords.focusX,coords.focusY,this._selectionBg,this._selectionFg)}}}resolveSelectionResolution(localSelection){let anchorCell=this.getCellAtLocalPosition(localSelection.anchorX,localSelection.anchorY),focusCell=this.getCellAtLocalPosition(localSelection.focusX,localSelection.focusY),anchorColumn=anchorCell?.colIdx??this.getColumnAtLocalX(localSelection.anchorX);if(anchorCell!==null&&focusCell!==null&&anchorCell.rowIdx===focusCell.rowIdx&&anchorCell.colIdx===focusCell.colIdx)return{mode:"single-cell",anchorCell,anchorColumn};let focusColumn=this.getColumnAtLocalX(localSelection.focusX);if(anchorColumn!==null&&focusColumn===anchorColumn)return{mode:"column-locked",anchorCell,anchorColumn};return{mode:"grid",anchorCell,anchorColumn}}getColumnAtLocalX(localX){if(this._columnCount===0)return null;if(localX<0||localX>=this._layout.tableWidth)return null;for(let colIdx=0;colIdx<this._columnCount;colIdx++){let colStart=(this._layout.columnOffsets[colIdx]??0)+1,colEnd=colStart+(this._layout.columnWidths[colIdx]??1)-1;if(localX>=colStart&&localX<=colEnd)return colIdx}return null}getFullCellSelectionCoords(rowIdx,colIdx){let colWidth=this._layout.columnWidths[colIdx]??1,rowHeight=this._layout.rowHeights[rowIdx]??1,contentWidth=Math.max(1,colWidth-this.getHorizontalCellPadding()),contentHeight=Math.max(1,rowHeight-this.getVerticalCellPadding());return{anchorX:-1,anchorY:0,focusX:contentWidth,focusY:contentHeight}}findRowForLocalY(localY){if(this._rowCount===0)return 0;if(localY<0)return 0;for(let rowIdx=0;rowIdx<this._rowCount;rowIdx++){let rowEnd=(this._layout.rowOffsets[rowIdx]??0)+1+(this._layout.rowHeights[rowIdx]??1)-1;if(localY<=rowEnd)return rowIdx}return this._rowCount-1}getSelectionRowRange(selection){if(!selection?.isActive||this._rowCount===0)return null;let minSelY=Math.min(selection.anchorY,selection.focusY),maxSelY=Math.max(selection.anchorY,selection.focusY);return{firstRow:this.findRowForLocalY(minSelY),lastRow:this.findRowForLocalY(maxSelY)}}getDirtySelectionRowRange(previousSelection,currentSelection){let previousRange=this.getSelectionRowRange(previousSelection),currentRange=this.getSelectionRowRange(currentSelection);if(previousRange===null)return currentRange;if(currentRange===null)return previousRange;return{firstRow:Math.min(previousRange.firstRow,currentRange.firstRow),lastRow:Math.max(previousRange.lastRow,currentRange.lastRow)}}resetRowSelection(rowIdx){let row=this._cells[rowIdx];if(!row)return;for(let cell of row)cell.textBufferView.resetLocalSelection()}resetCellSelections(){for(let rowIdx=0;rowIdx<this._rowCount;rowIdx++)this.resetRowSelection(rowIdx)}createEmptyLayout(){return{columnWidths:[],rowHeights:[],columnOffsets:[0],rowOffsets:[0],columnOffsetsI32:new Int32Array([0]),rowOffsetsI32:new Int32Array([0]),tableWidth:0,tableHeight:0}}resolveLayoutWidthConstraint(width){if(width===void 0||!Number.isFinite(width)||width<=0)return;if(this._wrapMode!=="none"||this.isFullWidthMode())return Math.max(1,Math.floor(width));return}getHorizontalCellPadding(){return this._cellPaddingX*2}getVerticalCellPadding(){return this._cellPaddingY*2}resolveColumnFitter(value){if(value===void 0)return this._defaultOptions.columnFitter;return value==="balanced"?"balanced":"proportional"}resolveCellPadding(value){if(value===void 0||!Number.isFinite(value))return this._defaultOptions.cellPadding;return Math.max(0,Math.floor(value))}resolveColumnGap(value){if(value===void 0||!Number.isFinite(value))return this._defaultOptions.columnGap;return Math.max(0,Math.floor(value))}invalidateLayoutAndRaster(markYogaDirty=!0){if(this._layoutDirty=!0,this._rasterDirty=!0,this._cachedMeasureLayout=null,this._cachedMeasureWidth=void 0,markYogaDirty)this.yogaNode.markDirty();this.requestRender()}invalidateRasterOnly(){this._rasterDirty=!0,this.requestRender()}}function parseMarkdownIncremental(newContent,prevState,trailingUnstable=2){if(!prevState||prevState.tokens.length===0)try{let tokens=x.lex(newContent,{gfm:!0});return{content:newContent,tokens,stableTokenCount:Math.max(0,tokens.length-trailingUnstable)}}catch{return{content:newContent,tokens:[],stableTokenCount:0}}let offset=0,reuseCount=0;for(let token of prevState.tokens){let tokenLength=token.raw.length;if(offset+tokenLength<=newContent.length&&newContent.startsWith(token.raw,offset))reuseCount++,offset+=tokenLength;else break}reuseCount=Math.max(0,reuseCount-trailingUnstable),offset=0;for(let i=0;i<reuseCount;i++)offset+=prevState.tokens[i].raw.length;let stableTokens=prevState.tokens.slice(0,reuseCount),remainingContent=newContent.slice(offset);if(!remainingContent)return{content:newContent,tokens:stableTokens,stableTokenCount:stableTokens.length};try{let newTokens=x.lex(remainingContent,{gfm:!0});return{content:newContent,tokens:[...stableTokens,...newTokens],stableTokenCount:trailingUnstable===0?stableTokens.length+newTokens.length:stableTokens.length}}catch{try{let fullTokens=x.lex(newContent,{gfm:!0});return{content:newContent,tokens:fullTokens,stableTokenCount:0}}catch{return{content:newContent,tokens:[],stableTokenCount:0}}}}var TRAILING_MARKDOWN_BLOCK_BREAKS_RE=/(?:\r?\n){2,}$/,TRAILING_MARKDOWN_BLOCK_NEWLINES_RE=/(?:\r?\n)+$/;function colorsEqual(left,right){if(!left||!right)return left===right;return left.equals(right)}class MarkdownRenderable extends Renderable{_content="";_syntaxStyle;_fg;_bg;_conceal;_concealCode;_treeSitterClient;_tableOptions;_renderNode;_internalBlockMode;_parseState=null;_streaming=!1;_blockStates=[];_stableBlockCount=0;_styleDirty=!1;_linkifyMarkdownChunks=(chunks,context)=>detectLinks(chunks,{content:context.content,highlights:context.highlights});_contentDefaultOptions={content:"",conceal:!0,concealCode:!1,streaming:!1,internalBlockMode:"coalesced"};constructor(ctx,options){super(ctx,{...options,flexDirection:"column",flexShrink:options.flexShrink??0});this._syntaxStyle=options.syntaxStyle,this._fg=options.fg?parseColor(options.fg):void 0,this._bg=options.bg?parseColor(options.bg):void 0,this._conceal=options.conceal??this._contentDefaultOptions.conceal,this._concealCode=options.concealCode??this._contentDefaultOptions.concealCode,this._content=options.content??this._contentDefaultOptions.content,this._treeSitterClient=options.treeSitterClient,this._tableOptions=options.tableOptions,this._renderNode=options.renderNode,this._streaming=options.streaming??this._contentDefaultOptions.streaming,this._internalBlockMode=options.internalBlockMode??this._contentDefaultOptions.internalBlockMode,this.updateBlocks()}get content(){return this._content}set content(value){if(this.isDestroyed)return;if(this._content!==value)this._content=value,this.updateBlocks(),this.requestRender()}get syntaxStyle(){return this._syntaxStyle}set syntaxStyle(value){if(this._syntaxStyle!==value)this._syntaxStyle=value,this._styleDirty=!0}get fg(){return this._fg}set fg(value){let next=value?parseColor(value):void 0;if(!colorsEqual(this._fg,next))this._fg=next,this._styleDirty=!0}get bg(){return this._bg}set bg(value){let next=value?parseColor(value):void 0;if(!colorsEqual(this._bg,next))this._bg=next,this._styleDirty=!0}get conceal(){return this._conceal}set conceal(value){if(this._conceal!==value)this._conceal=value,this._styleDirty=!0}get concealCode(){return this._concealCode}set concealCode(value){if(this._concealCode!==value)this._concealCode=value,this._styleDirty=!0}get streaming(){return this._streaming}set streaming(value){if(this.isDestroyed)return;if(this._streaming!==value)this._streaming=value,this.updateBlocks(!0)}get tableOptions(){return this._tableOptions}set tableOptions(value){this._tableOptions=value,this.applyTableOptionsToBlocks()}get renderNode(){return this._renderNode}set renderNode(value){if(this._renderNode===value)return;this._renderNode=value,this.clearBlockStates(),this._parseState=null,this.updateBlocks(!0),this.requestRender()}get internalBlockMode(){return this._internalBlockMode}set internalBlockMode(value){if(this._internalBlockMode===value)return;this._internalBlockMode=value,this.updateBlocks(!0),this.requestRender()}getStyle(group){if(!this._syntaxStyle)return;let style=this._syntaxStyle.getStyle(group);if(!style&&group.includes(".")){let baseName=group.split(".")[0];style=this._syntaxStyle.getStyle(baseName)}return style}createChunk(text,group,link2){let style=this.getStyle(group)||this.getStyle("default");return{__isChunk:!0,text,fg:style?.fg,bg:style?.bg,attributes:style?createTextAttributes({bold:style.bold,italic:style.italic,underline:style.underline,dim:style.dim}):0,link:link2}}createDefaultChunk(text){return this.createChunk(text,"default")}createInitialStyledText(token){if(!this._streaming)return;let chunks=[];if("tokens"in token&&Array.isArray(token.tokens))this.renderInlineContent(token.tokens,chunks);if(chunks.length===0&&"text"in token&&typeof token.text==="string")this.renderInlineContent(x.lexInline(token.text),chunks);return chunks.length>0?new StyledText(chunks):void 0}renderInlineContent(tokens,chunks){for(let token of tokens)this.renderInlineToken(token,chunks)}renderInlineToken(token,chunks){switch(token.type){case"text":chunks.push(this.createDefaultChunk(token.text));break;case"escape":chunks.push(this.createDefaultChunk(token.text));break;case"codespan":if(this._conceal)chunks.push(this.createChunk(token.text,"markup.raw"));else chunks.push(this.createChunk("`","markup.raw")),chunks.push(this.createChunk(token.text,"markup.raw")),chunks.push(this.createChunk("`","markup.raw"));break;case"strong":if(!this._conceal)chunks.push(this.createChunk("**","markup.strong"));for(let child of token.tokens)this.renderInlineTokenWithStyle(child,chunks,"markup.strong");if(!this._conceal)chunks.push(this.createChunk("**","markup.strong"));break;case"em":if(!this._conceal)chunks.push(this.createChunk("*","markup.italic"));for(let child of token.tokens)this.renderInlineTokenWithStyle(child,chunks,"markup.italic");if(!this._conceal)chunks.push(this.createChunk("*","markup.italic"));break;case"del":if(!this._conceal)chunks.push(this.createChunk("~~","markup.strikethrough"));for(let child of token.tokens)this.renderInlineTokenWithStyle(child,chunks,"markup.strikethrough");if(!this._conceal)chunks.push(this.createChunk("~~","markup.strikethrough"));break;case"link":{let linkHref={url:token.href};if(this._conceal){for(let child of token.tokens)this.renderInlineTokenWithStyle(child,chunks,"markup.link.label",linkHref);chunks.push(this.createChunk(" (","markup.link",linkHref)),chunks.push(this.createChunk(token.href,"markup.link.url",linkHref)),chunks.push(this.createChunk(")","markup.link",linkHref))}else{chunks.push(this.createChunk("[","markup.link",linkHref));for(let child of token.tokens)this.renderInlineTokenWithStyle(child,chunks,"markup.link.label",linkHref);chunks.push(this.createChunk("](","markup.link",linkHref)),chunks.push(this.createChunk(token.href,"markup.link.url",linkHref)),chunks.push(this.createChunk(")","markup.link",linkHref))}break}case"image":{let imageHref={url:token.href};if(this._conceal)chunks.push(this.createChunk(token.text||"image","markup.link.label",imageHref));else chunks.push(this.createChunk("![","markup.link",imageHref)),chunks.push(this.createChunk(token.text||"","markup.link.label",imageHref)),chunks.push(this.createChunk("](","markup.link",imageHref)),chunks.push(this.createChunk(token.href,"markup.link.url",imageHref)),chunks.push(this.createChunk(")","markup.link",imageHref));break}case"br":chunks.push(this.createDefaultChunk(`
3643
3643
  `));break;default:if("tokens"in token&&Array.isArray(token.tokens))this.renderInlineContent(token.tokens,chunks);else if("text"in token&&typeof token.text==="string")chunks.push(this.createDefaultChunk(token.text));break}}renderInlineTokenWithStyle(token,chunks,styleGroup,link2){switch(token.type){case"text":chunks.push(this.createChunk(token.text,styleGroup,link2));break;case"escape":chunks.push(this.createChunk(token.text,styleGroup,link2));break;case"codespan":if(this._conceal)chunks.push(this.createChunk(token.text,"markup.raw",link2));else chunks.push(this.createChunk("`","markup.raw",link2)),chunks.push(this.createChunk(token.text,"markup.raw",link2)),chunks.push(this.createChunk("`","markup.raw",link2));break;default:this.renderInlineToken(token,chunks);break}}applyMargins(renderable,marginTop,marginBottom){renderable.marginTop=marginTop,renderable.marginBottom=marginBottom}createMarkdownCodeRenderable(content,id,marginBottom=0,onChunks=this._linkifyMarkdownChunks,baseHighlight,initialStyledText){return new CodeRenderable(this.ctx,{id,content,filetype:"markdown",syntaxStyle:this._syntaxStyle,fg:this._fg,bg:this._bg,conceal:this._conceal,drawUnstyledText:initialStyledText!==void 0,streaming:!0,initialStyledText,baseHighlight,onChunks,treeSitterClient:this._treeSitterClient,width:"100%",marginBottom})}getBlockquoteContent(token){return"text"in token&&typeof token.text==="string"&&token.text?token.text:" "}getBlockquoteBorderColor(){return this.getStyle("conceal")?.fg??this.getStyle("default")?.fg??this._fg??"#FFFFFF"}createBlockquoteRenderable(token,id,marginBottom=0){let renderable=new BoxRenderable(this.ctx,{id,width:"100%",border:["left"],borderColor:this.getBlockquoteBorderColor(),paddingLeft:1,flexShrink:0,marginBottom});return renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token),`${id}-content`,0,this._linkifyMarkdownChunks,"markup.quote")),renderable}createListRenderable(token,id,marginBottom=0){let list=new BoxRenderable(this.ctx,{id,width:"100%",flexDirection:"column",flexShrink:0,marginBottom});for(let item of this.getListItemInputs(token,id))list.add(this.createListItemRenderable(item));return list}getListItemInputs(token,id){let items=token.items??[],start=token.start===""||token.start===void 0||token.start===null?1:Number(token.start),markerWidth=Math.max(1,...items.map((_2,index)=>(token.ordered?`${start+index}.`:"-").length));return items.map((item,index)=>({item,marker:token.ordered?`${start+index}.`:"-",markerWidth,id:`${id}-item-${index}`}))}applyListRenderable(renderable,token,previousToken,id,marginBottom=0){if(!(renderable instanceof BoxRenderable))return!1;renderable.marginBottom=marginBottom;let inputs=this.getListItemInputs(token,id),previousItems=previousToken?.items??[],rows=renderable.getChildren();for(let index=0;index<inputs.length;index+=1){let input=inputs[index],existing=rows[index];if(existing instanceof BoxRenderable&&this.applyListItemRenderable(existing,input,previousItems[index]))continue;existing?.destroyRecursively(),renderable.add(this.createListItemRenderable(input),index)}for(let index=rows.length-1;index>=inputs.length;index-=1)rows[index]?.destroyRecursively();return!0}createListItemRenderable(input){let row=new BoxRenderable(this.ctx,{id:input.id,width:"100%",flexDirection:"row",flexShrink:0,marginBottom:/\n[ \t]*\n$/.test(input.item.raw)?1:0});row.add(new TextRenderable(this.ctx,{id:`${input.id}-marker`,content:new StyledText([this.createChunk(input.marker.padStart(input.markerWidth)+" ","markup.list")]),width:input.markerWidth+1,flexShrink:0}));let content=new BoxRenderable(this.ctx,{id:`${input.id}-content`,flexDirection:"column",flexGrow:1,flexShrink:1});row.add(content);let pendingMarginTop=0;for(let index=0;index<input.item.tokens.length;index+=1){let child=input.item.tokens[index];if(!child)continue;if(child.type==="checkbox")continue;if(child.type==="space"){pendingMarginTop=Math.max(pendingMarginTop,1);continue}let renderable=this.createListChildRenderable(child,`${input.id}-child-${index}`);if(!renderable)continue;renderable.marginTop=child.type==="list"?0:pendingMarginTop,pendingMarginTop=0,content.add(renderable)}return row}applyListItemRenderable(row,input,previousItem){this.applyListItemMarker(row,input);let content=row.getChildren()[1];if(!(content instanceof BoxRenderable))return!1;if(previousItem&&previousItem.raw===input.item.raw)return!0;return this.applyListItemChildren(content,input.item,previousItem,input.id)}applyListItemChildren(content,item,previousItem,id){let previousTokens=previousItem?this.getRenderableListItemTokens(previousItem):[],children=content.getChildren(),childIndex=0,pendingMarginTop=0;for(let tokenIndex=0;tokenIndex<item.tokens.length;tokenIndex+=1){let token=item.tokens[tokenIndex];if(!token)continue;if(token.type==="checkbox")continue;if(token.type==="space"){pendingMarginTop=Math.max(pendingMarginTop,1);continue}let existing=children[childIndex],childId=`${id}-child-${tokenIndex}`,marginTop=token.type==="list"?0:pendingMarginTop;if(pendingMarginTop=0,!existing){let renderable=this.createListChildRenderable(token,childId);if(!renderable)return!1;renderable.marginTop=marginTop,content.add(renderable,childIndex),childIndex+=1;continue}if(!this.applyListChildRenderable(existing,token,previousTokens[childIndex],childId))return!1;existing.marginTop=marginTop,childIndex+=1}return this.destroyListItemChildrenAfter(content,childIndex),!0}getRenderableListItemTokens(item){let tokens=[];for(let token of item.tokens){if(token.type==="checkbox"||token.type==="space")continue;tokens.push(token)}return tokens}applyListChildRenderable(renderable,token,previousToken,id){if((token.type==="text"||token.type==="paragraph")&&renderable instanceof CodeRenderable)return this.applyMarkdownCodeRenderable(renderable,this.normalizeScrollbackMarkdownBlockRaw(token.raw),0),!0;if(token.type==="list"&&renderable instanceof BoxRenderable)return this.applyListRenderable(renderable,token,previousToken,id);if(token.type==="code"&&renderable instanceof CodeRenderable)return this.applyCodeBlockRenderable(renderable,token,0),!0;return previousToken?.raw===token.raw}destroyListItemChildrenAfter(content,index){let children=content.getChildren();for(let i=children.length-1;i>=index;i-=1)children[i]?.destroyRecursively()}applyListItemMarker(row,input){let marker=row.getChildren()[0];if(!(marker instanceof TextRenderable))return;let marginBottom=/\n[ \t]*\n$/.test(input.item.raw)?1:0,markerWidth=input.markerWidth+1,markerText=input.marker.padStart(input.markerWidth)+" ";if(row.marginBottom!==marginBottom)row.marginBottom=marginBottom;if(marker.width!==markerWidth)marker.width=markerWidth;if(marker.chunks[0]?.text!==markerText)marker.content=new StyledText([this.createChunk(markerText,"markup.list")])}createListChildRenderable(token,id){if(token.type==="text"||token.type==="paragraph")return this.createMarkdownCodeRenderable(this.normalizeScrollbackMarkdownBlockRaw(token.raw),id,0,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token));if(token.type==="list")return this.createListRenderable(token,id);if(token.type==="code")return this.createCodeRenderable(token,id);if(token.type==="blockquote")return this.createBlockquoteRenderable(token,id);if(token.type==="hr")return this.createHorizontalRuleRenderable(id);if(token.type==="table")return this.createTableBlock(token,id).renderable;return token.raw?this.createMarkdownCodeRenderable(token.raw,id,0,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token)):null}createHorizontalRuleRenderable(id,marginBottom=0){return new BoxRenderable(this.ctx,{id,width:"100%",height:1,border:["top"],borderColor:this.getStyle("conceal")?.fg??this._fg??"#888888",flexShrink:0,marginBottom})}createCodeRenderable(token,id,marginBottom=0){return new CodeRenderable(this.ctx,{id,content:token.text,filetype:infoStringToFiletype(token.lang??""),syntaxStyle:this._syntaxStyle,fg:this._fg,bg:this._bg,conceal:this._concealCode,drawUnstyledText:!this._streaming,streaming:this._streaming,treeSitterClient:this._treeSitterClient,width:"100%",marginBottom})}applyMarkdownCodeRenderable(renderable,content,marginBottom,baseHighlight,initialStyledText){renderable.initialStyledText=initialStyledText,renderable.filetype="markdown",renderable.syntaxStyle=this._syntaxStyle,renderable.fg=this._fg,renderable.bg=this._bg,renderable.conceal=this._conceal,renderable.drawUnstyledText=initialStyledText!==void 0,renderable.streaming=!0,renderable.baseHighlight=baseHighlight,renderable.content=content,renderable.marginBottom=marginBottom}applyBlockquoteRenderable(renderable,token,marginBottom){if(!(renderable instanceof BoxRenderable))return;renderable.borderColor=this.getBlockquoteBorderColor(),renderable.marginBottom=marginBottom;let child=renderable.getChildren()[0];if(child instanceof CodeRenderable){this.applyMarkdownCodeRenderable(child,this.getBlockquoteContent(token),0,"markup.quote");return}for(let existing of renderable.getChildren())existing.destroyRecursively();renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token),`${renderable.id}-content`,0,this._linkifyMarkdownChunks,"markup.quote"))}applyCodeBlockRenderable(renderable,token,marginBottom){if(!(renderable instanceof CodeRenderable))return;renderable.filetype=infoStringToFiletype(token.lang??""),renderable.syntaxStyle=this._syntaxStyle,renderable.fg=this._fg,renderable.bg=this._bg,renderable.conceal=this._concealCode,renderable.drawUnstyledText=!this._streaming,renderable.streaming=this._streaming,renderable.content=token.text,renderable.marginBottom=marginBottom}shouldRenderSeparately(token){return token.type==="code"||token.type==="table"||token.type==="blockquote"||token.type==="hr"}getInterBlockMargin(token,nextToken){if(!nextToken)return 0;if(this.shouldRenderSeparately(token))return 1;if(!this.shouldRenderSeparately(nextToken))return 0;return TRAILING_MARKDOWN_BLOCK_NEWLINES_RE.test(token.raw)?0:1}applyInterBlockMargin(state,token,nextToken){if(state.tracksInterBlockMargin===!1)return;state.renderable.marginBottom=this.getInterBlockMargin(token,nextToken)}createMarkdownBlockToken(raw){return{type:"paragraph",raw,text:raw,tokens:[]}}normalizeMarkdownBlockRaw(raw){return raw.replace(TRAILING_MARKDOWN_BLOCK_BREAKS_RE,`
3644
3644
  `)}normalizeScrollbackMarkdownBlockRaw(raw){return raw.replace(TRAILING_MARKDOWN_BLOCK_NEWLINES_RE,"")}isCodeBlockOnlyRenderer(){return this._renderNode?.codeBlockOnly===!0}buildRenderableTokens(tokens){if(this._renderNode&&!this.isCodeBlockOnlyRenderer())return tokens.filter((token)=>token.type!=="space");let renderTokens=[],markdownRaw="",flushMarkdownRaw=()=>{if(markdownRaw.length===0)return;let normalizedRaw=this.normalizeMarkdownBlockRaw(markdownRaw);if(normalizedRaw.length>0)renderTokens.push(this.createMarkdownBlockToken(normalizedRaw));markdownRaw=""};for(let i=0;i<tokens.length;i+=1){let token=tokens[i];if(token.type==="space"){if(markdownRaw.length===0)continue;let nextIndex=i+1;while(nextIndex<tokens.length&&tokens[nextIndex].type==="space")nextIndex+=1;let nextToken=tokens[nextIndex];if(nextToken&&!this.shouldRenderSeparately(nextToken))markdownRaw+=token.raw;continue}if(this.shouldRenderSeparately(token)){flushMarkdownRaw(),renderTokens.push(token);continue}markdownRaw+=token.raw}return flushMarkdownRaw(),renderTokens}buildTopLevelRenderBlocks(tokens){let blocks=[],gapBefore="";for(let i=0;i<tokens.length;i+=1){let token=tokens[i];if(token.type==="space"){gapBefore+=token.raw;continue}let prev=blocks[blocks.length-1],marginTop=prev&&this.shouldAddTopLevelMargin(prev.token,token,gapBefore)?1:0;blocks.push({token,sourceTokenEnd:i+1,marginTop}),gapBefore=""}return blocks}shouldAddTopLevelMargin(prev,current,gapBefore){if(this.isSeparatedTopLevelBlock(prev)||this.isSeparatedTopLevelBlock(current))return!0;if(prev.type!=="paragraph"||current.type!=="paragraph")return!1;return TRAILING_MARKDOWN_BLOCK_BREAKS_RE.test(prev.raw+gapBefore)}isSeparatedTopLevelBlock(token){return token.type==="heading"||token.type==="list"||this.shouldRenderSeparately(token)}getTableRowsToRender(table){return table.rows}hashString(value,seed){let hash=seed>>>0;for(let i=0;i<value.length;i+=1)hash^=value.charCodeAt(i),hash=Math.imul(hash,16777619);return hash>>>0}hashTableToken(token,seed,depth=0){let hash=this.hashString(token.type,seed);if("raw"in token&&typeof token.raw==="string")return this.hashString(token.raw,hash);if("text"in token&&typeof token.text==="string")hash=this.hashString(token.text,hash);if(depth<2&&"tokens"in token&&Array.isArray(token.tokens))for(let child of token.tokens)hash=this.hashTableToken(child,hash,depth+1);return hash>>>0}getTableCellKey(cell,isHeader){let seed=isHeader?2902232141:1371922141;if(!cell)return seed;if(typeof cell.text==="string")return this.hashString(cell.text,seed);if(Array.isArray(cell.tokens)&&cell.tokens.length>0){let hash=seed^cell.tokens.length;for(let token of cell.tokens)hash=this.hashTableToken(token,hash);return hash>>>0}return(seed^2654435769)>>>0}createTableDataCellChunks(cell){let chunks=[];if(cell)this.renderInlineContent(cell.tokens,chunks);return chunks.length>0?chunks:[this.createDefaultChunk(" ")]}createTableHeaderCellChunks(cell){let chunks=[];this.renderInlineContent(cell.tokens,chunks);let baseChunks=chunks.length>0?chunks:[this.createDefaultChunk(" ")],headingStyle=this.getStyle("markup.heading")||this.getStyle("default");if(!headingStyle)return baseChunks;let headingAttributes=createTextAttributes({bold:headingStyle.bold,italic:headingStyle.italic,underline:headingStyle.underline,dim:headingStyle.dim});return baseChunks.map((chunk)=>({...chunk,fg:headingStyle.fg??chunk.fg,bg:headingStyle.bg??chunk.bg,attributes:headingAttributes}))}buildTableContentCache(table,previous,forceRegenerate=!1){let colCount=table.header.length,rowsToRender=this.getTableRowsToRender(table);if(colCount===0||rowsToRender.length===0)return{cache:null,changed:previous!==void 0};let content=[],cellKeys=[],totalRows=rowsToRender.length+1,changed=forceRegenerate||!previous;for(let rowIndex=0;rowIndex<totalRows;rowIndex+=1){let rowContent=[],rowKeys=new Uint32Array(colCount);for(let colIndex=0;colIndex<colCount;colIndex+=1){let isHeader=rowIndex===0,cell=isHeader?table.header[colIndex]:rowsToRender[rowIndex-1]?.[colIndex],cellKey=this.getTableCellKey(cell,isHeader);rowKeys[colIndex]=cellKey;let previousCellKey=previous?.cellKeys[rowIndex]?.[colIndex],previousCellContent=previous?.content[rowIndex]?.[colIndex];if(!forceRegenerate&&previousCellKey===cellKey&&Array.isArray(previousCellContent)){rowContent.push(previousCellContent);continue}changed=!0,rowContent.push(isHeader?this.createTableHeaderCellChunks(table.header[colIndex]):this.createTableDataCellChunks(cell))}content.push(rowContent),cellKeys.push(rowKeys)}if(previous&&!changed){if(previous.content.length!==content.length)changed=!0;else for(let rowIndex=0;rowIndex<content.length;rowIndex+=1)if((previous.content[rowIndex]?.length??0)!==content[rowIndex].length){changed=!0;break}}return{cache:{content,cellKeys},changed}}resolveTableStyle(options=this._tableOptions){if(options?.style==="columns")return"columns";if(options?.style==="grid")return"grid";return this._internalBlockMode==="top-level"?"columns":"grid"}usesBorderlessColumnSpacing(options=this._tableOptions){let style=this.resolveTableStyle(options),borders=options?.borders??style==="grid";return style==="columns"&&!borders}resolveTableRenderableOptions(){let style=this.resolveTableStyle(),borders=this._tableOptions?.borders??style==="grid";return{columnWidthMode:this._tableOptions?.widthMode??(style==="columns"?"content":"full"),columnFitter:this._tableOptions?.columnFitter??"proportional",wrapMode:this._tableOptions?.wrapMode??"word",cellPadding:this._tableOptions?.cellPadding??0,cellPaddingX:this._tableOptions?.cellPaddingX??this._tableOptions?.cellPadding??0,cellPaddingY:this._tableOptions?.cellPaddingY??this._tableOptions?.cellPadding??0,columnGap:this.usesBorderlessColumnSpacing()?2:0,border:borders,outerBorder:this._tableOptions?.outerBorder??borders,showBorders:borders,borderStyle:this._tableOptions?.borderStyle??"single",borderColor:this._tableOptions?.borderColor??this.getStyle("conceal")?.fg??"#888888",selectable:this._tableOptions?.selectable??!0}}applyTableRenderableOptions(tableRenderable,options){tableRenderable.columnWidthMode=options.columnWidthMode,tableRenderable.columnFitter=options.columnFitter,tableRenderable.wrapMode=options.wrapMode,tableRenderable.cellPaddingX=options.cellPaddingX,tableRenderable.cellPaddingY=options.cellPaddingY,tableRenderable.columnGap=options.columnGap,tableRenderable.border=options.border,tableRenderable.outerBorder=options.outerBorder,tableRenderable.showBorders=options.showBorders,tableRenderable.borderStyle=options.borderStyle,tableRenderable.borderColor=options.borderColor,tableRenderable.selectable=options.selectable}applyTableOptionsToBlocks(){let options=this.resolveTableRenderableOptions(),updated=!1;for(let state of this._blockStates)if(state.renderable instanceof TextTableRenderable)this.applyTableRenderableOptions(state.renderable,options),updated=!0;if(updated)this.requestRender()}createTextTableRenderable(content,id,marginBottom=0){let options=this.resolveTableRenderableOptions();return new TextTableRenderable(this.ctx,{id,content,width:"100%",marginBottom,columnWidthMode:options.columnWidthMode,columnFitter:options.columnFitter,wrapMode:options.wrapMode,cellPadding:options.cellPadding,cellPaddingX:options.cellPaddingX,cellPaddingY:options.cellPaddingY,columnGap:options.columnGap,border:options.border,outerBorder:options.outerBorder,showBorders:options.showBorders,borderStyle:options.borderStyle,borderColor:options.borderColor,selectable:options.selectable})}createTableBlock(table,id,marginBottom=0,previousCache,forceRegenerate=!1){let{cache}=this.buildTableContentCache(table,previousCache,forceRegenerate);if(!cache)return{renderable:this.createMarkdownCodeRenderable(table.raw,id,marginBottom)};return{renderable:this.createTextTableRenderable(cache.content,id,marginBottom),tableContentCache:cache}}getStableBlockCount(blocks,stableTokenCount){if(this._internalBlockMode!=="top-level")return 0;let stableBlockCount=0;for(let block of blocks){if(block.sourceTokenEnd<=stableTokenCount){stableBlockCount+=1;continue}break}return stableBlockCount}syncTopLevelBlockState(state,block,tableContentCache=state.tableContentCache){state.token=block.token,state.tokenRaw=block.token.raw,state.marginTop=block.marginTop,state.tableContentCache=tableContentCache}getTopLevelBlockRaw(token){if(!token.raw)return;return this.shouldRenderSeparately(token)?token.raw:this.normalizeScrollbackMarkdownBlockRaw(token.raw)}createTopLevelDefaultRenderable(block,index){let{token,marginTop}=block,id=`${this.id}-block-${index}`;if(token.type==="code"){let renderable2=this.createCodeRenderable(token,id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}if(token.type==="table"){let next=this.createTableBlock(token,id);return next.renderable.marginTop=marginTop,{...next,canUpdateInPlace:!0}}if(token.type==="blockquote"){let renderable2=this.createBlockquoteRenderable(token,id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}if(token.type==="list"){let renderable2=this.createListRenderable(token,id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}if(token.type==="hr"){let renderable2=this.createHorizontalRuleRenderable(id);return renderable2.marginTop=marginTop,{renderable:renderable2,canUpdateInPlace:!0}}let markdownRaw=this.getTopLevelBlockRaw(token);if(!markdownRaw)return{renderable:void 0,canUpdateInPlace:!0};let renderable=this.createMarkdownCodeRenderable(markdownRaw,id,0,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token));return renderable.marginTop=marginTop,{renderable,canUpdateInPlace:!0}}createTopLevelRenderable(block,index){if(!this._renderNode)return this.createTopLevelDefaultRenderable(block,index);let custom=this.createTopLevelCustomRenderable(block,index);if(!custom.renderable)return this.createTopLevelDefaultRenderable(block,index);let marginTop=typeof custom.renderable.marginTop==="number"?Math.max(custom.renderable.marginTop,block.marginTop):block.marginTop;return this.applyMargins(custom.renderable,marginTop,0),{renderable:custom.renderable,tableContentCache:custom.tableContentCache,canUpdateInPlace:custom.canUpdateInPlace}}createDefaultRenderable(token,index,nextToken){let id=`${this.id}-block-${index}`,marginBottom=this.getInterBlockMargin(token,nextToken);if(token.type==="code")return this.createCodeRenderable(token,id,marginBottom);if(token.type==="blockquote")return this.createBlockquoteRenderable(token,id,marginBottom);if(token.type==="list")return this.createListRenderable(token,id,marginBottom);if(token.type==="hr")return this.createHorizontalRuleRenderable(id,marginBottom);if(token.type==="table")return this.createTableBlock(token,id,marginBottom).renderable;if(token.type==="space")return null;if(!token.raw)return null;return this.createMarkdownCodeRenderable(token.raw,id,marginBottom,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token))}createCustomRenderable(token,index,nextToken){let custom=this.renderCustomNode(token,()=>{return{renderable:this.createDefaultRenderable(token,index,nextToken)}});if(!custom.renderable)return{tracksInterBlockMargin:!0,canUpdateInPlace:!0};let canUpdateInPlace=custom.renderable===custom.defaultResult?.renderable;return{renderable:custom.renderable,tracksInterBlockMargin:canUpdateInPlace,canUpdateInPlace}}createTopLevelCustomRenderable(block,index){let custom=this.renderCustomNode(block.token,()=>{return this.createTopLevelDefaultRenderable(block,index)});if(!custom.renderable)return{tracksInterBlockMargin:!0,canUpdateInPlace:!0};let canUpdateInPlace=custom.renderable===custom.defaultResult?.renderable;return{renderable:custom.renderable,tableContentCache:canUpdateInPlace?custom.defaultResult?.tableContentCache:void 0,tracksInterBlockMargin:canUpdateInPlace,canUpdateInPlace}}renderCustomNode(token,createDefault){if(!this._renderNode)return{};let defaultResult,custom=this._renderNode(token,{syntaxStyle:this._syntaxStyle,conceal:this._conceal,concealCode:this._concealCode,treeSitterClient:this._treeSitterClient,defaultRender:()=>{return defaultResult=createDefault(),defaultResult.renderable??null}});return this.destroyUnusedDefaultRenderable(defaultResult?.renderable,custom??void 0),custom?{renderable:custom,defaultResult}:{}}destroyUnusedDefaultRenderable(renderable,usedRenderable){if(!renderable||renderable===usedRenderable||renderable.parent)return;renderable.destroyRecursively()}updateBlockRenderable(state,token,index,nextToken,forceListRefresh=!1){let marginBottom=this.getInterBlockMargin(token,nextToken);if(token.type==="code"){this.applyCodeBlockRenderable(state.renderable,token,marginBottom);return}if(token.type==="blockquote"){this.applyBlockquoteRenderable(state.renderable,token,marginBottom);return}if(token.type==="list"){if(!this.applyListRenderable(state.renderable,token,forceListRefresh?void 0:state.token,`${this.id}-block-${index}`,marginBottom))state.renderable.destroyRecursively(),state.renderable=this.createListRenderable(token,`${this.id}-block-${index}`,marginBottom),this.add(state.renderable,index);return}if(token.type==="hr"){state.renderable.marginBottom=marginBottom;return}if(token.type==="table"){let tableToken=token,{cache,changed}=this.buildTableContentCache(tableToken,state.tableContentCache);if(!cache){if(state.renderable instanceof CodeRenderable){this.applyMarkdownCodeRenderable(state.renderable,tableToken.raw,marginBottom),state.tableContentCache=void 0;return}state.renderable.destroyRecursively();let fallbackRenderable=this.createMarkdownCodeRenderable(tableToken.raw,`${this.id}-block-${index}`,marginBottom);this.add(fallbackRenderable,index),state.renderable=fallbackRenderable,state.tableContentCache=void 0;return}if(state.renderable instanceof TextTableRenderable){if(changed)state.renderable.content=cache.content;this.applyTableRenderableOptions(state.renderable,this.resolveTableRenderableOptions()),state.renderable.marginBottom=marginBottom,state.tableContentCache=cache;return}state.renderable.destroyRecursively();let tableRenderable=this.createTextTableRenderable(cache.content,`${this.id}-block-${index}`,marginBottom);this.add(tableRenderable,index),state.renderable=tableRenderable,state.tableContentCache=cache;return}if(state.renderable instanceof CodeRenderable){this.applyMarkdownCodeRenderable(state.renderable,this.getTopLevelBlockRaw(token)??token.raw,marginBottom,void 0,this.createInitialStyledText(token));return}state.renderable.destroyRecursively();let markdownRenderable=this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(token)??token.raw,`${this.id}-block-${index}`,marginBottom,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(token));this.add(markdownRenderable,index),state.renderable=markdownRenderable}updateTopLevelBlocks(tokens,forceTableRefresh){let blocks=this.buildTopLevelRenderBlocks(tokens);this._stableBlockCount=this.getStableBlockCount(blocks,this._parseState?.stableTokenCount??0);let blockIndex=0;for(let i=0;i<blocks.length;i+=1){let block=blocks[i],existing=this._blockStates[blockIndex];if(existing&&existing.token===block.token&&!forceTableRefresh){if(existing.marginTop!==block.marginTop)this.applyMargins(existing.renderable,block.marginTop,0);this.syncTopLevelBlockState(existing,block),blockIndex++;continue}if(existing&&existing.tokenRaw===block.token.raw&&existing.token.type===block.token.type&&!forceTableRefresh){if(existing.marginTop!==block.marginTop)this.applyMargins(existing.renderable,block.marginTop,0);this.syncTopLevelBlockState(existing,block),blockIndex++;continue}if(existing&&!forceTableRefresh&&existing.canUpdateInPlace&&existing.token.type===block.token.type&&this.canUpdateBlockRenderable(existing.renderable,block.token)){if(this._renderNode){let custom=this.createTopLevelCustomRenderable(block,blockIndex);if(custom.renderable&&!custom.canUpdateInPlace){let marginTop=typeof custom.renderable.marginTop==="number"?Math.max(custom.renderable.marginTop,block.marginTop):block.marginTop;if(this.applyMargins(custom.renderable,marginTop,0),custom.renderable!==existing.renderable)existing.renderable.destroyRecursively(),this.add(custom.renderable,blockIndex);this._blockStates[blockIndex]={token:block.token,tokenRaw:block.token.raw,marginTop:block.marginTop,renderable:custom.renderable,tableContentCache:custom.tableContentCache,canUpdateInPlace:custom.canUpdateInPlace},blockIndex++;continue}this.destroyUnusedDefaultRenderable(custom.renderable)}if(this.updateBlockRenderable(existing,block.token,blockIndex,blocks[i+1]?.token),existing.renderable.marginBottom=0,existing.marginTop!==block.marginTop)this.applyMargins(existing.renderable,block.marginTop,0);this.syncTopLevelBlockState(existing,block),blockIndex++;continue}if(existing)existing.renderable.destroyRecursively();let next=this.createTopLevelRenderable(block,blockIndex);if(next.renderable)this.add(next.renderable,blockIndex),this._blockStates[blockIndex]={token:block.token,tokenRaw:block.token.raw,marginTop:block.marginTop,renderable:next.renderable,tableContentCache:next.tableContentCache,canUpdateInPlace:next.canUpdateInPlace};blockIndex++}while(this._blockStates.length>blockIndex)this._blockStates.pop().renderable.destroyRecursively()}canUpdateBlockRenderable(renderable,token){if(token.type==="code")return renderable instanceof CodeRenderable;if(token.type==="table")return renderable instanceof TextTableRenderable;if(token.type==="blockquote")return renderable instanceof BoxRenderable;if(token.type==="list")return renderable instanceof BoxRenderable;if(token.type==="hr")return renderable instanceof BoxRenderable;return renderable instanceof CodeRenderable}updateBlocks(forceTableRefresh=!1){if(this.isDestroyed)return;if(!this._content){this.clearBlockStates(),this._parseState=null,this._stableBlockCount=0;return}let trailingUnstable=this._streaming?2:0;this._parseState=parseMarkdownIncremental(this._content,this._parseState,trailingUnstable);let tokens=this._parseState.tokens;if(tokens.length===0&&this._content.length>0){this.clearBlockStates(),this._stableBlockCount=0;let fallback=this.createMarkdownCodeRenderable(this._content,`${this.id}-fallback`);this.add(fallback),this._blockStates=[{token:{type:"text",raw:this._content,text:this._content},tokenRaw:this._content,marginTop:0,renderable:fallback,tracksInterBlockMargin:!0,canUpdateInPlace:!0}];return}if(this._internalBlockMode==="top-level"){this.updateTopLevelBlocks(tokens,forceTableRefresh);return}this._stableBlockCount=0;let blockTokens=this.buildRenderableTokens(tokens),blockIndex=0;for(let i=0;i<blockTokens.length;i++){let token=blockTokens[i],nextToken=blockTokens[i+1],existing=this._blockStates[blockIndex],shouldForceRefresh=forceTableRefresh;if(existing&&existing.token===token){if(shouldForceRefresh)this.updateBlockRenderable(existing,token,blockIndex,nextToken),existing.tokenRaw=token.raw;else this.applyInterBlockMargin(existing,token,nextToken);blockIndex++;continue}if(existing&&existing.tokenRaw===token.raw&&existing.token.type===token.type){if(existing.token=token,shouldForceRefresh)this.updateBlockRenderable(existing,token,blockIndex,nextToken),existing.tokenRaw=token.raw;else this.applyInterBlockMargin(existing,token,nextToken);blockIndex++;continue}if(existing&&existing.canUpdateInPlace&&existing.token.type===token.type){let custom2=this.createCustomRenderable(token,blockIndex,nextToken);if(custom2.renderable&&!custom2.canUpdateInPlace){if(custom2.renderable!==existing.renderable)existing.renderable.destroyRecursively(),this.add(custom2.renderable,blockIndex);this._blockStates[blockIndex]={token,tokenRaw:token.raw,renderable:custom2.renderable,tracksInterBlockMargin:custom2.tracksInterBlockMargin,canUpdateInPlace:custom2.canUpdateInPlace},blockIndex++;continue}this.destroyUnusedDefaultRenderable(custom2.renderable),this.updateBlockRenderable(existing,token,blockIndex,nextToken),existing.token=token,existing.tokenRaw=token.raw,existing.tracksInterBlockMargin=!0,blockIndex++;continue}if(existing)existing.renderable.destroyRecursively();let renderable,tableContentCache,tracksInterBlockMargin=!0,canUpdateInPlace=!0,custom=this.createCustomRenderable(token,blockIndex,nextToken);if(custom.renderable)renderable=custom.renderable,tracksInterBlockMargin=custom.tracksInterBlockMargin,canUpdateInPlace=custom.canUpdateInPlace;if(!renderable)if(token.type==="table"){let tableBlock=this.createTableBlock(token,`${this.id}-block-${blockIndex}`,this.getInterBlockMargin(token,nextToken));renderable=tableBlock.renderable,tableContentCache=tableBlock.tableContentCache}else renderable=this.createDefaultRenderable(token,blockIndex,nextToken)??void 0;if(token.type==="table"&&!tableContentCache&&renderable instanceof TextTableRenderable){let{cache}=this.buildTableContentCache(token);tableContentCache=cache??void 0}if(renderable)this.add(renderable,blockIndex),this._blockStates[blockIndex]={token,tokenRaw:token.raw,renderable,tableContentCache,tracksInterBlockMargin,canUpdateInPlace};blockIndex++}while(this._blockStates.length>blockIndex)this._blockStates.pop().renderable.destroyRecursively()}clearBlockStates(){for(let state of this._blockStates)state.renderable.destroyRecursively();this._blockStates=[],this._stableBlockCount=0}rerenderBlocks(){if(this._internalBlockMode==="top-level"){this.updateBlocks(!0);return}for(let i=0;i<this._blockStates.length;i++){let state=this._blockStates[i],marginBottom=this.getInterBlockMargin(state.token,this._blockStates[i+1]?.token);if(state.token.type==="code"){this.applyCodeBlockRenderable(state.renderable,state.token,marginBottom);continue}if(state.token.type==="blockquote"){this.applyBlockquoteRenderable(state.renderable,state.token,marginBottom);continue}if(state.token.type==="list"){this.updateBlockRenderable(state,state.token,i,this._blockStates[i+1]?.token,!0);continue}if(state.token.type==="hr"){state.renderable.marginBottom=marginBottom;continue}if(state.token.type==="table"){let tableToken=state.token,{cache}=this.buildTableContentCache(tableToken,state.tableContentCache,!0);if(!cache){if(state.renderable instanceof CodeRenderable)this.applyMarkdownCodeRenderable(state.renderable,tableToken.raw,marginBottom);else{state.renderable.destroyRecursively();let fallbackRenderable=this.createMarkdownCodeRenderable(tableToken.raw,`${this.id}-block-${i}`,marginBottom);this.add(fallbackRenderable,i),state.renderable=fallbackRenderable}state.tableContentCache=void 0;continue}if(state.renderable instanceof TextTableRenderable){state.renderable.content=cache.content,this.applyTableRenderableOptions(state.renderable,this.resolveTableRenderableOptions()),state.renderable.marginBottom=marginBottom,state.tableContentCache=cache;continue}state.renderable.destroyRecursively();let tableRenderable=this.createTextTableRenderable(cache.content,`${this.id}-block-${i}`,marginBottom);this.add(tableRenderable,i),state.renderable=tableRenderable,state.tableContentCache=cache;continue}if(state.renderable instanceof CodeRenderable){this.applyMarkdownCodeRenderable(state.renderable,this.getTopLevelBlockRaw(state.token)??state.token.raw,marginBottom,void 0,this.createInitialStyledText(state.token));continue}state.renderable.destroyRecursively();let markdownRenderable=this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(state.token)??state.token.raw,`${this.id}-block-${i}`,marginBottom,this._linkifyMarkdownChunks,void 0,this.createInitialStyledText(state.token));this.add(markdownRenderable,i),state.renderable=markdownRenderable}}clearCache(){this._parseState=null,this.clearBlockStates(),this.updateBlocks(),this.requestRender()}refreshStyles(){this._styleDirty=!1,this.rerenderBlocks(),this.requestRender()}renderSelf(buffer,deltaTime){if(this._styleDirty)this._styleDirty=!1,this.rerenderBlocks();super.renderSelf(buffer,deltaTime)}}var defaultThumbBackgroundColor=RGBA.fromHex("#9a9ea3"),defaultTrackBackgroundColor=RGBA.fromHex("#252527");class SliderRenderable extends Renderable{orientation;_value;_min;_max;_viewPortSize;_backgroundColor;_foregroundColor;_onChange;constructor(ctx,options){super(ctx,{flexShrink:0,...options});this.orientation=options.orientation,this._min=options.min??0,this._max=options.max??100,this._value=options.value??this._min,this._viewPortSize=options.viewPortSize??Math.max(1,(this._max-this._min)*0.1),this._onChange=options.onChange,this._backgroundColor=options.backgroundColor?parseColor(options.backgroundColor):defaultTrackBackgroundColor,this._foregroundColor=options.foregroundColor?parseColor(options.foregroundColor):defaultThumbBackgroundColor,this.setupMouseHandling()}get value(){return this._value}set value(newValue){let clamped=Math.max(this._min,Math.min(this._max,newValue));if(clamped!==this._value)this._value=clamped,this._onChange?.(clamped),this.emit("change",{value:clamped}),this.requestRender()}get min(){return this._min}set min(newMin){if(newMin!==this._min){if(this._min=newMin,this._value<newMin)this.value=newMin;this.requestRender()}}get max(){return this._max}set max(newMax){if(newMax!==this._max){if(this._max=newMax,this._value>newMax)this.value=newMax;this.requestRender()}}set viewPortSize(size){let clampedSize=Math.max(0.01,Math.min(size,this._max-this._min));if(clampedSize!==this._viewPortSize)this._viewPortSize=clampedSize,this.requestRender()}get viewPortSize(){return this._viewPortSize}get backgroundColor(){return this._backgroundColor}set backgroundColor(value){this._backgroundColor=parseColor(value),this.requestRender()}get foregroundColor(){return this._foregroundColor}set foregroundColor(value){this._foregroundColor=parseColor(value),this.requestRender()}calculateDragOffsetVirtual(event){let trackStart=this.orientation==="vertical"?this.y:this.x,mousePos=(this.orientation==="vertical"?event.y:event.x)-trackStart,virtualMousePos=Math.max(0,Math.min((this.orientation==="vertical"?this.height:this.width)*2,mousePos*2)),virtualThumbStart=this.getVirtualThumbStart(),virtualThumbSize=this.getVirtualThumbSize();return Math.max(0,Math.min(virtualThumbSize,virtualMousePos-virtualThumbStart))}setupMouseHandling(){let isDragging=!1,dragOffsetVirtual=0;this.onMouseDown=(event)=>{event.stopPropagation(),event.preventDefault();let thumb=this.getThumbRect();if(event.x>=thumb.x&&event.x<thumb.x+thumb.width&&event.y>=thumb.y&&event.y<thumb.y+thumb.height)isDragging=!0,dragOffsetVirtual=this.calculateDragOffsetVirtual(event);else this.updateValueFromMouseDirect(event),isDragging=!0,dragOffsetVirtual=this.calculateDragOffsetVirtual(event)},this.onMouseDrag=(event)=>{if(!isDragging)return;event.stopPropagation(),this.updateValueFromMouseWithOffset(event,dragOffsetVirtual)},this.onMouseUp=(event)=>{if(isDragging)this.updateValueFromMouseWithOffset(event,dragOffsetVirtual);isDragging=!1}}updateValueFromMouseDirect(event){let trackStart=this.orientation==="vertical"?this.y:this.x,trackSize=this.orientation==="vertical"?this.height:this.width,relativeMousePos=(this.orientation==="vertical"?event.y:event.x)-trackStart,clampedMousePos=Math.max(0,Math.min(trackSize,relativeMousePos)),ratio=trackSize===0?0:clampedMousePos/trackSize,range=this._max-this._min,newValue=this._min+ratio*range;this.value=newValue}updateValueFromMouseWithOffset(event,offsetVirtual){let trackStart=this.orientation==="vertical"?this.y:this.x,trackSize=this.orientation==="vertical"?this.height:this.width,mousePos=this.orientation==="vertical"?event.y:event.x,virtualTrackSize=trackSize*2,relativeMousePos=mousePos-trackStart,virtualMousePos=Math.max(0,Math.min(trackSize,relativeMousePos))*2,virtualThumbSize=this.getVirtualThumbSize(),maxThumbStart=Math.max(0,virtualTrackSize-virtualThumbSize),desiredThumbStart=virtualMousePos-offsetVirtual;desiredThumbStart=Math.max(0,Math.min(maxThumbStart,desiredThumbStart));let ratio=maxThumbStart===0?0:desiredThumbStart/maxThumbStart,range=this._max-this._min,newValue=this._min+ratio*range;this.value=newValue}getThumbRect(){let virtualThumbSize=this.getVirtualThumbSize(),virtualThumbStart=this.getVirtualThumbStart(),realThumbStart=Math.floor(virtualThumbStart/2),realThumbSize=Math.ceil((virtualThumbStart+virtualThumbSize)/2)-realThumbStart;if(this.orientation==="vertical")return{x:this.x,y:this.y+realThumbStart,width:this.width,height:Math.max(1,realThumbSize)};else return{x:this.x+realThumbStart,y:this.y,width:Math.max(1,realThumbSize),height:this.height}}renderSelf(buffer){if(this.orientation==="horizontal")this.renderHorizontal(buffer);else this.renderVertical(buffer)}renderHorizontal(buffer){let virtualThumbSize=this.getVirtualThumbSize(),virtualThumbStart=this.getVirtualThumbStart(),virtualThumbEnd=virtualThumbStart+virtualThumbSize;buffer.fillRect(this.x,this.y,this.width,this.height,this._backgroundColor);let realStartCell=Math.floor(virtualThumbStart/2),realEndCell=Math.ceil(virtualThumbEnd/2)-1,startX=Math.max(0,realStartCell),endX=Math.min(this.width-1,realEndCell);for(let realX=startX;realX<=endX;realX++){let virtualCellStart=realX*2,virtualCellEnd=virtualCellStart+2,thumbStartInCell=Math.max(virtualThumbStart,virtualCellStart),coverage=Math.min(virtualThumbEnd,virtualCellEnd)-thumbStartInCell,char=" ";if(coverage>=2)char="\u2588";else if(thumbStartInCell===virtualCellStart)char="\u258C";else char="\u2590";for(let y2=0;y2<this.height;y2++)buffer.setCellWithAlphaBlending(this.x+realX,this.y+y2,char,this._foregroundColor,this._backgroundColor)}}renderVertical(buffer){let virtualThumbSize=this.getVirtualThumbSize(),virtualThumbStart=this.getVirtualThumbStart(),virtualThumbEnd=virtualThumbStart+virtualThumbSize;buffer.fillRect(this.x,this.y,this.width,this.height,this._backgroundColor);let realStartCell=Math.floor(virtualThumbStart/2),realEndCell=Math.ceil(virtualThumbEnd/2)-1,startY=Math.max(0,realStartCell),endY=Math.min(this.height-1,realEndCell);for(let realY=startY;realY<=endY;realY++){let virtualCellStart=realY*2,virtualCellEnd=virtualCellStart+2,thumbStartInCell=Math.max(virtualThumbStart,virtualCellStart),coverage=Math.min(virtualThumbEnd,virtualCellEnd)-thumbStartInCell,char=" ";if(coverage>=2)char="\u2588";else if(coverage>0)if(thumbStartInCell-virtualCellStart===0)char="\u2580";else char="\u2584";for(let x2=0;x2<this.width;x2++)buffer.setCellWithAlphaBlending(this.x+x2,this.y+realY,char,this._foregroundColor,this._backgroundColor)}}getVirtualThumbSize(){let virtualTrackSize=this.orientation==="vertical"?this.height*2:this.width*2,range=this._max-this._min;if(range===0)return virtualTrackSize;let viewportSize=Math.max(1,this._viewPortSize),contentSize=range+viewportSize;if(contentSize<=viewportSize)return virtualTrackSize;let thumbRatio=viewportSize/contentSize,calculatedSize=Math.floor(virtualTrackSize*thumbRatio);return Math.max(1,Math.min(calculatedSize,virtualTrackSize))}getVirtualThumbStart(){let virtualTrackSize=this.orientation==="vertical"?this.height*2:this.width*2,range=this._max-this._min;if(range===0)return 0;let valueRatio=(this._value-this._min)/range,virtualThumbSize=this.getVirtualThumbSize();return Math.round(valueRatio*(virtualTrackSize-virtualThumbSize))}}class ScrollBarRenderable extends Renderable{slider;startArrow;endArrow;orientation;_focusable=!0;_scrollSize=0;_scrollPosition=0;_viewportSize=0;_showArrows=!1;_manualVisibility=!1;_onChange;scrollStep=null;get visible(){return super.visible}set visible(value){this._manualVisibility=!0,super.visible=value}resetVisibilityControl(){this._manualVisibility=!1,this.recalculateVisibility()}get scrollSize(){return this._scrollSize}get scrollPosition(){return this._scrollPosition}get viewportSize(){return this._viewportSize}set scrollSize(value){if(value===this.scrollSize)return;this._scrollSize=value,this.recalculateVisibility(),this.updateSliderFromScrollState(),this.scrollPosition=this.scrollPosition}set scrollPosition(value){let newPosition=Math.round(Math.min(Math.max(0,value),this.scrollSize-this.viewportSize));if(newPosition!==this._scrollPosition)this._scrollPosition=newPosition,this.updateSliderFromScrollState()}set viewportSize(value){if(value===this.viewportSize)return;this._viewportSize=value,this.slider.viewPortSize=Math.max(1,this._viewportSize),this.recalculateVisibility(),this.updateSliderFromScrollState(),this.scrollPosition=this.scrollPosition}get showArrows(){return this._showArrows}set showArrows(value){if(value===this._showArrows)return;this._showArrows=value,this.startArrow.visible=value,this.endArrow.visible=value}constructor(ctx,{trackOptions,arrowOptions,orientation,showArrows=!1,...options}){super(ctx,{flexDirection:orientation==="vertical"?"column":"row",alignSelf:"stretch",alignItems:"stretch",...options});this._onChange=options.onChange,this.orientation=orientation,this._showArrows=showArrows;let scrollRange=Math.max(0,this._scrollSize-this._viewportSize),defaultStepSize=Math.max(1,this._viewportSize),stepSize=trackOptions?.viewPortSize??defaultStepSize;this.slider=new SliderRenderable(ctx,{orientation,min:0,max:scrollRange,value:this._scrollPosition,viewPortSize:stepSize,onChange:(value)=>{this._scrollPosition=Math.round(value),this._onChange?.(this._scrollPosition),this.emit("change",{position:this._scrollPosition})},...orientation==="vertical"?{width:Math.max(1,Math.min(2,this.width)),height:"100%",marginLeft:"auto"}:{width:"100%",height:1,marginTop:"auto"},flexGrow:1,flexShrink:1,...trackOptions}),this.updateSliderFromScrollState();let arrowOpts=arrowOptions?{foregroundColor:arrowOptions.backgroundColor,backgroundColor:arrowOptions.backgroundColor,attributes:arrowOptions.attributes,...arrowOptions}:{};this.startArrow=new ArrowRenderable(ctx,{alignSelf:"center",visible:this.showArrows,direction:this.orientation==="vertical"?"up":"left",height:this.orientation==="vertical"?1:1,...arrowOpts}),this.endArrow=new ArrowRenderable(ctx,{alignSelf:"center",visible:this.showArrows,direction:this.orientation==="vertical"?"down":"right",height:this.orientation==="vertical"?1:1,...arrowOpts}),this.add(this.startArrow),this.add(this.slider),this.add(this.endArrow);let startArrowMouseTimeout=void 0,endArrowMouseTimeout=void 0;this.startArrow.onMouseDown=(event)=>{event.stopPropagation(),event.preventDefault(),this.scrollBy(-0.5,"viewport"),startArrowMouseTimeout=setTimeout(()=>{this.scrollBy(-0.5,"viewport"),startArrowMouseTimeout=setInterval(()=>{this.scrollBy(-0.2,"viewport")},200)},500)},this.startArrow.onMouseUp=(event)=>{event.stopPropagation(),clearInterval(startArrowMouseTimeout)},this.endArrow.onMouseDown=(event)=>{event.stopPropagation(),event.preventDefault(),this.scrollBy(0.5,"viewport"),endArrowMouseTimeout=setTimeout(()=>{this.scrollBy(0.5,"viewport"),endArrowMouseTimeout=setInterval(()=>{this.scrollBy(0.2,"viewport")},200)},500)},this.endArrow.onMouseUp=(event)=>{event.stopPropagation(),clearInterval(endArrowMouseTimeout)}}set arrowOptions(options){Object.assign(this.startArrow,options),Object.assign(this.endArrow,options),this.requestRender()}set trackOptions(options){Object.assign(this.slider,options),this.requestRender()}updateSliderFromScrollState(){let scrollRange=Math.max(0,this._scrollSize-this._viewportSize);this.slider.min=0,this.slider.max=scrollRange,this.slider.value=Math.min(this._scrollPosition,scrollRange)}scrollBy(delta,unit="absolute"){let resolvedDelta=(unit==="viewport"?this.viewportSize:unit==="content"?this.scrollSize:unit==="step"?this.scrollStep??1:1)*delta;this.scrollPosition+=resolvedDelta}recalculateVisibility(){if(!this._manualVisibility){let sizeRatio=this.scrollSize<=this.viewportSize?1:this.viewportSize/this.scrollSize;super.visible=sizeRatio<1}}handleKeyPress(key){switch(key.name){case"left":case"h":if(this.orientation!=="horizontal")return!1;return this.scrollBy(-0.2,"viewport"),!0;case"right":case"l":if(this.orientation!=="horizontal")return!1;return this.scrollBy(0.2,"viewport"),!0;case"up":case"k":if(this.orientation!=="vertical")return!1;return this.scrollBy(-0.2,"viewport"),!0;case"down":case"j":if(this.orientation!=="vertical")return!1;return this.scrollBy(0.2,"viewport"),!0;case"pageup":return this.scrollBy(-0.5,"viewport"),!0;case"pagedown":return this.scrollBy(0.5,"viewport"),!0;case"home":return this.scrollBy(-1,"content"),!0;case"end":return this.scrollBy(1,"content"),!0}return!1}}class ArrowRenderable extends Renderable{_direction;_foregroundColor;_backgroundColor;_attributes;_arrowChars;constructor(ctx,options){super(ctx,options);if(this._direction=options.direction,this._foregroundColor=options.foregroundColor?parseColor(options.foregroundColor):RGBA.fromValues(1,1,1,1),this._backgroundColor=options.backgroundColor?parseColor(options.backgroundColor):RGBA.fromValues(0,0,0,0),this._attributes=options.attributes??0,this._arrowChars={up:"\u25B2",down:"\u25BC",left:"\u25C0",right:"\u25B6",...options.arrowChars},!options.width)this.width=stringWidth2(this.getArrowChar())}get direction(){return this._direction}set direction(value){if(this._direction!==value)this._direction=value,this.requestRender()}get foregroundColor(){return this._foregroundColor}set foregroundColor(value){if(this._foregroundColor!==value)this._foregroundColor=parseColor(value),this.requestRender()}get backgroundColor(){return this._backgroundColor}set backgroundColor(value){if(this._backgroundColor!==value)this._backgroundColor=parseColor(value),this.requestRender()}get attributes(){return this._attributes}set attributes(value){if(this._attributes!==value)this._attributes=value,this.requestRender()}set arrowChars(value){this._arrowChars={...this._arrowChars,...value},this.requestRender()}renderSelf(buffer){let char=this.getArrowChar();buffer.drawText(char,this.x,this.y,this._foregroundColor,this._backgroundColor,this._attributes)}getArrowChar(){switch(this._direction){case"up":return this._arrowChars.up;case"down":return this._arrowChars.down;case"left":return this._arrowChars.left;case"right":return this._arrowChars.right;default:return"?"}}}class ContentRenderable extends BoxRenderable{viewport;_viewportCulling;constructor(ctx,viewport,viewportCulling,options){super(ctx,options);this.viewport=viewport,this._viewportCulling=viewportCulling}get viewportCulling(){return this._viewportCulling}set viewportCulling(value){this._viewportCulling=value}_hasVisibleChildFilter(){return this._viewportCulling}_getVisibleChildren(){if(this._viewportCulling)return getObjectsInViewport({x:this.viewport.screenX,y:this.viewport.screenY,width:this.viewport.width,height:this.viewport.height},this.getChildrenSortedByPrimaryAxis(),this.primaryAxis,0).map((child)=>child.num);return super._getVisibleChildren()}}var SCROLLBOX_PADDING_KEYS=["padding","paddingX","paddingY","paddingTop","paddingRight","paddingBottom","paddingLeft"];function pickScrollBoxPadding(options){if(!options)return{};let picked={};for(let key of SCROLLBOX_PADDING_KEYS){let value=options[key];if(value!==void 0)picked[key]=value}return picked}function stripScrollBoxPadding(options){let sanitized={...options};for(let key of SCROLLBOX_PADDING_KEYS)delete sanitized[key];return sanitized}class ScrollBoxRenderable extends BoxRenderable{static idCounter=0;internalId=0;wrapper;viewport;content;horizontalScrollBar;verticalScrollBar;_focusable=!0;selectionListener;autoScrollMouseX=0;autoScrollMouseY=0;autoScrollThresholdVertical=3;autoScrollThresholdHorizontal=3;autoScrollSpeedSlow=6;autoScrollSpeedMedium=36;autoScrollSpeedFast=72;isAutoScrolling=!1;cachedAutoScrollSpeed=3;autoScrollAccumulatorX=0;autoScrollAccumulatorY=0;scrollAccumulatorX=0;scrollAccumulatorY=0;_stickyScroll;_stickyScrollTop=!1;_stickyScrollBottom=!1;_stickyScrollLeft=!1;_stickyScrollRight=!1;_stickyStart;_hasManualScroll=!1;_isApplyingStickyScroll=!1;scrollAccel;get stickyScroll(){return this._stickyScroll}set stickyScroll(value){this._stickyScroll=value,this.updateStickyState()}get stickyStart(){return this._stickyStart}set stickyStart(value){this._stickyStart=value,this.updateStickyState()}get scrollTop(){return this.verticalScrollBar.scrollPosition}set scrollTop(value){this.verticalScrollBar.scrollPosition=value,this.updateStickyState()}get scrollLeft(){return this.horizontalScrollBar.scrollPosition}set scrollLeft(value){this.horizontalScrollBar.scrollPosition=value,this.updateStickyState()}get scrollWidth(){return this.horizontalScrollBar.scrollSize}get scrollHeight(){return this.verticalScrollBar.scrollSize}updateStickyState(){if(!this._stickyScroll){this.syncManualScrollState();return}let maxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),maxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width);if(this.scrollTop<=0)this._stickyScrollTop=!0,this._stickyScrollBottom=!1;else if(this.scrollTop>=maxScrollTop)this._stickyScrollTop=!1,this._stickyScrollBottom=!0;else this._stickyScrollTop=!1,this._stickyScrollBottom=!1;if(this.scrollLeft<=0)this._stickyScrollLeft=!0,this._stickyScrollRight=!1;else if(this.scrollLeft>=maxScrollLeft)this._stickyScrollLeft=!1,this._stickyScrollRight=!0;else this._stickyScrollLeft=!1,this._stickyScrollRight=!1;this.syncManualScrollState()}syncManualScrollState(){if(!this._stickyScroll){this._hasManualScroll=!1;return}let maxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),maxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width),hasScrollableContent=maxScrollTop>1||maxScrollLeft>1;if(this._isApplyingStickyScroll){if(this._hasManualScroll&&hasScrollableContent&&this.isAtStickyPosition())this._hasManualScroll=!1;return}this._hasManualScroll=hasScrollableContent&&!this.isAtStickyPosition()}applyStickyStart(stickyStart){let wasApplyingStickyScroll=this._isApplyingStickyScroll;this._isApplyingStickyScroll=!0;try{switch(stickyStart){case"top":this._stickyScrollTop=!0,this._stickyScrollBottom=!1,this.verticalScrollBar.scrollPosition=0;break;case"bottom":this._stickyScrollTop=!1,this._stickyScrollBottom=!0,this.verticalScrollBar.scrollPosition=Math.max(0,this.scrollHeight-this.viewport.height);break;case"left":this._stickyScrollLeft=!0,this._stickyScrollRight=!1,this.horizontalScrollBar.scrollPosition=0;break;case"right":this._stickyScrollLeft=!1,this._stickyScrollRight=!0,this.horizontalScrollBar.scrollPosition=Math.max(0,this.scrollWidth-this.viewport.width);break}}finally{this._isApplyingStickyScroll=wasApplyingStickyScroll}}constructor(ctx,options){let{wrapperOptions,viewportOptions,contentOptions,rootOptions,scrollbarOptions,verticalScrollbarOptions,horizontalScrollbarOptions,stickyScroll=!1,stickyStart,scrollX=!1,scrollY=!0,scrollAcceleration,viewportCulling=!0,...rootBoxOptions}=options,forwardedContentPadding={...pickScrollBoxPadding(rootBoxOptions),...pickScrollBoxPadding(rootOptions)},sanitizedRootBoxOptions=stripScrollBoxPadding(rootBoxOptions),sanitizedRootOptions=rootOptions?stripScrollBoxPadding(rootOptions):void 0,mergedContentOptions={...forwardedContentPadding,...contentOptions};super(ctx,{flexDirection:"row",alignItems:"stretch",...sanitizedRootBoxOptions,...sanitizedRootOptions});if(this.internalId=ScrollBoxRenderable.idCounter++,this._stickyScroll=stickyScroll,this._stickyStart=stickyStart,this.scrollAccel=scrollAcceleration??new LinearScrollAccel,this.wrapper=new BoxRenderable(ctx,{flexDirection:"column",flexGrow:1,...wrapperOptions,id:`scroll-box-wrapper-${this.internalId}`}),super.add(this.wrapper),this.viewport=new BoxRenderable(ctx,{flexDirection:"column",flexGrow:1,overflow:"hidden",onSizeChange:()=>{this.recalculateBarProps()},...viewportOptions,id:`scroll-box-viewport-${this.internalId}`}),this.wrapper.add(this.viewport),this.content=new ContentRenderable(ctx,this.viewport,viewportCulling,{alignSelf:"flex-start",flexShrink:0,...scrollX?{minWidth:"100%"}:{minWidth:"100%",maxWidth:"100%"},...scrollY?{minHeight:"100%"}:{minHeight:"100%",maxHeight:"100%"},onSizeChange:()=>{this.recalculateBarProps()},...mergedContentOptions,id:`scroll-box-content-${this.internalId}`}),this.viewport.add(this.content),this.verticalScrollBar=new ScrollBarRenderable(ctx,{...scrollbarOptions,...verticalScrollbarOptions,arrowOptions:{...scrollbarOptions?.arrowOptions,...verticalScrollbarOptions?.arrowOptions},id:`scroll-box-vertical-scrollbar-${this.internalId}`,orientation:"vertical",onChange:(position)=>{this.content.translateY=-position,this.updateStickyState()}}),super.add(this.verticalScrollBar),this.horizontalScrollBar=new ScrollBarRenderable(ctx,{...scrollbarOptions,...horizontalScrollbarOptions,arrowOptions:{...scrollbarOptions?.arrowOptions,...horizontalScrollbarOptions?.arrowOptions},id:`scroll-box-horizontal-scrollbar-${this.internalId}`,orientation:"horizontal",onChange:(position)=>{this.content.translateX=-position,this.updateStickyState()}}),this.wrapper.add(this.horizontalScrollBar),this.recalculateBarProps(),stickyStart&&stickyScroll)this.applyStickyStart(stickyStart);this.selectionListener=()=>{let selection=this._ctx.getSelection();if(!selection||!selection.isDragging)this.stopAutoScroll()},this._ctx.on("selection",this.selectionListener)}onUpdate(deltaTime){this.handleAutoScroll(deltaTime)}scrollBy(delta,unit="absolute"){if(typeof delta==="number")this.verticalScrollBar.scrollBy(delta,unit);else this.verticalScrollBar.scrollBy(delta.y,unit),this.horizontalScrollBar.scrollBy(delta.x,unit)}scrollChildIntoView(childId){let child=this.content.findDescendantById(childId);if(!child)return;let getNearestDelta=(elementStart,elementEnd,viewportStart,viewportEnd)=>{let elementSize=elementEnd-elementStart,viewportSize=viewportEnd-viewportStart,elementStartOutside=elementStart<viewportStart,elementEndOutside=elementEnd>viewportEnd;if(elementStartOutside&&elementEndOutside)return 0;if(elementStartOutside&&elementSize<viewportSize||elementEndOutside&&elementSize>viewportSize)return elementStart-viewportStart;if(elementStartOutside&&elementSize>viewportSize||elementEndOutside&&elementSize<viewportSize)return elementEnd-viewportEnd;return 0},childTop=child.y,childBottom=child.y+child.height,viewportTop=this.viewport.y,viewportBottom=this.viewport.y+this.viewport.height,dy=getNearestDelta(childTop,childBottom,viewportTop,viewportBottom),childLeft=child.x,childRight=child.x+child.width,viewportLeft=this.viewport.x,viewportRight=this.viewport.x+this.viewport.width,dx=getNearestDelta(childLeft,childRight,viewportLeft,viewportRight);if(dx!==0||dy!==0)this.scrollBy({x:dx,y:dy})}scrollTo(position){if(typeof position==="number")this.scrollTop=position;else this.scrollTop=position.y,this.scrollLeft=position.x}isAtStickyPosition(){if(!this._stickyScroll||!this._stickyStart)return!1;let maxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),maxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width);switch(this._stickyStart){case"top":return this.scrollTop===0;case"bottom":return this.scrollTop>=maxScrollTop;case"left":return this.scrollLeft===0;case"right":return this.scrollLeft>=maxScrollLeft;default:return!1}}isAtStickyReengagePoint(stickyStart,maxScrollTop,maxScrollLeft){switch(stickyStart){case"top":return maxScrollTop>0&&this.scrollTop<=0;case"bottom":return maxScrollTop>0&&this.scrollTop>=maxScrollTop-1;case"left":return maxScrollLeft>0&&this.scrollLeft<=0;case"right":return maxScrollLeft>0&&this.scrollLeft>=maxScrollLeft-1}}add(obj,index){return this.content.add(obj,index)}insertBefore(obj,anchor){return this.content.insertBefore(obj,anchor)}remove(child){if(child.parent===this){super.remove(child);return}this.content.remove(child)}getChildren(){return this.content.getChildren()}getRenderable(id){return this.content.getRenderable(id)}onMouseEvent(event){if(event.type==="scroll"){let dir=event.scroll?.direction;if(event.modifiers.shift)dir=dir==="up"?"left":dir==="down"?"right":dir==="right"?"down":"up";let baseDelta=event.scroll?.delta??0,now=Date.now(),multiplier=this.scrollAccel.tick(now),scrollAmount=baseDelta*multiplier;if(dir==="up"){this.scrollAccumulatorY-=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorY);if(integerScroll!==0)this.scrollTop+=integerScroll,this.scrollAccumulatorY-=integerScroll}else if(dir==="down"){this.scrollAccumulatorY+=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorY);if(integerScroll!==0)this.scrollTop+=integerScroll,this.scrollAccumulatorY-=integerScroll}else if(dir==="left"){this.scrollAccumulatorX-=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorX);if(integerScroll!==0)this.scrollLeft+=integerScroll,this.scrollAccumulatorX-=integerScroll}else if(dir==="right"){this.scrollAccumulatorX+=scrollAmount;let integerScroll=Math.trunc(this.scrollAccumulatorX);if(integerScroll!==0)this.scrollLeft+=integerScroll,this.scrollAccumulatorX-=integerScroll}this.syncManualScrollState()}if(event.type==="drag"&&event.isDragging)this.updateAutoScroll(event.x,event.y);else if(event.type==="up")this.stopAutoScroll()}handleKeyPress(key){if(this.verticalScrollBar.handleKeyPress(key))return this.scrollAccel.reset(),this.resetScrollAccumulators(),this.syncManualScrollState(),!0;if(this.horizontalScrollBar.handleKeyPress(key))return this.scrollAccel.reset(),this.resetScrollAccumulators(),this.syncManualScrollState(),!0;return!1}resetScrollAccumulators(){this.scrollAccumulatorX=0,this.scrollAccumulatorY=0}startAutoScroll(mouseX,mouseY){if(this.stopAutoScroll(),this.autoScrollMouseX=mouseX,this.autoScrollMouseY=mouseY,this.cachedAutoScrollSpeed=this.getAutoScrollSpeed(mouseX,mouseY),this.isAutoScrolling=!0,!this.live)this.live=!0}updateAutoScroll(mouseX,mouseY){this.autoScrollMouseX=mouseX,this.autoScrollMouseY=mouseY,this.cachedAutoScrollSpeed=this.getAutoScrollSpeed(mouseX,mouseY);let scrollX=this.getAutoScrollDirectionX(mouseX),scrollY=this.getAutoScrollDirectionY(mouseY);if(scrollX===0&&scrollY===0)this.stopAutoScroll();else if(!this.isAutoScrolling)this.startAutoScroll(mouseX,mouseY)}stopAutoScroll(){let wasAutoScrolling=this.isAutoScrolling;if(this.isAutoScrolling=!1,this.autoScrollAccumulatorX=0,this.autoScrollAccumulatorY=0,wasAutoScrolling&&!this.hasOtherLiveReasons())this.live=!1}hasOtherLiveReasons(){return!1}handleAutoScroll(deltaTime){if(!this.isAutoScrolling)return;let scrollX=this.getAutoScrollDirectionX(this.autoScrollMouseX),scrollY=this.getAutoScrollDirectionY(this.autoScrollMouseY),scrollAmount=this.cachedAutoScrollSpeed*(deltaTime/1000),scrolled=!1;if(scrollX!==0){this.autoScrollAccumulatorX+=scrollX*scrollAmount;let integerScrollX=Math.trunc(this.autoScrollAccumulatorX);if(integerScrollX!==0)this.scrollLeft+=integerScrollX,this.autoScrollAccumulatorX-=integerScrollX,scrolled=!0}if(scrollY!==0){this.autoScrollAccumulatorY+=scrollY*scrollAmount;let integerScrollY=Math.trunc(this.autoScrollAccumulatorY);if(integerScrollY!==0)this.scrollTop+=integerScrollY,this.autoScrollAccumulatorY-=integerScrollY,scrolled=!0}if(scrolled)this._ctx.requestSelectionUpdate();if(scrollX===0&&scrollY===0)this.stopAutoScroll()}getAutoScrollDirectionX(mouseX){let relativeX=mouseX-this.x,distToLeft=relativeX,distToRight=this.width-relativeX;if(distToLeft<=this.autoScrollThresholdHorizontal)return this.scrollLeft>0?-1:0;else if(distToRight<=this.autoScrollThresholdHorizontal){let maxScrollLeft=this.scrollWidth-this.viewport.width;return this.scrollLeft<maxScrollLeft?1:0}return 0}getAutoScrollDirectionY(mouseY){let relativeY=mouseY-this.y,distToTop=relativeY,distToBottom=this.height-relativeY;if(distToTop<=this.autoScrollThresholdVertical)return this.scrollTop>0?-1:0;else if(distToBottom<=this.autoScrollThresholdVertical){let maxScrollTop=this.scrollHeight-this.viewport.height;return this.scrollTop<maxScrollTop?1:0}return 0}getAutoScrollSpeed(mouseX,mouseY){let relativeX=mouseX-this.x,relativeY=mouseY-this.y,distToLeft=relativeX,distToRight=this.width-relativeX,distToTop=relativeY,distToBottom=this.height-relativeY,minDistance=Math.min(distToLeft,distToRight,distToTop,distToBottom);if(minDistance<=1)return this.autoScrollSpeedFast;else if(minDistance<=2)return this.autoScrollSpeedMedium;else return this.autoScrollSpeedSlow}recalculateBarProps(){let wasApplyingStickyScroll=this._isApplyingStickyScroll;this._isApplyingStickyScroll=!0;try{if(this.verticalScrollBar.scrollSize=this.content.height,this.verticalScrollBar.viewportSize=this.viewport.height,this.horizontalScrollBar.scrollSize=this.content.width,this.horizontalScrollBar.viewportSize=this.viewport.width,this._stickyScroll){let newMaxScrollTop=Math.max(0,this.scrollHeight-this.viewport.height),newMaxScrollLeft=Math.max(0,this.scrollWidth-this.viewport.width),stickyStart=this._stickyStart;if(stickyStart&&!this._hasManualScroll)this.applyStickyStart(stickyStart);else if(stickyStart&&this._hasManualScroll&&this.isAtStickyReengagePoint(stickyStart,newMaxScrollTop,newMaxScrollLeft))this._hasManualScroll=!1,this.applyStickyStart(stickyStart);else if(!this._hasManualScroll){if(this._stickyScrollTop)this.scrollTop=0;else if(this._stickyScrollBottom&&newMaxScrollTop>0)this.scrollTop=newMaxScrollTop;if(this._stickyScrollLeft)this.scrollLeft=0;else if(this._stickyScrollRight&&newMaxScrollLeft>0)this.scrollLeft=newMaxScrollLeft}}}finally{this._isApplyingStickyScroll=wasApplyingStickyScroll}process.nextTick(()=>{this.requestRender()})}set padding(value){this.content.padding=value,this.requestRender()}set paddingX(value){this.content.paddingX=value,this.requestRender()}set paddingY(value){this.content.paddingY=value,this.requestRender()}set paddingTop(value){this.content.paddingTop=value,this.requestRender()}set paddingRight(value){this.content.paddingRight=value,this.requestRender()}set paddingBottom(value){this.content.paddingBottom=value,this.requestRender()}set paddingLeft(value){this.content.paddingLeft=value,this.requestRender()}set rootOptions(options){Object.assign(this,options),this.requestRender()}set wrapperOptions(options){Object.assign(this.wrapper,options),this.requestRender()}set viewportOptions(options){Object.assign(this.viewport,options),this.requestRender()}set contentOptions(options){Object.assign(this.content,options),this.requestRender()}set scrollbarOptions(options){Object.assign(this.verticalScrollBar,options),Object.assign(this.horizontalScrollBar,options),this.requestRender()}set verticalScrollbarOptions(options){Object.assign(this.verticalScrollBar,options),this.requestRender()}set horizontalScrollbarOptions(options){Object.assign(this.horizontalScrollBar,options),this.requestRender()}get scrollAcceleration(){return this.scrollAccel}set scrollAcceleration(value){this.scrollAccel=value}get viewportCulling(){return this.content.viewportCulling}set viewportCulling(value){this.content.viewportCulling=value,this.requestRender()}destroySelf(){if(this.selectionListener)this._ctx.off("selection",this.selectionListener),this.selectionListener=void 0;super.destroySelf()}}var defaultSelectKeybindings=[{name:"up",action:"move-up"},{name:"k",action:"move-up"},{name:"down",action:"move-down"},{name:"j",action:"move-down"},{name:"up",shift:!0,action:"move-up-fast"},{name:"down",shift:!0,action:"move-down-fast"},{name:"return",action:"select-current"},{name:"linefeed",action:"select-current"}],SelectRenderableEvents;((SelectRenderableEvents2)=>{SelectRenderableEvents2.SELECTION_CHANGED="selectionChanged",SelectRenderableEvents2.ITEM_SELECTED="itemSelected"})(SelectRenderableEvents||={});class SelectRenderable extends Renderable{_focusable=!0;_options=[];_selectedIndex=0;scrollOffset=0;maxVisibleItems;_backgroundColor;_textColor;_focusedBackgroundColor;_focusedTextColor;_selectedBackgroundColor;_selectedTextColor;_descriptionColor;_selectedDescriptionColor;_showScrollIndicator;_wrapSelection;_showDescription;_showSelectionIndicator;_font;_itemSpacing;linesPerItem;fontHeight;_fastScrollStep;_keyBindingsMap;_keyAliasMap;_keyBindings;_defaultOptions={backgroundColor:"transparent",textColor:"#FFFFFF",focusedBackgroundColor:"#1a1a1a",focusedTextColor:"#FFFFFF",selectedBackgroundColor:"#334455",selectedTextColor:"#FFFF00",selectedIndex:0,descriptionColor:"#888888",selectedDescriptionColor:"#CCCCCC",showScrollIndicator:!1,wrapSelection:!1,showDescription:!0,showSelectionIndicator:!0,itemSpacing:0,fastScrollStep:5};constructor(ctx,options){super(ctx,{...options,buffered:!0});this._options=options.options||[];let requestedIndex=options.selectedIndex??this._defaultOptions.selectedIndex;this._selectedIndex=this._options.length>0?Math.min(requestedIndex,this._options.length-1):0,this._backgroundColor=parseColor(options.backgroundColor||this._defaultOptions.backgroundColor),this._textColor=parseColor(options.textColor||this._defaultOptions.textColor),this._focusedBackgroundColor=parseColor(options.focusedBackgroundColor||this._defaultOptions.focusedBackgroundColor),this._focusedTextColor=parseColor(options.focusedTextColor||this._defaultOptions.focusedTextColor),this._showScrollIndicator=options.showScrollIndicator??this._defaultOptions.showScrollIndicator,this._wrapSelection=options.wrapSelection??this._defaultOptions.wrapSelection,this._showDescription=options.showDescription??this._defaultOptions.showDescription,this._showSelectionIndicator=options.showSelectionIndicator??this._defaultOptions.showSelectionIndicator,this._font=options.font,this._itemSpacing=options.itemSpacing||this._defaultOptions.itemSpacing,this.fontHeight=this._font?measureText({text:"A",font:this._font}).height:1,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this._selectedBackgroundColor=parseColor(options.selectedBackgroundColor||this._defaultOptions.selectedBackgroundColor),this._selectedTextColor=parseColor(options.selectedTextColor||this._defaultOptions.selectedTextColor),this._descriptionColor=parseColor(options.descriptionColor||this._defaultOptions.descriptionColor),this._selectedDescriptionColor=parseColor(options.selectedDescriptionColor||this._defaultOptions.selectedDescriptionColor),this._fastScrollStep=options.fastScrollStep||this._defaultOptions.fastScrollStep,this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,options.keyAliasMap||{}),this._keyBindings=options.keyBindings||[];let mergedBindings=mergeKeyBindings(defaultSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap),this.updateScrollOffset(),this.requestRender()}renderSelf(buffer,deltaTime){if(!this.visible||!this.frameBuffer)return;if(this.isDirty)this.refreshFrameBuffer()}refreshFrameBuffer(){if(!this.frameBuffer)return;let bgColor=this._focused?this._focusedBackgroundColor:this._backgroundColor;if(this.frameBuffer.clear(bgColor),this._options.length===0)return;let contentX=0,contentY=0,contentWidth=this.width,contentHeight=this.height,visibleOptions=this._options.slice(this.scrollOffset,this.scrollOffset+this.maxVisibleItems);for(let i=0;i<visibleOptions.length;i++){let actualIndex=this.scrollOffset+i,option=visibleOptions[i],isSelected=actualIndex===this._selectedIndex,itemY=contentY+i*this.linesPerItem;if(itemY+this.linesPerItem-1>=contentY+contentHeight)break;if(isSelected){let contentHeight2=this.linesPerItem-this._itemSpacing;this.frameBuffer.fillRect(contentX,itemY,contentWidth,contentHeight2,this._selectedBackgroundColor)}let indicator=this._showSelectionIndicator?isSelected?"\u25B6 ":" ":"",indicatorWidth=this._showSelectionIndicator?2:0,nameContent=`${indicator}${option.name}`,baseTextColor=this._focused?this._focusedTextColor:this._textColor,nameColor=isSelected?this._selectedTextColor:baseTextColor,textX=contentX+1+indicatorWidth;if(this._font){if(indicator)this.frameBuffer.drawText(indicator,contentX+1,itemY,nameColor);renderFontToFrameBuffer(this.frameBuffer,{text:option.name,x:textX,y:itemY,color:nameColor,backgroundColor:isSelected?this._selectedBackgroundColor:bgColor,font:this._font})}else this.frameBuffer.drawText(nameContent,contentX+1,itemY,nameColor);if(this._showDescription&&itemY+this.fontHeight<contentY+contentHeight){let descColor=isSelected?this._selectedDescriptionColor:this._descriptionColor;this.frameBuffer.drawText(option.description,textX,itemY+this.fontHeight,descColor)}}if(this._showScrollIndicator&&this._options.length>this.maxVisibleItems)this.renderScrollIndicatorToFrameBuffer(contentX,contentY,contentWidth,contentHeight)}renderScrollIndicatorToFrameBuffer(contentX,contentY,contentWidth,contentHeight){if(!this.frameBuffer)return;let maxScrollOffset=this._options.length-this.maxVisibleItems,scrollPercent=this.scrollOffset/maxScrollOffset,indicatorHeight=Math.max(1,contentHeight-2),indicatorY=contentY+1+Math.floor(scrollPercent*indicatorHeight),indicatorX=contentX+contentWidth-1;this.frameBuffer.drawText("\u2588",indicatorX,indicatorY,parseColor("#666666"))}get options(){return this._options}set options(options){this._options=options,this._selectedIndex=Math.min(this._selectedIndex,Math.max(0,options.length-1)),this.updateScrollOffset(),this.requestRender()}getSelectedOption(){return this._options[this._selectedIndex]||null}getSelectedIndex(){return this._selectedIndex}moveUp(steps=1){let newIndex=this._selectedIndex-steps;if(newIndex>=0)this._selectedIndex=newIndex;else if(this._wrapSelection&&this._options.length>0)this._selectedIndex=this._options.length-1;else this._selectedIndex=0;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this._selectedIndex,this.getSelectedOption())}moveDown(steps=1){let newIndex=this._selectedIndex+steps;if(newIndex<this._options.length)this._selectedIndex=newIndex;else if(this._wrapSelection&&this._options.length>0)this._selectedIndex=0;else this._selectedIndex=this._options.length-1;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this._selectedIndex,this.getSelectedOption())}selectCurrent(){let selected=this.getSelectedOption();if(selected)this.emit("itemSelected",this._selectedIndex,selected)}setSelectedIndex(index){if(index>=0&&index<this._options.length)this._selectedIndex=index,this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this._selectedIndex,this.getSelectedOption())}updateScrollOffset(){if(!this._options)return;let halfVisible=Math.floor(this.maxVisibleItems/2),newScrollOffset=Math.max(0,Math.min(this._selectedIndex-halfVisible,this._options.length-this.maxVisibleItems));if(newScrollOffset!==this.scrollOffset)this.scrollOffset=newScrollOffset,this.requestRender()}onResize(width,height){this.maxVisibleItems=Math.max(1,Math.floor(height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}handleKeyPress(key){let action=getKeyBindingAction(this._keyBindingsMap,key);if(action)switch(action){case"move-up":return this.moveUp(1),!0;case"move-down":return this.moveDown(1),!0;case"move-up-fast":return this.moveUp(this._fastScrollStep),!0;case"move-down-fast":return this.moveDown(this._fastScrollStep),!0;case"select-current":return this.selectCurrent(),!0}return!1}get showScrollIndicator(){return this._showScrollIndicator}set showScrollIndicator(show){this._showScrollIndicator=show,this.requestRender()}get showDescription(){return this._showDescription}set showDescription(show){if(this._showDescription!==show)this._showDescription=show,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}get showSelectionIndicator(){return this._showSelectionIndicator}set showSelectionIndicator(show){let next=show??this._defaultOptions.showSelectionIndicator;if(this._showSelectionIndicator!==next)this._showSelectionIndicator=next,this.requestRender()}get wrapSelection(){return this._wrapSelection}set wrapSelection(wrap){this._wrapSelection=wrap}set backgroundColor(value){let newColor=parseColor(value??this._defaultOptions.backgroundColor);if(this._backgroundColor!==newColor)this._backgroundColor=newColor,this.requestRender()}set textColor(value){let newColor=parseColor(value??this._defaultOptions.textColor);if(this._textColor!==newColor)this._textColor=newColor,this.requestRender()}set focusedBackgroundColor(value){let newColor=parseColor(value??this._defaultOptions.focusedBackgroundColor);if(this._focusedBackgroundColor!==newColor)this._focusedBackgroundColor=newColor,this.requestRender()}set focusedTextColor(value){let newColor=parseColor(value??this._defaultOptions.focusedTextColor);if(this._focusedTextColor!==newColor)this._focusedTextColor=newColor,this.requestRender()}set selectedBackgroundColor(value){let newColor=parseColor(value??this._defaultOptions.selectedBackgroundColor);if(this._selectedBackgroundColor!==newColor)this._selectedBackgroundColor=newColor,this.requestRender()}set selectedTextColor(value){let newColor=parseColor(value??this._defaultOptions.selectedTextColor);if(this._selectedTextColor!==newColor)this._selectedTextColor=newColor,this.requestRender()}set descriptionColor(value){let newColor=parseColor(value??this._defaultOptions.descriptionColor);if(this._descriptionColor!==newColor)this._descriptionColor=newColor,this.requestRender()}set selectedDescriptionColor(value){let newColor=parseColor(value??this._defaultOptions.selectedDescriptionColor);if(this._selectedDescriptionColor!==newColor)this._selectedDescriptionColor=newColor,this.requestRender()}set font(font){this._font=font,this.fontHeight=measureText({text:"A",font:this._font}).height,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}set itemSpacing(spacing){this._itemSpacing=spacing,this.linesPerItem=this._showDescription?this._font?this.fontHeight+1:2:this._font?this.fontHeight:1,this.linesPerItem+=this._itemSpacing,this.maxVisibleItems=Math.max(1,Math.floor(this.height/this.linesPerItem)),this.updateScrollOffset(),this.requestRender()}set fastScrollStep(step){this._fastScrollStep=step}set keyBindings(bindings){this._keyBindings=bindings;let mergedBindings=mergeKeyBindings(defaultSelectKeybindings,bindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}set keyAliasMap(aliases){this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,aliases);let mergedBindings=mergeKeyBindings(defaultSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}set selectedIndex(value){let newIndex=value??this._defaultOptions.selectedIndex,clampedIndex=this._options.length>0?Math.min(Math.max(0,newIndex),this._options.length-1):0;if(this._selectedIndex!==clampedIndex)this._selectedIndex=clampedIndex,this.updateScrollOffset(),this.requestRender()}}var defaultTabSelectKeybindings=[{name:"left",action:"move-left"},{name:"[",action:"move-left"},{name:"right",action:"move-right"},{name:"]",action:"move-right"},{name:"return",action:"select-current"},{name:"linefeed",action:"select-current"}],TabSelectRenderableEvents;((TabSelectRenderableEvents2)=>{TabSelectRenderableEvents2.SELECTION_CHANGED="selectionChanged",TabSelectRenderableEvents2.ITEM_SELECTED="itemSelected"})(TabSelectRenderableEvents||={});function calculateDynamicHeight(showUnderline,showDescription){let height=1;if(showUnderline)height+=1;if(showDescription)height+=1;return height}class TabSelectRenderable extends Renderable{_focusable=!0;_options=[];selectedIndex=0;scrollOffset=0;_tabWidth;maxVisibleTabs;_backgroundColor;_textColor;_focusedBackgroundColor;_focusedTextColor;_selectedBackgroundColor;_selectedTextColor;_selectedDescriptionColor;_showScrollArrows;_showDescription;_showUnderline;_wrapSelection;_keyBindingsMap;_keyAliasMap;_keyBindings;constructor(ctx,options){let calculatedHeight=calculateDynamicHeight(options.showUnderline??!0,options.showDescription??!0);super(ctx,{...options,height:calculatedHeight,buffered:!0});this._backgroundColor=parseColor(options.backgroundColor||"transparent"),this._textColor=parseColor(options.textColor||"#FFFFFF"),this._focusedBackgroundColor=parseColor(options.focusedBackgroundColor||options.backgroundColor||"#1a1a1a"),this._focusedTextColor=parseColor(options.focusedTextColor||options.textColor||"#FFFFFF"),this._options=options.options||[],this._tabWidth=options.tabWidth||20,this._showDescription=options.showDescription??!0,this._showUnderline=options.showUnderline??!0,this._showScrollArrows=options.showScrollArrows??!0,this._wrapSelection=options.wrapSelection??!1,this.maxVisibleTabs=Math.max(1,Math.floor(this.width/this._tabWidth)),this._selectedBackgroundColor=parseColor(options.selectedBackgroundColor||"#334455"),this._selectedTextColor=parseColor(options.selectedTextColor||"#FFFF00"),this._selectedDescriptionColor=parseColor(options.selectedDescriptionColor||"#CCCCCC"),this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,options.keyAliasMap||{}),this._keyBindings=options.keyBindings||[];let mergedBindings=mergeKeyBindings(defaultTabSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}calculateDynamicHeight(){return calculateDynamicHeight(this._showUnderline,this._showDescription)}renderSelf(buffer,deltaTime){if(!this.visible||!this.frameBuffer)return;if(this.isDirty)this.refreshFrameBuffer()}refreshFrameBuffer(){if(!this.frameBuffer)return;let bgColor=this._focused?this._focusedBackgroundColor:this._backgroundColor;if(this.frameBuffer.clear(bgColor),this._options.length===0)return;let contentX=0,contentY=0,contentWidth=this.width,contentHeight=this.height,visibleOptions=this._options.slice(this.scrollOffset,this.scrollOffset+this.maxVisibleTabs);for(let i=0;i<visibleOptions.length;i++){let actualIndex=this.scrollOffset+i,option=visibleOptions[i],isSelected=actualIndex===this.selectedIndex,tabX=contentX+i*this._tabWidth;if(tabX>=contentX+contentWidth)break;let actualTabWidth=Math.min(this._tabWidth,contentWidth-i*this._tabWidth);if(isSelected)this.frameBuffer.fillRect(tabX,contentY,actualTabWidth,1,this._selectedBackgroundColor);let baseTextColor=this._focused?this._focusedTextColor:this._textColor,nameColor=isSelected?this._selectedTextColor:baseTextColor,nameContent=this.truncateText(option.name,actualTabWidth-2);if(this.frameBuffer.drawText(nameContent,tabX+1,contentY,nameColor),isSelected&&this._showUnderline&&contentHeight>=2){let underlineY=contentY+1,underlineBg=isSelected?this._selectedBackgroundColor:bgColor;this.frameBuffer.drawText("\u25AC".repeat(actualTabWidth),tabX,underlineY,nameColor,underlineBg)}}if(this._showDescription&&contentHeight>=(this._showUnderline?3:2)){let selectedOption=this.getSelectedOption();if(selectedOption){let descriptionY=contentY+(this._showUnderline?2:1),descColor=this._selectedDescriptionColor,descContent=this.truncateText(selectedOption.description,contentWidth-2);this.frameBuffer.drawText(descContent,contentX+1,descriptionY,descColor)}}if(this._showScrollArrows&&this._options.length>this.maxVisibleTabs)this.renderScrollArrowsToFrameBuffer(contentX,contentY,contentWidth,contentHeight)}truncateText(text,maxWidth){if(text.length<=maxWidth)return text;return text.substring(0,Math.max(0,maxWidth-1))+"\u2026"}renderScrollArrowsToFrameBuffer(contentX,contentY,contentWidth,contentHeight){if(!this.frameBuffer)return;let hasMoreLeft=this.scrollOffset>0,hasMoreRight=this.scrollOffset+this.maxVisibleTabs<this._options.length;if(hasMoreLeft)this.frameBuffer.drawText("\u2039",contentX,contentY,parseColor("#AAAAAA"));if(hasMoreRight)this.frameBuffer.drawText("\u203A",contentX+contentWidth-1,contentY,parseColor("#AAAAAA"))}setOptions(options){this._options=options,this.selectedIndex=Math.min(this.selectedIndex,Math.max(0,options.length-1)),this.updateScrollOffset(),this.requestRender()}getSelectedOption(){return this._options[this.selectedIndex]||null}getSelectedIndex(){return this.selectedIndex}moveLeft(){if(this.selectedIndex>0)this.selectedIndex--;else if(this._wrapSelection&&this._options.length>0)this.selectedIndex=this._options.length-1;else return;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this.selectedIndex,this.getSelectedOption())}moveRight(){if(this.selectedIndex<this._options.length-1)this.selectedIndex++;else if(this._wrapSelection&&this._options.length>0)this.selectedIndex=0;else return;this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this.selectedIndex,this.getSelectedOption())}selectCurrent(){let selected=this.getSelectedOption();if(selected)this.emit("itemSelected",this.selectedIndex,selected)}setSelectedIndex(index){if(index>=0&&index<this._options.length)this.selectedIndex=index,this.updateScrollOffset(),this.requestRender(),this.emit("selectionChanged",this.selectedIndex,this.getSelectedOption())}updateScrollOffset(){let halfVisible=Math.floor(this.maxVisibleTabs/2),newScrollOffset=Math.max(0,Math.min(this.selectedIndex-halfVisible,this._options.length-this.maxVisibleTabs));if(newScrollOffset!==this.scrollOffset)this.scrollOffset=newScrollOffset,this.requestRender()}onResize(width,height){this.maxVisibleTabs=Math.max(1,Math.floor(width/this._tabWidth)),this.updateScrollOffset(),this.requestRender()}setTabWidth(tabWidth){if(this._tabWidth===tabWidth)return;this._tabWidth=tabWidth,this.maxVisibleTabs=Math.max(1,Math.floor(this.width/this._tabWidth)),this.updateScrollOffset(),this.requestRender()}getTabWidth(){return this._tabWidth}handleKeyPress(key){let action=getKeyBindingAction(this._keyBindingsMap,key);if(action)switch(action){case"move-left":return this.moveLeft(),!0;case"move-right":return this.moveRight(),!0;case"select-current":return this.selectCurrent(),!0}return!1}get options(){return this._options}set options(options){this._options=options,this.selectedIndex=Math.min(this.selectedIndex,Math.max(0,options.length-1)),this.updateScrollOffset(),this.requestRender()}set backgroundColor(color){this._backgroundColor=parseColor(color),this.requestRender()}set textColor(color){this._textColor=parseColor(color),this.requestRender()}set focusedBackgroundColor(color){this._focusedBackgroundColor=parseColor(color),this.requestRender()}set focusedTextColor(color){this._focusedTextColor=parseColor(color),this.requestRender()}set selectedBackgroundColor(color){this._selectedBackgroundColor=parseColor(color),this.requestRender()}set selectedTextColor(color){this._selectedTextColor=parseColor(color),this.requestRender()}set selectedDescriptionColor(color){this._selectedDescriptionColor=parseColor(color),this.requestRender()}get showDescription(){return this._showDescription}set showDescription(show){if(this._showDescription!==show){this._showDescription=show;let newHeight=this.calculateDynamicHeight();this.height=newHeight,this.requestRender()}}get showUnderline(){return this._showUnderline}set showUnderline(show){if(this._showUnderline!==show){this._showUnderline=show;let newHeight=this.calculateDynamicHeight();this.height=newHeight,this.requestRender()}}get showScrollArrows(){return this._showScrollArrows}set showScrollArrows(show){if(this._showScrollArrows!==show)this._showScrollArrows=show,this.requestRender()}get wrapSelection(){return this._wrapSelection}set wrapSelection(wrap){this._wrapSelection=wrap}get tabWidth(){return this._tabWidth}set tabWidth(tabWidth){if(this._tabWidth===tabWidth)return;this._tabWidth=tabWidth,this.maxVisibleTabs=Math.max(1,Math.floor(this.width/this._tabWidth)),this.updateScrollOffset(),this.requestRender()}set keyBindings(bindings){this._keyBindings=bindings;let mergedBindings=mergeKeyBindings(defaultTabSelectKeybindings,bindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}set keyAliasMap(aliases){this._keyAliasMap=mergeKeyAliases(defaultKeyAliases,aliases);let mergedBindings=mergeKeyBindings(defaultTabSelectKeybindings,this._keyBindings);this._keyBindingsMap=buildKeyBindingsMap(mergedBindings,this._keyAliasMap)}}class TimeToFirstDrawRenderable extends Renderable{_runtimeMs=null;textColor;label;precision;constructor(ctx,options={}){super(ctx,{width:"100%",height:1,flexShrink:0,alignSelf:"center",...options});this.textColor=parseColor(options.fg??"#AAAAAA"),this.label=options.label??"Time to first draw",this.precision=this.normalizePrecision(options.precision??2)}get runtimeMs(){return this._runtimeMs}set fg(value){this.textColor=parseColor(value),this.requestRender()}set color(value){this.fg=value}set textLabel(value){if(value===this.label)return;this.label=value,this.requestRender()}set decimals(value){let nextPrecision=this.normalizePrecision(value);if(nextPrecision===this.precision)return;this.precision=nextPrecision,this.requestRender()}reset(){this._runtimeMs=null,this.requestRender()}renderSelf(buffer){if(this._runtimeMs===null)this._runtimeMs=performance.now();let content=`${this.label}: ${this._runtimeMs.toFixed(this.precision)}ms`,maxWidth=Math.max(this.width,1),visibleContent=content.length>maxWidth?content.slice(0,maxWidth):content,centeredX=this.x+Math.max(0,Math.floor((maxWidth-visibleContent.length)/2));buffer.drawText(visibleContent,centeredX,this.y,this.textColor)}normalizePrecision(value){if(!Number.isFinite(value))return 2;return Math.max(0,Math.floor(value))}}var import_react=__toESM(require_react_production(),1);var import_react2=__toESM(require_react_production(),1),import_react3=__toESM(require_react_production(),1);var REACT_ELEMENT_TYPE=Symbol.for("react.transitional.element"),REACT_FRAGMENT_TYPE=Symbol.for("react.fragment");function jsxProd(type,config,maybeKey){var key=null;if(maybeKey!==void 0&&(key=""+maybeKey),config.key!==void 0&&(key=""+config.key),"key"in config){maybeKey={};for(var propName in config)propName!=="key"&&(maybeKey[propName]=config[propName])}else maybeKey=config;return config=maybeKey.ref,{$$typeof:REACT_ELEMENT_TYPE,type,key,ref:config!==void 0?config:null,props:maybeKey}}var $Fragment=REACT_FRAGMENT_TYPE,$jsx=jsxProd,$jsxs=jsxProd;var jsxDEV=$jsx;var import_react_reconciler=__toESM(require_react_reconciler_production(),1);var $ConcurrentRoot=1;var $DefaultEventPriority=32;var $NoEventPriority=0;var import_react4=__toESM(require_react_production(),1);var textNodeKeys=["span","b","strong","i","em","u","br","a"];class SpanRenderable extends TextNodeRenderable{ctx;constructor(ctx,options){super(options);this.ctx=ctx}}class TextModifierRenderable extends SpanRenderable{constructor(options,modifier){super(null,options);if(modifier==="b"||modifier==="strong")this.attributes=(this.attributes||0)|TextAttributes.BOLD;else if(modifier==="i"||modifier==="em")this.attributes=(this.attributes||0)|TextAttributes.ITALIC;else if(modifier==="u")this.attributes=(this.attributes||0)|TextAttributes.UNDERLINE}}class BoldSpanRenderable extends TextModifierRenderable{constructor(_ctx,options){super(options,"b")}}class ItalicSpanRenderable extends TextModifierRenderable{constructor(_ctx,options){super(options,"i")}}class UnderlineSpanRenderable extends TextModifierRenderable{constructor(_ctx,options){super(options,"u")}}class LineBreakRenderable extends SpanRenderable{constructor(_ctx,options){super(null,options);this.add()}add(){return super.add(`
3645
- `)}}class LinkRenderable extends SpanRenderable{constructor(_ctx,options){let linkOptions={...options,link:{url:options.href}};super(null,linkOptions)}}var baseComponents={box:BoxRenderable,text:TextRenderable,code:CodeRenderable,diff:DiffRenderable,markdown:MarkdownRenderable,input:InputRenderable,select:SelectRenderable,textarea:TextareaRenderable,scrollbox:ScrollBoxRenderable,"ascii-font":ASCIIFontRenderable,"tab-select":TabSelectRenderable,"line-number":LineNumberRenderable,span:SpanRenderable,br:LineBreakRenderable,b:BoldSpanRenderable,strong:BoldSpanRenderable,i:ItalicSpanRenderable,em:ItalicSpanRenderable,u:UnderlineSpanRenderable,a:LinkRenderable},componentCatalogue={...baseComponents};function extend(objects){Object.assign(componentCatalogue,objects)}function getComponentCatalogue(){return componentCatalogue}var AppContext=import_react.createContext({keyHandler:null,renderer:null}),useAppContext=()=>{return import_react.useContext(AppContext)};class ErrorBoundary extends import_react3.default.Component{constructor(props){super(props);this.state={hasError:!1,error:null}}static getDerivedStateFromError(error){return{hasError:!0,error}}render(){if(this.state.hasError&&this.state.error)return jsxDEV("box",{style:{flexDirection:"column",padding:2},children:jsxDEV("text",{fg:"red",children:this.state.error.stack||this.state.error.message},void 0,!1,void 0,this)},void 0,!1,void 0,this);return this.props.children}}var package_default={name:"@opentui/react",version:"0.4.3",description:"React renderer for building terminal user interfaces using OpenTUI core",license:"MIT",repository:{type:"git",url:"https://github.com/anomalyco/opentui",directory:"packages/react"},module:"src/index.ts",type:"module",private:!0,main:"src/index.ts",exports:{".":{import:"./src/index.ts",types:"./src/index.ts"},"./test-utils":{import:"./src/test-utils.ts",types:"./src/test-utils.d.ts"},"./runtime-plugin-support":{import:"./scripts/runtime-plugin-support.ts",types:"./scripts/runtime-plugin-support.ts"},"./runtime-plugin-support/configure":{import:"./scripts/runtime-plugin-support-configure.ts",types:"./scripts/runtime-plugin-support-configure.ts"},"./jsx-runtime":{import:"./jsx-runtime.js",types:"./jsx-runtime.d.ts"},"./jsx-dev-runtime":{import:"./jsx-dev-runtime.js",types:"./jsx-dev-runtime.d.ts"}},scripts:{build:"bun run scripts/build.ts","build:examples":"bun examples/build.ts","build:dev":"bun run scripts/build.ts --dev",publish:"bun run scripts/publish.ts",test:"bun test"},devDependencies:{"@opentui/keymap":"workspace:*","@types/bun":"latest","@types/node":"^24.0.0","@types/react":"^19.2.0","@types/react-reconciler":"^0.33.0","@types/ws":"^8.18.1",react:">=19.2.0","react-devtools-core":"^7.0.1",typescript:"^5",ws:"^8.18.0"},peerDependencies:{react:">=19.2.0","react-devtools-core":"^7.0.1",ws:"^8.18.0"},peerDependenciesMeta:{"react-devtools-core":{optional:!0},ws:{optional:!0}},dependencies:{"@opentui/core":"workspace:*","react-reconciler":"^0.33.0"}},idCounter=new Map;function getNextId(type){if(!idCounter.has(type))idCounter.set(type,0);let value=idCounter.get(type)+1;return idCounter.set(type,value),`${type}-${value}`}function initEventListeners(instance,eventName,listener,previousListener){if(previousListener)instance.off(eventName,previousListener);if(listener)instance.on(eventName,listener)}function setStyle(instance,styles,oldStyles){if(oldStyles!=null&&typeof oldStyles==="object"){for(let styleName in oldStyles)if(oldStyles.hasOwnProperty(styleName)){if(styles==null||!styles.hasOwnProperty(styleName))instance[styleName]=null}}if(styles!=null&&typeof styles==="object"){for(let styleName in styles)if(styles.hasOwnProperty(styleName)){let value=styles[styleName],oldValue=oldStyles?.[styleName];if(value!==oldValue)instance[styleName]=value}}}function setProperty(instance,type,propKey,propValue,oldPropValue){switch(propKey){case"onChange":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.CHANGE,propValue,oldPropValue);else if(instance instanceof SelectRenderable)initEventListeners(instance,SelectRenderableEvents.SELECTION_CHANGED,propValue,oldPropValue);else if(instance instanceof TabSelectRenderable)initEventListeners(instance,TabSelectRenderableEvents.SELECTION_CHANGED,propValue,oldPropValue);break;case"onInput":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.INPUT,propValue,oldPropValue);break;case"onSubmit":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.ENTER,propValue,oldPropValue);else if(instance instanceof TextareaRenderable)instance.onSubmit=propValue;break;case"onSelect":if(instance instanceof SelectRenderable)initEventListeners(instance,SelectRenderableEvents.ITEM_SELECTED,propValue,oldPropValue);else if(instance instanceof TabSelectRenderable)initEventListeners(instance,TabSelectRenderableEvents.ITEM_SELECTED,propValue,oldPropValue);break;case"focused":if(isRenderable(instance))if(propValue)instance.focus();else instance.blur();break;case"style":setStyle(instance,propValue,oldPropValue);break;case"children":break;default:instance[propKey]=propValue}}function setInitialProperties(instance,type,props){for(let propKey in props){if(!props.hasOwnProperty(propKey))continue;let propValue=props[propKey];if(propValue==null)continue;setProperty(instance,type,propKey,propValue)}}function updateProperties(instance,type,oldProps,newProps){for(let propKey in oldProps){let oldProp=oldProps[propKey];if(oldProps.hasOwnProperty(propKey)&&oldProp!=null&&!newProps.hasOwnProperty(propKey))setProperty(instance,type,propKey,null,oldProp)}for(let propKey in newProps){let newProp=newProps[propKey],oldProp=oldProps[propKey];if(newProps.hasOwnProperty(propKey)&&newProp!==oldProp&&(newProp!=null||oldProp!=null))setProperty(instance,type,propKey,newProp,oldProp)}}var currentUpdatePriority=$NoEventPriority,hostConfig={supportsMutation:!0,supportsPersistence:!1,supportsHydration:!1,supportsMicrotasks:!0,scheduleMicrotask:queueMicrotask,createInstance(type,props,rootContainerInstance,hostContext){if(textNodeKeys.includes(type)&&!hostContext.isInsideText)throw Error(`Component of type "${type}" must be created inside of a text node`);let id=getNextId(type),components=getComponentCatalogue();if(!components[type])throw Error(`Unknown component type: ${type}`);return new components[type](rootContainerInstance.ctx,{id,...props})},appendChild(parent,child){parent.add(child)},removeChild(parent,child){if(!child.parent)return;parent.remove(child)},insertBefore(parent,child,beforeChild){parent.insertBefore(child,beforeChild)},insertInContainerBefore(parent,child,beforeChild){parent.insertBefore(child,beforeChild)},removeChildFromContainer(parent,child){if(!child.parent)return;parent.remove(child)},prepareForCommit(containerInfo){return null},resetAfterCommit(containerInfo){containerInfo.requestRender()},getRootHostContext(rootContainerInstance){return{isInsideText:!1}},getChildHostContext(parentHostContext,type,rootContainerInstance){let isInsideText=["text",...textNodeKeys].includes(type);return{...parentHostContext,isInsideText}},shouldSetTextContent(type,props){return!1},createTextInstance(text,rootContainerInstance,hostContext){if(!hostContext.isInsideText)throw Error("Text must be created inside of a text node");return TextNodeRenderable.fromString(text)},scheduleTimeout:setTimeout,cancelTimeout:clearTimeout,noTimeout:-1,shouldAttemptEagerTransition(){return!0},finalizeInitialChildren(instance,type,props,rootContainerInstance,hostContext){return setInitialProperties(instance,type,props),!1},commitMount(instance,type,props,internalInstanceHandle){},commitUpdate(instance,type,oldProps,newProps,internalInstanceHandle){updateProperties(instance,type,oldProps,newProps)},commitTextUpdate(textInstance,oldText,newText){textInstance.children=[newText]},appendChildToContainer(container,child){container.add(child)},appendInitialChild(parent,child){parent.add(child)},hideInstance(instance){instance.visible=!1},unhideInstance(instance,props){instance.visible=!0},hideTextInstance(textInstance){textInstance.visible=!1},unhideTextInstance(textInstance,text){textInstance.visible=!0},clearContainer(container){container.getChildren().forEach((child)=>container.remove(child))},setCurrentUpdatePriority(newPriority){currentUpdatePriority=newPriority},getCurrentUpdatePriority:()=>currentUpdatePriority,resolveUpdatePriority(){if(currentUpdatePriority!==$NoEventPriority)return currentUpdatePriority;return $DefaultEventPriority},maySuspendCommit(){return!1},maySuspendCommitOnUpdate(){return!1},maySuspendCommitInSyncRender(){return!1},NotPendingTransition:null,HostTransitionContext:import_react4.createContext(null),resetFormInstance(){},requestPostPaintCallback(){},trackSchedulerEvent(){},resolveEventType(){return null},resolveEventTimeStamp(){return-1.1},preloadInstance(){return!0},startSuspendingCommit(){},suspendInstance(){},waitForCommitToBeReady(){return null},detachDeletedInstance(instance){if(!instance.parent)instance.destroyRecursively()},getPublicInstance(instance){return instance},preparePortalMount(containerInfo){},isPrimaryRenderer:!0,getInstanceFromNode(){return null},beforeActiveInstanceBlur(){},afterActiveInstanceBlur(){},prepareScopeUpdate(){},getInstanceFromScope(){return null},rendererPackageName:"@opentui/react",rendererVersion:package_default.version},reconciler=import_react_reconciler.default(hostConfig);reconciler.injectIntoDevTools();function _render(element,root){let container=reconciler.createContainer(root,$ConcurrentRoot,null,!1,null,"",console.error,console.error,console.error,()=>{});return reconciler.updateContainer(element,container,null,()=>{}),container}var _r=reconciler,flushSync=_r.flushSyncFromReconciler??_r.flushSync;function createRoot(renderer){let container=null,cleanup=()=>{if(container)reconciler.updateContainer(null,container,null,()=>{}),reconciler.flushSyncWork(),container=null};return renderer.once(CliRenderEvents.DESTROY,cleanup),{render:(node)=>{engine.attach(renderer),container=_render(import_react2.default.createElement(AppContext.Provider,{value:{keyHandler:renderer.keyInput,renderer}},import_react2.default.createElement(ErrorBoundary,null,node)),renderer.root)},unmount:cleanup}}var import_react5=__toESM(require_react_production(),1),import_react6=__toESM(require_react_production(),1),import_react7=__toESM(require_react_production(),1),import_react8=__toESM(require_react_production(),1),import_react9=__toESM(require_react_production(),1),import_react10=__toESM(require_react_production(),1),import_react11=__toESM(require_react_production(),1),import_react12=__toESM(require_react_production(),1);var import_react13=__toESM(require_react_production(),1);var import_react14=__toESM(require_react_production(),1);var import_react15=__toESM(require_react_production(),1),import_react16=__toESM(require_react_production(),1);function useEffectEvent(handler){let handlerRef=import_react6.useRef(handler);return import_react6.useLayoutEffect(()=>{handlerRef.current=handler}),import_react6.useCallback((...args)=>{let fn=handlerRef.current;return fn(...args)},[])}var useRenderer=()=>{let{renderer}=useAppContext();if(!renderer)throw Error("Renderer not found.");return renderer};var useKeyboard=(handler,options={release:!1})=>{let{keyHandler}=useAppContext(),stableHandler=useEffectEvent(handler);import_react8.useEffect(()=>{if(keyHandler?.on("keypress",stableHandler),options?.release)keyHandler?.on("keyrelease",stableHandler);return()=>{if(keyHandler?.off("keypress",stableHandler),options?.release)keyHandler?.off("keyrelease",stableHandler)}},[keyHandler,options.release])};var useOnResize=(callback)=>{let renderer=useRenderer(),stableCallback=useEffectEvent(callback);return import_react10.useEffect(()=>{return renderer.on("resize",stableCallback),()=>{renderer.off("resize",stableCallback)}},[renderer]),renderer};var useTerminalDimensions=()=>{let renderer=useRenderer(),[dimensions,setDimensions]=import_react12.useState({width:renderer.width,height:renderer.height});return useOnResize((width,height)=>{setDimensions({width,height})}),dimensions};function createReactSlotRegistry(renderer,context,options={}){return createSlotRegistry(renderer,"react:slot-registry",context,options)}function renderPluginFailurePlaceholder(registry,pluginFailurePlaceholder,failure,pluginId,slot){if(!pluginFailurePlaceholder)return null;try{return pluginFailurePlaceholder(failure)}catch(error){return registry.reportPluginError({pluginId,slot,phase:"error_placeholder",source:"react",error}),null}}class PluginErrorBoundary extends import_react14.default.Component{constructor(props){super(props);this.state={failure:null}}componentDidCatch(error){let failure=this.props.registry.reportPluginError({pluginId:this.props.pluginId,slot:this.props.slotName,phase:"render",source:"react",error});this.setState({failure})}componentDidUpdate(previousProps){if(previousProps.resetToken!==this.props.resetToken&&this.state.failure)this.setState({failure:null})}render(){if(this.state.failure){let placeholder=renderPluginFailurePlaceholder(this.props.registry,this.props.pluginFailurePlaceholder,this.state.failure,this.props.pluginId,this.props.slotName);if(placeholder===null||placeholder===void 0||placeholder===!1)return this.props.fallbackOnFailure??null;return placeholder}return this.props.children}}function getSlotProps(props){let{children:_children,mode:_mode,name:_name,registry:_registry,pluginFailurePlaceholder:_pluginFailurePlaceholder,...slotProps}=props;return slotProps}function createSlot(registry,options={}){return function(props){return jsxDEV(Slot,{...props,registry,pluginFailurePlaceholder:options.pluginFailurePlaceholder},void 0,!1,void 0,this)}}function Slot(props){let[version,setVersion]=import_react14.useState(0),registry=props.registry,slotName=String(props.name),renderFailuresByPluginRef=import_react14.useRef(new Map),pendingRenderReportsRef=import_react14.useRef(new Map);import_react14.useEffect(()=>{return registry.subscribe(()=>{setVersion((current)=>current+1)})},[registry]),import_react14.useEffect(()=>{if(pendingRenderReportsRef.current.size===0)return;let pendingReports=[...pendingRenderReportsRef.current.values()];pendingRenderReportsRef.current.clear();for(let report of pendingReports){let failure=registry.reportPluginError({pluginId:report.pluginId,slot:report.slot,phase:"render",source:"react",error:report.error});renderFailuresByPluginRef.current.set(`${report.slot}:${report.pluginId}:render`,failure)}});let entries=import_react14.useMemo(()=>registry.resolveEntries(props.name),[registry,props.name,version]),slotProps=getSlotProps(props),renderEntry=(entry,fallbackOnFailure)=>{let key=`${slotName}:${entry.id}`,failureKey=`${slotName}:${entry.id}:render`;try{let rendered=entry.renderer(registry.context,slotProps);return renderFailuresByPluginRef.current.delete(failureKey),pendingRenderReportsRef.current.delete(failureKey),jsxDEV(PluginErrorBoundary,{registry,pluginFailurePlaceholder:props.pluginFailurePlaceholder,pluginId:entry.id,slotName,resetToken:version,fallbackOnFailure,children:rendered},key,!1,void 0,this)}catch(error){let normalizedError=error instanceof Error?error:typeof error==="string"?Error(error):Error(String(error)),lastFailure=renderFailuresByPluginRef.current.get(failureKey),isSameFailure=lastFailure&&lastFailure.error.message===normalizedError.message;if(!isSameFailure){let queued=pendingRenderReportsRef.current.get(failureKey);if(!queued||queued.error.message!==normalizedError.message)pendingRenderReportsRef.current.set(failureKey,{pluginId:entry.id,slot:slotName,error:normalizedError})}let failure=isSameFailure&&lastFailure?lastFailure:{pluginId:entry.id,slot:slotName,phase:"render",source:"react",error:normalizedError,timestamp:Date.now()};renderFailuresByPluginRef.current.set(failureKey,failure);let placeholder=renderPluginFailurePlaceholder(registry,props.pluginFailurePlaceholder,failure,entry.id,slotName);if(placeholder===null||placeholder===void 0||placeholder===!1)return fallbackOnFailure??null;return jsxDEV(import_react14.Fragment,{children:placeholder},key,!1,void 0,this)}};if(entries.length===0)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);if(props.mode==="single_winner"){let winner=entries[0];if(!winner)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);let rendered=renderEntry(winner,props.children);if(rendered===null||rendered===void 0||rendered===!1)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:rendered},void 0,!1,void 0,this)}if(props.mode==="replace"){if(entries.length===1){let rendered=renderEntry(entries[0],props.children);if(rendered===null||rendered===void 0||rendered===!1)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:rendered},void 0,!1,void 0,this)}let renderedEntries=entries.map((entry)=>renderEntry(entry));if(!renderedEntries.some((node)=>node!==null&&node!==void 0&&node!==!1))return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:renderedEntries},void 0,!1,void 0,this)}return jsxDEV($Fragment,{children:[props.children,entries.map((entry)=>renderEntry(entry))]},void 0,!0,void 0,this)}extend({"time-to-first-draw":TimeToFirstDrawRenderable});init_perf();var import_react163=__toESM(require_react_production(),1);var INTERP_RE=/\{!(.+?)\}/g,hasInterp=(s)=>/\{!.+?\}/.test(s);async function interpolate(gw,text){let hits=[...text.matchAll(INTERP_RE)];if(hits.length===0)return text;let outs=await Promise.all(hits.map((m2)=>gw.request("shell.exec",{command:m2[1]}).then((r)=>[r.stdout,r.stderr].filter(Boolean).join(`
3645
+ `)}}class LinkRenderable extends SpanRenderable{constructor(_ctx,options){let linkOptions={...options,link:{url:options.href}};super(null,linkOptions)}}var baseComponents={box:BoxRenderable,text:TextRenderable,code:CodeRenderable,diff:DiffRenderable,markdown:MarkdownRenderable,input:InputRenderable,select:SelectRenderable,textarea:TextareaRenderable,scrollbox:ScrollBoxRenderable,"ascii-font":ASCIIFontRenderable,"tab-select":TabSelectRenderable,"line-number":LineNumberRenderable,span:SpanRenderable,br:LineBreakRenderable,b:BoldSpanRenderable,strong:BoldSpanRenderable,i:ItalicSpanRenderable,em:ItalicSpanRenderable,u:UnderlineSpanRenderable,a:LinkRenderable},componentCatalogue={...baseComponents};function extend(objects){Object.assign(componentCatalogue,objects)}function getComponentCatalogue(){return componentCatalogue}var AppContext=import_react.createContext({keyHandler:null,renderer:null}),useAppContext=()=>{return import_react.useContext(AppContext)};class ErrorBoundary extends import_react3.default.Component{constructor(props){super(props);this.state={hasError:!1,error:null}}static getDerivedStateFromError(error){return{hasError:!0,error}}render(){if(this.state.hasError&&this.state.error)return jsxDEV("box",{style:{flexDirection:"column",padding:2},children:jsxDEV("text",{fg:"red",children:this.state.error.stack||this.state.error.message},void 0,!1,void 0,this)},void 0,!1,void 0,this);return this.props.children}}var package_default={name:"@opentui/react",version:"0.4.3",description:"React renderer for building terminal user interfaces using OpenTUI core",license:"MIT",repository:{type:"git",url:"https://github.com/anomalyco/opentui",directory:"packages/react"},module:"src/index.ts",type:"module",private:!0,main:"src/index.ts",exports:{".":{import:"./src/index.ts",types:"./src/index.ts"},"./test-utils":{import:"./src/test-utils.ts",types:"./src/test-utils.d.ts"},"./runtime-plugin-support":{import:"./scripts/runtime-plugin-support.ts",types:"./scripts/runtime-plugin-support.ts"},"./runtime-plugin-support/configure":{import:"./scripts/runtime-plugin-support-configure.ts",types:"./scripts/runtime-plugin-support-configure.ts"},"./jsx-runtime":{import:"./jsx-runtime.js",types:"./jsx-runtime.d.ts"},"./jsx-dev-runtime":{import:"./jsx-dev-runtime.js",types:"./jsx-dev-runtime.d.ts"}},scripts:{build:"bun run scripts/build.ts","build:examples":"bun examples/build.ts","build:dev":"bun run scripts/build.ts --dev",publish:"bun run scripts/publish.ts",test:"bun test"},devDependencies:{"@opentui/keymap":"workspace:*","@types/bun":"latest","@types/node":"^24.0.0","@types/react":"^19.2.0","@types/react-reconciler":"^0.33.0","@types/ws":"^8.18.1",react:">=19.2.0","react-devtools-core":"^7.0.1",typescript:"^5",ws:"^8.18.0"},peerDependencies:{react:">=19.2.0","react-devtools-core":"^7.0.1",ws:"^8.18.0"},peerDependenciesMeta:{"react-devtools-core":{optional:!0},ws:{optional:!0}},dependencies:{"@opentui/core":"workspace:*","react-reconciler":"^0.33.0"}},idCounter=new Map;function getNextId(type){if(!idCounter.has(type))idCounter.set(type,0);let value=idCounter.get(type)+1;return idCounter.set(type,value),`${type}-${value}`}function initEventListeners(instance,eventName,listener,previousListener){if(previousListener)instance.off(eventName,previousListener);if(listener)instance.on(eventName,listener)}function setStyle(instance,styles,oldStyles){if(oldStyles!=null&&typeof oldStyles==="object"){for(let styleName in oldStyles)if(oldStyles.hasOwnProperty(styleName)){if(styles==null||!styles.hasOwnProperty(styleName))instance[styleName]=null}}if(styles!=null&&typeof styles==="object"){for(let styleName in styles)if(styles.hasOwnProperty(styleName)){let value=styles[styleName],oldValue=oldStyles?.[styleName];if(value!==oldValue)instance[styleName]=value}}}function setProperty(instance,type,propKey,propValue,oldPropValue){switch(propKey){case"onChange":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.CHANGE,propValue,oldPropValue);else if(instance instanceof SelectRenderable)initEventListeners(instance,SelectRenderableEvents.SELECTION_CHANGED,propValue,oldPropValue);else if(instance instanceof TabSelectRenderable)initEventListeners(instance,TabSelectRenderableEvents.SELECTION_CHANGED,propValue,oldPropValue);break;case"onInput":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.INPUT,propValue,oldPropValue);break;case"onSubmit":if(instance instanceof InputRenderable)initEventListeners(instance,InputRenderableEvents.ENTER,propValue,oldPropValue);else if(instance instanceof TextareaRenderable)instance.onSubmit=propValue;break;case"onSelect":if(instance instanceof SelectRenderable)initEventListeners(instance,SelectRenderableEvents.ITEM_SELECTED,propValue,oldPropValue);else if(instance instanceof TabSelectRenderable)initEventListeners(instance,TabSelectRenderableEvents.ITEM_SELECTED,propValue,oldPropValue);break;case"focused":if(isRenderable(instance))if(propValue)instance.focus();else instance.blur();break;case"style":setStyle(instance,propValue,oldPropValue);break;case"children":break;default:instance[propKey]=propValue}}function setInitialProperties(instance,type,props){for(let propKey in props){if(!props.hasOwnProperty(propKey))continue;let propValue=props[propKey];if(propValue==null)continue;setProperty(instance,type,propKey,propValue)}}function updateProperties(instance,type,oldProps,newProps){for(let propKey in oldProps){let oldProp=oldProps[propKey];if(oldProps.hasOwnProperty(propKey)&&oldProp!=null&&!newProps.hasOwnProperty(propKey))setProperty(instance,type,propKey,null,oldProp)}for(let propKey in newProps){let newProp=newProps[propKey],oldProp=oldProps[propKey];if(newProps.hasOwnProperty(propKey)&&newProp!==oldProp&&(newProp!=null||oldProp!=null))setProperty(instance,type,propKey,newProp,oldProp)}}var currentUpdatePriority=$NoEventPriority,hostConfig={supportsMutation:!0,supportsPersistence:!1,supportsHydration:!1,supportsMicrotasks:!0,scheduleMicrotask:queueMicrotask,createInstance(type,props,rootContainerInstance,hostContext){if(textNodeKeys.includes(type)&&!hostContext.isInsideText)throw Error(`Component of type "${type}" must be created inside of a text node`);let id=getNextId(type),components=getComponentCatalogue();if(!components[type])throw Error(`Unknown component type: ${type}`);return new components[type](rootContainerInstance.ctx,{id,...props})},appendChild(parent,child){parent.add(child)},removeChild(parent,child){if(!child.parent)return;parent.remove(child)},insertBefore(parent,child,beforeChild){parent.insertBefore(child,beforeChild)},insertInContainerBefore(parent,child,beforeChild){parent.insertBefore(child,beforeChild)},removeChildFromContainer(parent,child){if(!child.parent)return;parent.remove(child)},prepareForCommit(containerInfo){return null},resetAfterCommit(containerInfo){containerInfo.requestRender()},getRootHostContext(rootContainerInstance){return{isInsideText:!1}},getChildHostContext(parentHostContext,type,rootContainerInstance){let isInsideText=["text",...textNodeKeys].includes(type);return{...parentHostContext,isInsideText}},shouldSetTextContent(type,props){return!1},createTextInstance(text,rootContainerInstance,hostContext){if(!hostContext.isInsideText)throw Error("Text must be created inside of a text node");return TextNodeRenderable.fromString(text)},scheduleTimeout:setTimeout,cancelTimeout:clearTimeout,noTimeout:-1,shouldAttemptEagerTransition(){return!0},finalizeInitialChildren(instance,type,props,rootContainerInstance,hostContext){return setInitialProperties(instance,type,props),!1},commitMount(instance,type,props,internalInstanceHandle){},commitUpdate(instance,type,oldProps,newProps,internalInstanceHandle){updateProperties(instance,type,oldProps,newProps)},commitTextUpdate(textInstance,oldText,newText){textInstance.children=[newText]},appendChildToContainer(container,child){container.add(child)},appendInitialChild(parent,child){parent.add(child)},hideInstance(instance){instance.visible=!1},unhideInstance(instance,props){instance.visible=!0},hideTextInstance(textInstance){textInstance.visible=!1},unhideTextInstance(textInstance,text){textInstance.visible=!0},clearContainer(container){container.getChildren().forEach((child)=>container.remove(child))},setCurrentUpdatePriority(newPriority){currentUpdatePriority=newPriority},getCurrentUpdatePriority:()=>currentUpdatePriority,resolveUpdatePriority(){if(currentUpdatePriority!==$NoEventPriority)return currentUpdatePriority;return $DefaultEventPriority},maySuspendCommit(){return!1},maySuspendCommitOnUpdate(){return!1},maySuspendCommitInSyncRender(){return!1},NotPendingTransition:null,HostTransitionContext:import_react4.createContext(null),resetFormInstance(){},requestPostPaintCallback(){},trackSchedulerEvent(){},resolveEventType(){return null},resolveEventTimeStamp(){return-1.1},preloadInstance(){return!0},startSuspendingCommit(){},suspendInstance(){},waitForCommitToBeReady(){return null},detachDeletedInstance(instance){if(!instance.parent)instance.destroyRecursively()},getPublicInstance(instance){return instance},preparePortalMount(containerInfo){},isPrimaryRenderer:!0,getInstanceFromNode(){return null},beforeActiveInstanceBlur(){},afterActiveInstanceBlur(){},prepareScopeUpdate(){},getInstanceFromScope(){return null},rendererPackageName:"@opentui/react",rendererVersion:package_default.version},reconciler=import_react_reconciler.default(hostConfig);reconciler.injectIntoDevTools();function _render(element,root){let container=reconciler.createContainer(root,$ConcurrentRoot,null,!1,null,"",console.error,console.error,console.error,()=>{});return reconciler.updateContainer(element,container,null,()=>{}),container}var _r=reconciler,flushSync=_r.flushSyncFromReconciler??_r.flushSync;function createRoot(renderer){let container=null,cleanup=()=>{if(container)reconciler.updateContainer(null,container,null,()=>{}),reconciler.flushSyncWork(),container=null};return renderer.once(CliRenderEvents.DESTROY,cleanup),{render:(node)=>{engine.attach(renderer),container=_render(import_react2.default.createElement(AppContext.Provider,{value:{keyHandler:renderer.keyInput,renderer}},import_react2.default.createElement(ErrorBoundary,null,node)),renderer.root)},unmount:cleanup}}var import_react5=__toESM(require_react_production(),1),import_react6=__toESM(require_react_production(),1),import_react7=__toESM(require_react_production(),1),import_react8=__toESM(require_react_production(),1),import_react9=__toESM(require_react_production(),1),import_react10=__toESM(require_react_production(),1),import_react11=__toESM(require_react_production(),1),import_react12=__toESM(require_react_production(),1);var import_react13=__toESM(require_react_production(),1);var import_react14=__toESM(require_react_production(),1);var import_react15=__toESM(require_react_production(),1),import_react16=__toESM(require_react_production(),1);function useEffectEvent(handler){let handlerRef=import_react6.useRef(handler);return import_react6.useLayoutEffect(()=>{handlerRef.current=handler}),import_react6.useCallback((...args)=>{let fn=handlerRef.current;return fn(...args)},[])}var useRenderer=()=>{let{renderer}=useAppContext();if(!renderer)throw Error("Renderer not found.");return renderer};var useKeyboard=(handler,options={release:!1})=>{let{keyHandler}=useAppContext(),stableHandler=useEffectEvent(handler);import_react8.useEffect(()=>{if(keyHandler?.on("keypress",stableHandler),options?.release)keyHandler?.on("keyrelease",stableHandler);return()=>{if(keyHandler?.off("keypress",stableHandler),options?.release)keyHandler?.off("keyrelease",stableHandler)}},[keyHandler,options.release])};var useOnResize=(callback)=>{let renderer=useRenderer(),stableCallback=useEffectEvent(callback);return import_react10.useEffect(()=>{return renderer.on("resize",stableCallback),()=>{renderer.off("resize",stableCallback)}},[renderer]),renderer};var useTerminalDimensions=()=>{let renderer=useRenderer(),[dimensions,setDimensions]=import_react12.useState({width:renderer.width,height:renderer.height});return useOnResize((width,height)=>{setDimensions({width,height})}),dimensions};function createReactSlotRegistry(renderer,context,options={}){return createSlotRegistry(renderer,"react:slot-registry",context,options)}function renderPluginFailurePlaceholder(registry,pluginFailurePlaceholder,failure,pluginId,slot){if(!pluginFailurePlaceholder)return null;try{return pluginFailurePlaceholder(failure)}catch(error){return registry.reportPluginError({pluginId,slot,phase:"error_placeholder",source:"react",error}),null}}class PluginErrorBoundary extends import_react14.default.Component{constructor(props){super(props);this.state={failure:null}}componentDidCatch(error){let failure=this.props.registry.reportPluginError({pluginId:this.props.pluginId,slot:this.props.slotName,phase:"render",source:"react",error});this.setState({failure})}componentDidUpdate(previousProps){if(previousProps.resetToken!==this.props.resetToken&&this.state.failure)this.setState({failure:null})}render(){if(this.state.failure){let placeholder=renderPluginFailurePlaceholder(this.props.registry,this.props.pluginFailurePlaceholder,this.state.failure,this.props.pluginId,this.props.slotName);if(placeholder===null||placeholder===void 0||placeholder===!1)return this.props.fallbackOnFailure??null;return placeholder}return this.props.children}}function getSlotProps(props){let{children:_children,mode:_mode,name:_name,registry:_registry,pluginFailurePlaceholder:_pluginFailurePlaceholder,...slotProps}=props;return slotProps}function createSlot(registry,options={}){return function(props){return jsxDEV(Slot,{...props,registry,pluginFailurePlaceholder:options.pluginFailurePlaceholder},void 0,!1,void 0,this)}}function Slot(props){let[version,setVersion]=import_react14.useState(0),registry=props.registry,slotName=String(props.name),renderFailuresByPluginRef=import_react14.useRef(new Map),pendingRenderReportsRef=import_react14.useRef(new Map);import_react14.useEffect(()=>{return registry.subscribe(()=>{setVersion((current)=>current+1)})},[registry]),import_react14.useEffect(()=>{if(pendingRenderReportsRef.current.size===0)return;let pendingReports=[...pendingRenderReportsRef.current.values()];pendingRenderReportsRef.current.clear();for(let report of pendingReports){let failure=registry.reportPluginError({pluginId:report.pluginId,slot:report.slot,phase:"render",source:"react",error:report.error});renderFailuresByPluginRef.current.set(`${report.slot}:${report.pluginId}:render`,failure)}});let entries=import_react14.useMemo(()=>registry.resolveEntries(props.name),[registry,props.name,version]),slotProps=getSlotProps(props),renderEntry=(entry,fallbackOnFailure)=>{let key=`${slotName}:${entry.id}`,failureKey=`${slotName}:${entry.id}:render`;try{let rendered=entry.renderer(registry.context,slotProps);return renderFailuresByPluginRef.current.delete(failureKey),pendingRenderReportsRef.current.delete(failureKey),jsxDEV(PluginErrorBoundary,{registry,pluginFailurePlaceholder:props.pluginFailurePlaceholder,pluginId:entry.id,slotName,resetToken:version,fallbackOnFailure,children:rendered},key,!1,void 0,this)}catch(error){let normalizedError=error instanceof Error?error:typeof error==="string"?Error(error):Error(String(error)),lastFailure=renderFailuresByPluginRef.current.get(failureKey),isSameFailure=lastFailure&&lastFailure.error.message===normalizedError.message;if(!isSameFailure){let queued=pendingRenderReportsRef.current.get(failureKey);if(!queued||queued.error.message!==normalizedError.message)pendingRenderReportsRef.current.set(failureKey,{pluginId:entry.id,slot:slotName,error:normalizedError})}let failure=isSameFailure&&lastFailure?lastFailure:{pluginId:entry.id,slot:slotName,phase:"render",source:"react",error:normalizedError,timestamp:Date.now()};renderFailuresByPluginRef.current.set(failureKey,failure);let placeholder=renderPluginFailurePlaceholder(registry,props.pluginFailurePlaceholder,failure,entry.id,slotName);if(placeholder===null||placeholder===void 0||placeholder===!1)return fallbackOnFailure??null;return jsxDEV(import_react14.Fragment,{children:placeholder},key,!1,void 0,this)}};if(entries.length===0)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);if(props.mode==="single_winner"){let winner=entries[0];if(!winner)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);let rendered=renderEntry(winner,props.children);if(rendered===null||rendered===void 0||rendered===!1)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:rendered},void 0,!1,void 0,this)}if(props.mode==="replace"){if(entries.length===1){let rendered=renderEntry(entries[0],props.children);if(rendered===null||rendered===void 0||rendered===!1)return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:rendered},void 0,!1,void 0,this)}let renderedEntries=entries.map((entry)=>renderEntry(entry));if(!renderedEntries.some((node)=>node!==null&&node!==void 0&&node!==!1))return jsxDEV($Fragment,{children:props.children},void 0,!1,void 0,this);return jsxDEV($Fragment,{children:renderedEntries},void 0,!1,void 0,this)}return jsxDEV($Fragment,{children:[props.children,entries.map((entry)=>renderEntry(entry))]},void 0,!0,void 0,this)}extend({"time-to-first-draw":TimeToFirstDrawRenderable});init_perf();var import_react165=__toESM(require_react_production(),1);var INTERP_RE=/\{!(.+?)\}/g,hasInterp=(s)=>/\{!.+?\}/.test(s);async function interpolate(gw,text){let hits=[...text.matchAll(INTERP_RE)];if(hits.length===0)return text;let outs=await Promise.all(hits.map((m2)=>gw.request("shell.exec",{command:m2[1]}).then((r)=>[r.stdout,r.stderr].filter(Boolean).join(`
3646
3646
  `).trim()).catch(()=>"(error)"))),out=text;for(let i=hits.length-1;i>=0;i--){let m2=hits[i];out=out.slice(0,m2.index)+outs[i]+out.slice(m2.index+m2[0].length)}return out}var import_react17=__toESM(require_react_production(),1);import{EventEmitter as EventEmitter7}from"events";import{homedir}from"os";import{resolve as resolve3,delimiter}from"path";import{existsSync as existsSync4}from"fs";var BAD=/[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g;function scalar(s){let count2=0;return{text:s.replace(BAD,(m2)=>{if(m2.length===2)return m2;return count2+=1,"\uFFFD"}),count:count2}}function encode(v2){let paths=new WeakMap,issues=[];return{text:JSON.stringify(v2,function(key,value){let holder=this&&typeof this==="object"?paths.get(this):void 0,path4=key?`${holder??"$"}.${key}`:"$";if(value&&typeof value==="object")paths.set(value,path4);if(typeof value!=="string")return value;let next=scalar(value);if(next.count>0)issues.push({path:path4,count:next.count});return next.text})??"null",issues}}var LOG_MAX=200,LOG_PREVIEW=240,STARTUP_MS=15000,REQUEST_MS=120000,WS_CONNECTING=0,WS_OPEN=1,WS_CLOSING=2,WS_CLOSED=3,decoder2=new TextDecoder;function hermesAgentRoot(){if(process.env.HERMES_AGENT_ROOT)return process.env.HERMES_AGENT_ROOT;let homePath=`${process.env.HOME||homedir()}/.hermes/hermes-agent`;if(existsSync4(homePath))return homePath;let fhs="/usr/local/lib/hermes-agent";if(existsSync4(fhs))return fhs;return homePath}function gatewayUrl(){return process.env.HERM_GATEWAY_URL?.trim()||process.env.HERMES_TUI_GATEWAY_URL?.trim()||null}function websocketUrl(raw){let url=new URL(raw);if(url.protocol==="http:")url.protocol="ws:";else if(url.protocol==="https:")url.protocol="wss:";else if(url.protocol!=="ws:"&&url.protocol!=="wss:")throw Error(`unsupported gateway URL protocol: ${url.protocol}`);let prefix=url.pathname.replace(/\/+$/,"");if(!prefix.endsWith("/api/ws"))url.pathname=`${prefix}/api/ws`;return url.toString()}function redact(raw){try{let url=new URL(raw);if(url.username||url.password)url.username="***",url.password="";if(url.search)url.search="?***";return url.toString()}catch{return"invalid gateway URL"}}function python(root,platform=process.platform){let env2=process.env.HERMES_PYTHON?.trim();if(env2)return env2;let venv=process.env.VIRTUAL_ENV?.trim();return(platform==="win32"?[venv&&resolve3(venv,"Scripts","python.exe"),resolve3(root,"venv","Scripts","python.exe"),resolve3(root,".venv","Scripts","python.exe")]:[venv&&resolve3(venv,"bin","python"),venv&&resolve3(venv,"bin","python3"),resolve3(root,"venv","bin","python"),resolve3(root,"venv","bin","python3"),resolve3(root,".venv","bin","python"),resolve3(root,".venv","bin","python3")]).find((p)=>p&&existsSync4(p))||(platform==="win32"?"python":"python3")}function asEvent(v2){if(v2&&typeof v2==="object"&&!Array.isArray(v2)&&typeof v2.type==="string")return v2;return null}function text(raw){if(typeof raw==="string")return raw;if(raw instanceof ArrayBuffer)return decoder2.decode(raw);if(ArrayBuffer.isView(raw))return decoder2.decode(raw);return null}async function lines(stream,cb){let reader=stream.getReader(),decoder3=new TextDecoder,buf="";try{while(!0){let{done,value}=await reader.read();if(done)break;buf+=decoder3.decode(value,{stream:!0});let parts=buf.split(`
3647
3647
  `);buf=parts.pop()||"";for(let line of parts)if(line)cb(line)}if(buf.trim())cb(buf)}catch{}}class GatewayClient extends EventEmitter7{proc=null;ws=null;link=null;target=null;id=0;logs=[];pending=new Map;buf=[];exit;ok=!1;timer=null;sub=!1;root(){return hermesAgentRoot()}push(ev){if(ev.type==="gateway.ready"){if(this.ok=!0,this.timer)clearTimeout(this.timer),this.timer=null}if(this.sub)return void this.emit("event",ev);this.buf.push(ev)}log(line){if(this.logs.push(line)>LOG_MAX)this.logs.splice(0,this.logs.length-LOG_MAX)}dispatch(msg){let id=msg.id,p=id?this.pending.get(id):void 0;if(p){if(this.pending.delete(id),msg.error){let err=msg.error;p.reject(Error(typeof err?.message==="string"?err.message:"request failed"))}else p.resolve(msg.result);return}if(msg.method==="event"){let ev=asEvent(msg.params);if(ev)this.push(ev)}}fail(err){for(let p of this.pending.values())p.reject(err);this.pending.clear()}connect(raw){let cwd=process.env.HERMES_CWD||process.cwd(),url;try{url=websocketUrl(raw)}catch(err){let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] websocket failed: ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return}let safe=redact(url),ws;try{ws=new WebSocket(url)}catch(err){let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] websocket failed (${safe}): ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return}this.target=raw,this.ws=ws;let settled=!1;this.link=new Promise((resolve4,reject)=>{ws.addEventListener("open",()=>{if(settled)return;settled=!0,resolve4()},{once:!0}),ws.addEventListener("error",()=>{if(settled)return;settled=!0,reject(Error("gateway websocket connection failed"));try{ws.close()}catch{}},{once:!0}),ws.addEventListener("close",(event)=>{if(settled)return;settled=!0,reject(Error(`gateway websocket closed (${event.code}) during connect`))},{once:!0})}),this.link.catch(()=>{}),this.timer=setTimeout(()=>{if(this.ok||this.ws!==ws)return;this.log(`[startup] timed out (websocket=${safe}, cwd=${cwd})`),this.push({type:"gateway.start_timeout",payload:{cwd,python:"websocket"}}),this.ws=null,this.link=null,this.fail(Error("gateway websocket startup timeout"));try{ws.close()}catch{}if(this.sub)this.emit("exit",null);else this.exit=null},STARTUP_MS),ws.addEventListener("message",(event)=>{if(this.ws!==ws)return;let raw2=text(event.data);if(!raw2)return;try{this.dispatch(JSON.parse(raw2))}catch{let preview=raw2.trim().slice(0,LOG_PREVIEW)||"(empty)";this.log(`[protocol] malformed websocket: ${preview}`),this.push({type:"gateway.protocol_error",payload:{preview}})}}),ws.addEventListener("error",()=>{if(this.ws!==ws)return;let line=`websocket transport error (${safe})`;this.log(`[gateway] ${line}`),this.push({type:"gateway.stderr",payload:{line}})}),ws.addEventListener("close",(event)=>{if(this.ws!==ws)return;if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.ws=null,this.link=null,this.fail(Error(`gateway websocket closed${event.code?` (${event.code})`:""}`)),this.sub)this.emit("exit",event.code);else this.exit=event.code})}start(){let raw=gatewayUrl(),root=this.root(),bin=python(root),cwd=process.env.HERMES_CWD||process.cwd(),env2={...process.env};if(!env2.TERMINAL_CWD)env2.TERMINAL_CWD=cwd;let pp=env2.PYTHONPATH?.trim();env2.PYTHONPATH=pp?`${root}${delimiter}${pp}`:root,env2.HERMES_PYTHON_SRC_ROOT=root,this.ok=!1,this.buf=[],this.exit=void 0;let restarted=!1,previous=this.proc;if(previous){this.proc=null,this.fail(Error("gateway restarted")),restarted=!0;try{previous.kill()}catch{}}let socket=this.ws;if(socket){if(this.ws=null,this.link=null,this.target=null,!restarted)this.fail(Error("gateway restarted"));try{socket.close()}catch{}}if(this.timer)clearTimeout(this.timer);if(raw){this.connect(raw);return}this.timer=setTimeout(()=>{if(this.ok)return;this.log(`[startup] timed out (python=${bin}, cwd=${cwd})`),this.push({type:"gateway.start_timeout",payload:{cwd,python:bin}});let proc2=this.proc;if(!proc2||proc2.exitCode!==null)return;try{proc2.kill()}catch(err){this.proc=null;let failure=Error(`gateway startup timeout: ${err instanceof Error?err.message:String(err)}`);if(this.fail(failure),this.sub)this.emit("exit",null);else this.exit=null}},STARTUP_MS);let proc=(()=>{try{return Bun.spawn([bin,"-u","-m","tui_gateway.entry"],{cwd,env:env2,stdin:"pipe",stdout:"pipe",stderr:"pipe"})}catch(err){if(this.timer)clearTimeout(this.timer),this.timer=null;this.proc=null;let message=err instanceof Error?err.message:String(err);if(this.log(`[startup] spawn failed: ${message}`),this.push({type:"gateway.stderr",payload:{line:message}}),this.sub)this.emit("exit",null);else this.exit=null;return null}})();if(!proc)return;if(this.proc=proc,proc.stdout)lines(proc.stdout,(raw2)=>{if(this.proc!==proc)return;try{this.dispatch(JSON.parse(raw2))}catch{let preview=raw2.trim().slice(0,LOG_PREVIEW)||"(empty)";this.log(`[protocol] malformed: ${preview}`),this.push({type:"gateway.protocol_error",payload:{preview}})}});if(proc.stderr)lines(proc.stderr,(raw2)=>{if(this.proc!==proc)return;let line=raw2.trim();if(!line)return;this.log(line),this.push({type:"gateway.stderr",payload:{line}})});proc.exited.then((code)=>{if(this.proc!==proc)return;if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.fail(Error(`gateway exited${code===null?"":` (${code})`}`)),this.sub)this.emit("exit",code);else this.exit=code})}drain(){if(this.sub)return;this.sub=!0;for(let ev of this.buf.splice(0))this.emit("event",ev);if(this.exit!==void 0){let code=this.exit;this.exit=void 0,this.emit("exit",code)}}tail(n=20){return this.logs.slice(-Math.max(1,n)).join(`
3648
3648
  `)}sid="";setSession(sid){this.sid=sid}request(method,params={}){let raw=gatewayUrl();if(raw)return this.remote(raw,method,params);if(!this.proc||this.proc.exitCode!==null)this.start();let stdin=this.proc?.stdin;if(!stdin||typeof stdin==="number")return Promise.reject(Error("gateway not running"));let rid=`r${++this.id}`,writer=stdin,merged=this.sid&&params.session_id===void 0?{session_id:this.sid,...params}:params;return new Promise((resolve4,reject)=>{let timeout=setTimeout(()=>{if(this.pending.delete(rid))reject(Error(`timeout: ${method}`))},REQUEST_MS);this.pending.set(rid,{reject:(e)=>{clearTimeout(timeout),reject(e)},resolve:(v2)=>{clearTimeout(timeout),resolve4(v2)}});try{let frame=encode({jsonrpc:"2.0",id:rid,method,params:merged});if(frame.issues.length){let detail=frame.issues.map((x2)=>`${x2.path}:${x2.count}`).join(", ");this.log(`[wire] sanitized invalid unicode for ${method}: ${detail}`)}writer.write(frame.text+`
@@ -4086,17 +4086,17 @@ tell application "System Events" to get value of property list item "CFBundleNam
4086
4086
  `),found=!1,updated=lines3.map((line)=>{let eq2=line.trim().indexOf("=");if(eq2>=1&&envKey(line.trim().slice(0,eq2))===key3)return found=!0,`${key3}=${value}`;return line});if(!found)updated.push(`${key3}=${value}`);await Bun.write(envPath(),updated.join(`
4087
4087
  `))}async function removeEnvVar(key3){let text4="";try{text4=await Bun.file(envPath()).text()}catch{return}let lines3=text4.split(`
4088
4088
  `).filter((line)=>{let eq2=line.trim().indexOf("=");return eq2<1||envKey(line.trim().slice(0,eq2))!==key3});await Bun.write(envPath(),lines3.join(`
4089
- `))}var ENV_CATALOG=[{category:"LLM Providers",keys:["ANTHROPIC_API_KEY","ARCEEAI_API_KEY","DEEPSEEK_API_KEY","FIREWORKS_API_KEY","GEMINI_API_KEY","GLM_API_KEY","GMI_API_KEY","GOOGLE_API_KEY","GROQ_API_KEY","KIMI_API_KEY","LM_API_KEY","MINIMAX_API_KEY","MISTRAL_API_KEY","NOUS_API_KEY","NVIDIA_API_KEY","OPENAI_API_KEY","OPENROUTER_API_KEY","STEPFUN_API_KEY","TOGETHER_API_KEY","VERTEX_CREDENTIALS_PATH","XAI_API_KEY","ZAI_API_KEY","Z_AI_API_KEY"]},{category:"Tool API Keys",keys:["AGENT_BROWSER_ENGINE","BRAVE_SEARCH_API_KEY","BROWSERBASE_API_KEY","BROWSERBASE_PROJECT_ID","BROWSER_USE_API_KEY","CAMOFOX_API_KEY","CAMOFOX_URL","ELEVENLABS_API_KEY","EXA_API_KEY","FAL_KEY","FIRECRAWL_API_KEY","FIRECRAWL_API_URL","FIRECRAWL_BROWSER_TTL","KREA_API_KEY","OPENVIKING_API_KEY","OPENVIKING_ENDPOINT","SEARXNG_URL","TAVILY_API_KEY","TOOL_GATEWAY_DOMAIN","TOOL_GATEWAY_SCHEME","TOOL_GATEWAY_USER_TOKEN"]},{category:"Messaging",keys:["DISCORD_ALLOWED_USERS","DISCORD_BOT_TOKEN","DISCORD_REPLY_TO_MODE","SLACK_ALLOWED_USERS","SLACK_APP_TOKEN","SLACK_BOT_TOKEN","TELEGRAM_ALLOWED_USERS","TELEGRAM_BOT_TOKEN","TELEGRAM_PROXY"]},{category:"Agent",keys:["API_SERVER_KEY","BRV_API_KEY","HERMES_LANGFUSE_BASE_URL","HERMES_LANGFUSE_PUBLIC_KEY","HERMES_LANGFUSE_SECRET_KEY","HINDSIGHT_API_KEY","HINDSIGHT_API_URL","MEM0_API_KEY","RETAINDB_API_KEY","RETAINDB_BASE_URL","SUPERMEMORY_API_KEY"]}];var SLICES={config:{read:()=>readConfig(),watch:()=>[hermesPath("config.yaml")]},memory:{read:(d2)=>readMemoryFile("MEMORY.md",d2.config?.memory?.memory_char_limit??2200),deps:["config"],watch:()=>[hermesPath("memories/MEMORY.md")]},userProfile:{read:(d2)=>readMemoryFile("USER.md",d2.config?.memory?.user_char_limit??1375),deps:["config"],watch:()=>[hermesPath("memories/USER.md")]},memoryProviders:{read:(d2)=>readMemoryProviders(d2.config?.memory?.provider??""),deps:["config"]},memoryActivity:{read:()=>io.memoryActivity()},env:{read:()=>readEnvFile(),watch:()=>[hermesPath(".env")]},soul:{read:()=>readSoul(),watch:()=>[hermesPath("SOUL.md")]},liveSessions:{read:()=>readLiveSessions(),watch:()=>[hermesPath("sessions/sessions.json")]},recentSessions:{read:()=>io.roots(30)},systemPrompt:{read:()=>io.systemPrompt().then((r)=>r&&{source:makeSource("state.db"),sessionId:r.id,text:r.text,totalChars:r.text.length,tokenEstimate:count2(r.text)}).catch(()=>null)},toolsInfo:{read:()=>readToolsFromLatestSession(),watch:()=>[hermesPath("sessions")]},skillUsage:{read:()=>readSkillUsage(),watch:()=>[hermesPath("skills/.usage.json")]},curatorState:{read:()=>readCuratorState(),watch:()=>[hermesPath("skills/.curator_state")]}},DEPENDENTS=(()=>{let m2=new Map;for(let[k2,s]of Object.entries(SLICES))for(let d2 of s.deps??[]){let arr=m2.get(d2)??[];arr.push(k2),m2.set(d2,arr)}return m2})(),DEBOUNCE_MS=50,watchfs=(path4,cb)=>watch2(path4,{persistent:!1},(_ev,file)=>cb(file));class HomeStore{watcher;data={};subs=new Map;inflight=new Map;watchers=new Map;debounce=new Map;rev=new Map;gen=0;constructor(watcher=watchfs){this.watcher=watcher}get(k2){return this.data[k2]}subscribe(k2,cb){let set2=this.subs.get(k2);if(!set2)this.subs.set(k2,set2=new Set);return set2.add(cb),()=>set2.delete(cb)}ensure(k2){if(k2 in this.data)return Promise.resolve(this.data[k2]);let hit=this.inflight.get(k2);if(hit)return hit;let slice=SLICES[k2],gen=this.gen,rev2=this.rev.get(k2)??0,p=(async()=>{let deps={};for(let d2 of slice.deps??[])deps[d2]=await this.ensure(d2);let v2=await slice.read(deps);if(gen!==this.gen||rev2!==(this.rev.get(k2)??0))return v2;return this.data[k2]=v2,this.startWatch(k2,slice.watch),this.notify(k2),v2})();this.inflight.set(k2,p);let clear=()=>{if(this.inflight.get(k2)===p)this.inflight.delete(k2)};return p.then(clear,clear),p}invalidate(k2){if(!(k2 in this.data)&&!this.inflight.has(k2))return;if(this.rev.set(k2,(this.rev.get(k2)??0)+1),delete this.data[k2],this.inflight.delete(k2),this.subs.get(k2)?.size)this.ensure(k2);for(let dep of DEPENDENTS.get(k2)??[])this.invalidate(dep)}update(k2,fn){if(!(k2 in this.data))return;this.data[k2]=fn(this.data[k2]),this.notify(k2);for(let dep of DEPENDENTS.get(k2)??[])this.invalidate(dep)}close(){this.gen++;for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.subs.clear(),this.inflight.clear(),this.rev.clear(),this.data={}}reset(){this.gen++;for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.inflight.clear(),this.rev.clear(),this.data={};for(let k2 of this.subs.keys())if(this.subs.get(k2)?.size)this.ensure(k2)}notify(k2){let set2=this.subs.get(k2);if(set2)for(let cb of set2)cb()}startWatch(k2,watchFn){if(!watchFn||this.watchers.has(k2))return;let paths=watchFn(),ws=[],fire=()=>{let prev=this.debounce.get(k2);if(prev)clearTimeout(prev);this.debounce.set(k2,setTimeout(()=>this.invalidate(k2),DEBOUNCE_MS))};for(let p of paths){let dir=dirname7(p),name=basename8(p);try{if(existsSync17(p)&&statSync6(p).isDirectory())dir=p,name=null}catch{}if(!existsSync17(dir))continue;try{ws.push(this.watcher(dir,(file)=>{if(name===null||file?.toString()===name)fire()}))}catch{}}this.watchers.set(k2,ws)}}var home3=new HomeStore;function useHome(k2){let v2=import_react57.useSyncExternalStore((cb)=>home3.subscribe(k2,cb),()=>home3.get(k2));return import_react57.useEffect(()=>{home3.ensure(k2)},[k2]),v2}var cmp=(s)=>{let k2=(r)=>s==="started"?r.started_at:r.detail?.last_active??r.started_at;return(a,b2)=>k2(b2)-k2(a)},WORD={api:"API",cli:"CLI",tui:"TUI",whatsapp:"WhatsApp"},badge=(s)=>s.split(/[_-]+/).filter(Boolean).map((w2)=>WORD[w2.toLowerCase()]??(w2[0]?.toUpperCase()??"")+w2.slice(1)).join(" ")||"\u2014",label=(r)=>r.title.trim()||(r.live?"-":"Untitled"),src=(r)=>r.detail?.sessionSource||r.source||"",HOME4="conversations",HBAR={visible:!1},ROW={flexDirection:"row"},sid=(s)=>`source:${s}`,chip=(id)=>`sessions-source-${id.replace(/[^a-z0-9_-]/gi,"_")}`,tick2=(r)=>r.detail?.last_active??r.started_at,FilterRow=import_react58.memo((p)=>{let theme=useTheme().theme,ref=import_react58.useRef(null),renderer=useRenderer();return import_react58.useEffect(()=>{let move=()=>{let node=ref.current,idx=p.views.findIndex((v2)=>v2.id===p.view);if(!node||idx<0)return;let left=p.views.slice(0,idx).reduce((n,v2,i)=>n+(i===0?0:1)+`${v2.label} ${v2.count}`.length+2,0),w2=`${p.views[idx].label} ${p.views[idx].count}`.length+2,port2=Math.max(1,node.viewport.width-4),pos=node.scrollLeft;node.scrollLeft=Math.max(0,left<pos?left:left+w2>pos+port2?left+w2-port2:pos)};move();let frames=0,frame=async()=>{if(move(),++frames>=2)renderer.removeFrameCallback(frame)};return renderer.setFrameCallback(frame),()=>renderer.removeFrameCallback(frame)},[p.view,p.views,renderer]),$jsx("scrollbox",{ref,scrollX:!0,height:1,paddingLeft:2,horizontalScrollbarOptions:HBAR,contentOptions:ROW,children:p.views.map((v2,i)=>$jsx(FilterChip,{id:chip(v2.id),label:`${v2.label} ${v2.count}`,state:p.view===v2.id?"in":"off",gap:i===0?0:1,color:theme.primary,textColor:theme.primary,onMouseDown:()=>p.setView(v2.id)},v2.id))})}),line=(s)=>(s??"").replace(/\s+/g," ").trim(),fold=(msgs)=>{let turns=[],tools=0;for(let m2 of msgs){if(m2.role==="tool"){tools++;continue}if(m2.role!=="user"&&m2.role!=="assistant")continue;let text4=line(m2.content);if(!text4)continue;turns.push({role:m2.role,text:text4})}return{turns,tools}},PeekRow=import_react58.memo((props)=>{let theme=useTheme().theme,[hot,setHot]=import_react58.useState(!1),left=props.row.role==="user",color=left?theme.primary:theme.accent,fg2=left?theme.text:theme.markdownText,bar=(side)=>$jsx("box",{width:2,flexShrink:0,height:1,border:[side],borderColor:color,customBorderChars:SIDE_PIPE});return $jsxs("box",{height:1,flexDirection:"row",backgroundColor:hot?theme.backgroundElement:void 0,onMouseOver:()=>setHot(!0),onMouseOut:()=>setHot(!1),children:[left?bar("left"):null,$jsx(Ticker,{active:hot,speed:35,hold:150,fg:fg2,children:inline(props.row.text).map((s,i)=>s.c?$jsx("span",{fg:theme.warning,children:s.t},i):s.b?$jsx("span",{fg:fg2,children:$jsx("strong",{children:s.t})},i):s.i?$jsx("span",{fg:fg2,children:$jsx("u",{children:s.t})},i):$jsx("span",{fg:fg2,children:s.t},i))}),left?null:bar("right")]})}),Peek=import_react58.memo((props)=>{let theme=useTheme().theme,[data2,setData]=import_react58.useState(null),[err,setErr]=import_react58.useState(""),sb=import_react58.useRef(null),gen=import_react58.useRef(0);if(import_react58.useEffect(()=>{let current=++gen.current;return setData(null),setErr(""),Promise.resolve(props.peek(props.sid)).then((m2)=>{if(gen.current===current)setData(fold(m2))}).catch((e)=>{if(gen.current===current)setErr(e instanceof Error?e.message:String(e))}),()=>{gen.current++}},[props.sid,props.peek]),import_react58.useEffect(()=>{if(data2&&sb.current)sb.current.scrollTop=sb.current.scrollHeight},[data2]),err)return $jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:err})});if(data2===null)return null;if(data2.turns.length===0&&data2.tools===0)return $jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local transcript)"})});let gap=props.total>4;return $jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:5,border:!0,borderStyle:"single",borderColor:theme.border,title:` Transcript${gap?" \xB7 first 2 / last 2":""} `,titleAlignment:"left",children:[$jsx("scrollbox",{ref:sb,scrollY:!0,flexGrow:1,minHeight:3,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.turns.map((r,i)=>$jsxs(import_react58.Fragment,{children:[$jsx(PeekRow,{row:r}),gap&&i===1?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:" \u2026"})}):null]},i))})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${data2.turns.length} turn${data2.turns.length===1?"":"s"} \xB7 ${data2.tools} tool call${data2.tools===1?"":"s"}`})})]})}),Detail=import_react58.memo((props)=>{let theme=useTheme().theme,r=props.row,d2=r.detail,lastActive=d2?.last_active??d2?.ended_at??null,subs2=d2?.subagent_count??0,[info,setInfo]=import_react58.useState({}),[lineageErr,setLineageErr]=import_react58.useState(""),lineageGen=import_react58.useRef(0);import_react58.useEffect(()=>{let current=++lineageGen.current;return setInfo({}),setLineageErr(""),Promise.resolve(props.lineage(r.id)).then((next)=>{if(lineageGen.current===current)setInfo(next)}).catch((e)=>{if(lineageGen.current===current)setLineageErr(e instanceof Error?e.message:String(e))}),()=>{lineageGen.current++}},[r.id,props.lineage]);let hasLineage=info.continuesFrom||info.compressedTo||subs2>0,go=(sid2)=>()=>props.onSwitch?.(sid2);return $jsx(TabShell,{title:"Session Detail",grow:2,children:$jsxs("box",{flexDirection:"column",width:"100%",flexGrow:1,overflow:"hidden",children:[$jsxs("box",{flexDirection:"column",flexShrink:0,children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:label(r)})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",r.id],["Source",badge(src(r))],["Model",d2?.model??"\u2014"],["Started",when(r.started_at)],["Last active",lastActive?`${when(lastActive)} (${ago(lastActive)})`:"\u2014"],["Duration",lastActive?span(r.started_at,lastActive):"\u2014"],["Ended",d2?.ended_at?`${when(d2.ended_at)} \xB7 ${d2.end_reason??"\u2014"}`:void 0]]}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Messages",String(r.message_count)],["Tool calls",d2?String(d2.tool_call_count):void 0],["Input",d2?`${fmt(d2.input_tokens)} tok`:void 0],["Output",d2?`${fmt(d2.output_tokens)} tok`:void 0],["Cache",d2?`${fmt(d2.cache_read_tokens)} r / ${fmt(d2.cache_write_tokens)} w`:void 0],["Reasoning",d2?`${fmt(d2.reasoning_tokens)} tok`:void 0],["Cost",d2?cost2(d2.estimated_cost_usd):void 0,theme.success]]}),hasLineage?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,children:"Lineage"})}),info.continuesFrom?$jsx("box",{height:1,onMouseDown:go(info.continuesFrom.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2190 continues from "}),$jsx("span",{fg:theme.accent,children:info.continuesFrom.title||info.continuesFrom.id})]})}):null,info.compressedTo?$jsx("box",{height:1,onMouseDown:go(info.compressedTo.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2192 compressed to "}),$jsx("span",{fg:theme.accent,children:info.compressedTo.title||info.compressedTo.id})]})}):null,subs2>0?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2387 spawned "}),$jsx("span",{fg:theme.text,children:String(subs2)}),$jsx("span",{fg:theme.textMuted,children:` subagent${subs2===1?"":"s"}`})]})}):null]}):null,lineageErr?$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:lineageErr})}):null,!d2?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local detail \u2014 state.db mismatch)"})})]}):null,$jsx("box",{height:1})]}),$jsx(Peek,{sid:r.id,total:r.message_count,peek:props.peek})]})})}),SearchDetail=import_react58.memo((props)=>{let theme=useTheme().theme,r=props.result,parts2=[],rest=r.snippet;while(rest.length){let start=rest.indexOf(">>>");if(start<0){parts2.push({text:rest,hi:!1});break}if(start>0)parts2.push({text:rest.slice(0,start),hi:!1});let end=rest.indexOf("<<<",start+3);if(end<0){parts2.push({text:rest.slice(start+3),hi:!0});break}parts2.push({text:rest.slice(start+3,end),hi:!0}),rest=rest.slice(end+3)}return $jsx(TabShell,{title:"Search Match",grow:2,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:r.title??"Untitled"})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Source",badge(r.source)],["Model",r.model??"\u2014"],["Time",when(r.started_at)]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Snippet"})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:parts2.map((p,i)=>p.hi?$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:p.text})},i):$jsx("span",{fg:theme.text,children:p.text},i))})})]})})})}),HeaderRow=import_react58.memo((props)=>{let theme=useTheme().theme,fg2=theme.textMuted,on=theme.accent,by=props.sort;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:8,fg:by==="started"?on:fg2,bold:!0,onClick:()=>props.onSort("started"),children:by==="started"?"Start \u25BE":"Start"}),$jsx(Col,{w:10,fg:by==="active"?on:fg2,bold:!0,right:!0,onClick:()=>props.onSort("active"),children:by==="active"?"Active \u25BE":"Active"}),$jsx(Col,{w:7,fg:fg2,bold:!0,right:!0,children:"Msgs"}),$jsx("box",{width:3})]})}),Item=import_react58.memo((props)=>{let theme=useTheme().theme,{row:r,idx:i}=props,[x2,setX]=import_react58.useState(!1),active=r.detail?.last_active??r.detail?.ended_at??null,locked=props.locked||props.indent||Boolean(r.live),subs2=!props.indent&&(r.detail?.subagent_count??0)>0,leader=props.indent?"\u2514\u2500":props.selected?"\u25B8 ":" ",muted=props.indent&&!props.selected?theme.textMuted:void 0;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:muted??theme.text,children:leader}),$jsx(Marquee,{grow:!0,active:props.selected,fg:props.selected?theme.accent:muted??theme.text,bold:props.selected,underline:props.selected&&subs2,children:label(r)}),$jsx(Col,{w:9,fg:muted??theme.info,children:badge(src(r))}),$jsx(Col,{w:8,fg:theme.textMuted,children:stamp(r.started_at)}),$jsx(Col,{w:10,fg:theme.textMuted,right:!0,children:active?ago(active):"\u2014"}),$jsx(Col,{w:7,fg:theme.textMuted,right:!0,children:subs2?`${r.detail?.subagent_count} subs`:String(r.message_count)}),locked?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{children:$jsx("span",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})})]})}),SearchHeaderRow=import_react58.memo(()=>{let fg2=useTheme().theme.textMuted;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:10,fg:fg2,bold:!0,children:"When"}),$jsx(Col,{w:20,fg:fg2,bold:!0,children:"Model"})]})}),SearchItem=import_react58.memo((props)=>{let theme=useTheme().theme,{result:r,idx:i}=props;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,bold:props.selected,children:r.title??"Untitled"}),$jsx(Col,{w:9,fg:theme.info,children:badge(r.source)}),$jsx(Col,{w:10,fg:theme.textMuted,children:ago(r.started_at)}),$jsx(Col,{w:20,fg:theme.textMuted,children:r.model??"\u2014"})]})}),last={rows:[],kids:new Map},Sessions=import_react58.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),cached2=props.io==null,io2=import_react58.useMemo(()=>({list:props.io?.list??io.roots,search:props.io?.search??io.search,subagents:props.io?.subagents??io.children,lineage:props.io?.lineage??io.lineage,peek:props.io?.peek??io.peek,remove:props.io?.remove??exports_sessions_db.remove,rename:props.io?.rename??exports_sessions_db.rename}),[props.io]),[rows2,setRows]=import_react58.useState(cached2?last.rows:[]),[liveRows,setLiveRows]=import_react58.useState([]),[warn,setWarn]=import_react58.useState(""),[searchErr,setSearchErr]=import_react58.useState(""),[pending3,setPending]=import_react58.useState(rows2.length===0),sort=exports_preferences.usePref("sessions")?.sort??"active",setSort=import_react58.useCallback((s)=>exports_preferences.set("sessions",{sort:s}),[]),[view,setView]=import_react58.useState(HOME4),active=import_react58.useMemo(()=>[...liveRows].sort((a,b2)=>Number(Boolean(b2.live?.current))-Number(Boolean(a.live?.current))||(b2.live?.last_active??b2.started_at)-(a.live?.last_active??a.started_at)),[liveRows]),ids=import_react58.useMemo(()=>new Set(active.flatMap((r)=>[r.id,r.live?.session_key].filter((x2)=>Boolean(x2)))),[active]),sorted=import_react58.useMemo(()=>rows2.filter((r)=>!ids.has(r.id)).sort(cmp(sort)),[rows2,ids,sort]),views=import_react58.useMemo(()=>{let stats=sorted.reduce((m2,r)=>{let s=src(r);if(!s)return m2;let prev=m2.get(s);return m2.set(s,{count:(prev?.count??0)+1,last:Math.max(prev?.last??0,tick2(r))}),m2},new Map),conv=sorted.filter((r)=>src(r)!=="cron").length;return[...conv>0?[{id:HOME4,label:"Conversations",count:conv,aggregate:"conversations"}]:[],...[...stats.entries()].sort((a,b2)=>b2[1].last-a[1].last||badge(a[0]).localeCompare(badge(b2[0]))).map(([source,stat2])=>({id:sid(source),label:badge(source),count:stat2.count,source}))]},[sorted]),cur=views.find((v2)=>v2.id===view)??views[0],chosen=cur?.id??view,hist=import_react58.useMemo(()=>{if(!cur)return[];if(cur.aggregate===HOME4)return sorted.filter((r)=>src(r)!=="cron");return sorted.filter((r)=>src(r)===cur.source)},[sorted,cur]),listed=import_react58.useMemo(()=>[...active,...hist],[active,hist]);import_react58.useEffect(()=>{if(views.length>0&&!views.some((v2)=>v2.id===view))setView(views[0].id)},[views,view]);let[anchor,setAnchor]=import_react58.useState(null),[open2,setOpen]=import_react58.useState(null),[searching,setSearching]=import_react58.useState(!1),[query,setQuery]=import_react58.useState(""),[results,setResults]=import_react58.useState([]),[searchSel,setSearchSel]=import_react58.useState(0),[kids,setKids]=import_react58.useState(cached2?last.kids:new Map),debounce=import_react58.useRef(null),searchGen=import_react58.useRef(0),vscroll=import_react58.useRef(null),seen=import_react58.useRef(!1),gen=import_react58.useRef(0),anchored=anchor&&listed.find((r)=>r.id===anchor.id),branch2=open2?listed.find((r)=>r.id===open2):void 0,owner=branch2&&(anchor?.indent?kids.get(branch2.id)?.some((c)=>c.id===anchor.id):anchored?.id===branch2.id)?branch2:void 0,showDetailPanel=dims.width>=120,visible2=listed.flatMap((r,i)=>r.id===owner?.id?[{row:r,indent:!1,parentIdx:i},...(kids.get(r.id)??[]).map((c)=>({row:c,indent:!0,parentIdx:i}))]:[{row:r,indent:!1,parentIdx:i}]),sel=anchor?Math.max(0,visible2.findIndex((v2)=>v2.row.id===anchor.id&&v2.indent===anchor.indent)):0,live=import_react58.useRef({rows:listed,visible:visible2,anchor,results,searching,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId});live.current={rows:listed,visible:visible2,anchor,results,searching,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId};let setSel=import_react58.useCallback((arg)=>{let cur2=live.current,prev=cur2.visible.findIndex((v3)=>v3.row.id===cur2.anchor?.id&&v3.indent===cur2.anchor.indent),n=typeof arg==="function"?arg(Math.max(0,prev)):arg,v2=cur2.visible[Math.max(0,Math.min(cur2.visible.length-1,n))];if(v2)setAnchor({id:v2.row.id,indent:v2.indent})},[]),LIMIT=2000,keep=(d2)=>d2.message_count>0||d2.lineage_root_id!=null,toRow2=(d2)=>({id:d2.id,title:d2.title??"",preview:d2.lastMessage??"",message_count:d2.message_count,started_at:d2.started_at,source:d2.sessionSource,detail:d2}),toLiveRow=(s,d2,r)=>({id:s.id,title:s.title?.trim()||d2?.title||"",preview:s.preview??"",message_count:s.message_count??d2?.message_count??r?.message_count??0,started_at:s.started_at??d2?.started_at??r?.started_at??s.last_active??0,source:d2?.sessionSource??r?.source??s.source??"",detail:d2,live:s}),pick=(m2,s)=>m2.get(s.id)??m2.get(s.session_key??""),patchTitle=import_react58.useCallback((id,title)=>{if(!id||title===void 0)return;home3.update("recentSessions",(rows3)=>rows3.map((r)=>r.id===id?{...r,title}:r)),setRows((prev)=>prev.map((row3)=>row3.id===id?{...row3,title,detail:row3.detail?{...row3.detail,title}:row3.detail}:row3)),setLiveRows((prev)=>prev.map((row3)=>row3.id===id||row3.live?.session_key===id?{...row3,title,live:row3.live?{...row3.live,title}:row3.live}:row3))},[]);useGatewayEvent((ev)=>{if(ev.type==="session.title")patchTitle(ev.payload.session_id,ev.payload.title)});let load4=import_react58.useCallback(async()=>{let current=++gen.current;setPending(!0);let rpc=gw.request("session.list",{limit:LIMIT}).then((r2)=>({ok:!0,v:r2})).catch((e)=>({ok:!1,e})),active2=gw.request("session.active_list",{current_session_id:props.currentId}).then((r2)=>({ok:!0,v:r2})).catch((e)=>({ok:!1,e})),disk=await Promise.resolve(io2.list(LIMIT)).catch(()=>[]);if(gen.current!==current)return;let local=new Map(disk.map((r2)=>[r2.id,r2])),diskRows=disk.filter(keep).map(toRow2);if(setRows(diskRows),cached2)last.rows=diskRows;let[a,r]=await Promise.all([active2,rpc]);if(gen.current!==current)return;let live2=a.ok?a.v.sessions??[]:[];if(a.ok)setLiveRows(live2.map((s)=>toLiveRow(s,pick(local,s))));let final=diskRows;if(r.ok&&r.v.sessions?.length){let seen2=new Set(diskRows.map((s)=>s.id)),merged=[...diskRows,...r.v.sessions.filter((s)=>(s.message_count??0)>0&&!seen2.has(s.id)).map((s)=>({...s,detail:local.get(s.id)}))];if(final=merged,setRows(merged),cached2)last.rows=merged;let found=new Map(merged.map((s)=>[s.id,s]));if(live2.length)setLiveRows(live2.map((s)=>toLiveRow(s,pick(local,s),pick(found,s))))}let kidsError="";try{let parents=final.filter((row3)=>(row3.detail?.subagent_count??0)>0),children2=[];for(let i=0;i<parents.length;i+=8)if(children2.push(...await Promise.all(parents.slice(i,i+8).map((row3)=>io2.subagents(row3.id)))),gen.current!==current)return;if(gen.current!==current)return;let next=new Map(parents.map((row3,i)=>[row3.id,children2[i].map(toRow2)]));if(setKids(next),cached2)last.kids=next}catch(err){kidsError=err instanceof Error?err.message:String(err)}if(gen.current!==current)return;setPending(!1);let listError=!r.ok?local.size?`gateway session.list failed (${r.e.message}) \u2014 listing state.db directly; rows may not resume`:r.e.message:"";setWarn([listError,kidsError].filter(Boolean).join(" \xB7 "))},[gw,props.currentId,io2,cached2]);import_react58.useEffect(()=>{load4()},[load4]),import_react58.useEffect(()=>()=>{gen.current++},[]),import_react58.useEffect(()=>{let on=active.length>0,fresh=on&&!seen.current;if(!listed.length){seen.current=on;return}if(!anchor||!visible2.some((v2)=>v2.row.id===anchor.id&&v2.indent===anchor.indent)){setAnchor({id:listed[0].id,indent:!1}),seen.current=on;return}if(fresh&&active[0]&&hist[0]?.id===anchor.id&&!anchor.indent)setAnchor({id:active[0].id,indent:!1});seen.current=on},[listed,active,hist,anchor]),import_react58.useEffect(()=>{let current=++searchGen.current;if(setSearchErr(""),!searching||!query.trim()){setResults([]);return}return setResults([]),setSearchSel(0),debounce.current=setTimeout(()=>{Promise.resolve(io2.search(query,30)).then((r)=>{if(searchGen.current!==current)return;setResults(r),setSearchSel(0),setSearchErr("")}).catch((err)=>{if(searchGen.current===current)setSearchErr(err instanceof Error?err.message:String(err))})},150),()=>{if(debounce.current)clearTimeout(debounce.current)}},[query,searching,io2]);let rowHover=import_react58.useCallback((i)=>{live.current.searching?setSearchSel(i):setSel(i)},[setSel]),rowActivate=import_react58.useCallback((i)=>{let l=live.current;l.searching?setSearchSel(i):setSel(i);let hit=l.searching?l.results[i]:l.visible[i]?.row,id=l.searching?hit?.session_id:hit?.id;if(!id)return;if(!l.searching&&hit?.live){if(l.onActivateLive)return l.onActivateLive(id);return l.onSwitch?.(id)}if(!l.onSwitch)return;if(id===l.currentId)return l.onSwitch(id);let title=hit?.title||"Untitled",n=l.searching?void 0:hit.message_count;openConfirm(dialog,{title:"Load session?",body:`${trunc5(title,60)}${n!=null?` \xB7 ${n} msg${n===1?"":"s"}`:""}
4089
+ `))}var ENV_CATALOG=[{category:"LLM Providers",keys:["ANTHROPIC_API_KEY","ARCEEAI_API_KEY","DEEPSEEK_API_KEY","FIREWORKS_API_KEY","GEMINI_API_KEY","GLM_API_KEY","GMI_API_KEY","GOOGLE_API_KEY","GROQ_API_KEY","KIMI_API_KEY","LM_API_KEY","MINIMAX_API_KEY","MISTRAL_API_KEY","NOUS_API_KEY","NVIDIA_API_KEY","OPENAI_API_KEY","OPENROUTER_API_KEY","STEPFUN_API_KEY","TOGETHER_API_KEY","VERTEX_CREDENTIALS_PATH","XAI_API_KEY","ZAI_API_KEY","Z_AI_API_KEY"]},{category:"Tool API Keys",keys:["AGENT_BROWSER_ENGINE","BRAVE_SEARCH_API_KEY","BROWSERBASE_API_KEY","BROWSERBASE_PROJECT_ID","BROWSER_USE_API_KEY","CAMOFOX_API_KEY","CAMOFOX_URL","ELEVENLABS_API_KEY","EXA_API_KEY","FAL_KEY","FIRECRAWL_API_KEY","FIRECRAWL_API_URL","FIRECRAWL_BROWSER_TTL","KREA_API_KEY","OPENVIKING_API_KEY","OPENVIKING_ENDPOINT","SEARXNG_URL","TAVILY_API_KEY","TOOL_GATEWAY_DOMAIN","TOOL_GATEWAY_SCHEME","TOOL_GATEWAY_USER_TOKEN"]},{category:"Messaging",keys:["DISCORD_ALLOWED_USERS","DISCORD_BOT_TOKEN","DISCORD_REPLY_TO_MODE","SLACK_ALLOWED_USERS","SLACK_APP_TOKEN","SLACK_BOT_TOKEN","TELEGRAM_ALLOWED_USERS","TELEGRAM_BOT_TOKEN","TELEGRAM_PROXY"]},{category:"Agent",keys:["API_SERVER_KEY","BRV_API_KEY","HERMES_LANGFUSE_BASE_URL","HERMES_LANGFUSE_PUBLIC_KEY","HERMES_LANGFUSE_SECRET_KEY","HINDSIGHT_API_KEY","HINDSIGHT_API_URL","MEM0_API_KEY","RETAINDB_API_KEY","RETAINDB_BASE_URL","SUPERMEMORY_API_KEY"]}];var SLICES={config:{read:()=>readConfig(),watch:()=>[hermesPath("config.yaml")]},memory:{read:(d2)=>readMemoryFile("MEMORY.md",d2.config?.memory?.memory_char_limit??2200),deps:["config"],watch:()=>[hermesPath("memories/MEMORY.md")]},userProfile:{read:(d2)=>readMemoryFile("USER.md",d2.config?.memory?.user_char_limit??1375),deps:["config"],watch:()=>[hermesPath("memories/USER.md")]},memoryProviders:{read:(d2)=>readMemoryProviders(d2.config?.memory?.provider??""),deps:["config"]},memoryActivity:{read:()=>io.memoryActivity()},env:{read:()=>readEnvFile(),watch:()=>[hermesPath(".env")]},soul:{read:()=>readSoul(),watch:()=>[hermesPath("SOUL.md")]},liveSessions:{read:()=>readLiveSessions(),watch:()=>[hermesPath("sessions/sessions.json")]},recentSessions:{read:()=>io.roots(30)},systemPrompt:{read:()=>io.systemPrompt().then((r)=>r&&{source:makeSource("state.db"),sessionId:r.id,text:r.text,totalChars:r.text.length,tokenEstimate:count2(r.text)}).catch(()=>null)},toolsInfo:{read:()=>readToolsFromLatestSession(),watch:()=>[hermesPath("sessions")]},skillUsage:{read:()=>readSkillUsage(),watch:()=>[hermesPath("skills/.usage.json")]},curatorState:{read:()=>readCuratorState(),watch:()=>[hermesPath("skills/.curator_state")]}},DEPENDENTS=(()=>{let m2=new Map;for(let[k2,s]of Object.entries(SLICES))for(let d2 of s.deps??[]){let arr=m2.get(d2)??[];arr.push(k2),m2.set(d2,arr)}return m2})(),DEBOUNCE_MS=50,watchfs=(path4,cb)=>watch2(path4,{persistent:!1},(_ev,file)=>cb(file));class HomeStore{watcher;data={};subs=new Map;inflight=new Map;watchers=new Map;debounce=new Map;rev=new Map;gen=0;constructor(watcher=watchfs){this.watcher=watcher}get(k2){return this.data[k2]}subscribe(k2,cb){let set2=this.subs.get(k2);if(!set2)this.subs.set(k2,set2=new Set);return set2.add(cb),()=>set2.delete(cb)}ensure(k2){if(k2 in this.data)return Promise.resolve(this.data[k2]);let hit=this.inflight.get(k2);if(hit)return hit;let slice=SLICES[k2],gen=this.gen,rev2=this.rev.get(k2)??0,p=(async()=>{let deps={};for(let d2 of slice.deps??[])deps[d2]=await this.ensure(d2);let v2=await slice.read(deps);if(gen!==this.gen||rev2!==(this.rev.get(k2)??0))return v2;return this.data[k2]=v2,this.startWatch(k2,slice.watch),this.notify(k2),v2})();this.inflight.set(k2,p);let clear=()=>{if(this.inflight.get(k2)===p)this.inflight.delete(k2)};return p.then(clear,clear),p}invalidate(k2){if(!(k2 in this.data)&&!this.inflight.has(k2))return;if(this.rev.set(k2,(this.rev.get(k2)??0)+1),delete this.data[k2],this.inflight.delete(k2),this.subs.get(k2)?.size)this.ensure(k2);for(let dep of DEPENDENTS.get(k2)??[])this.invalidate(dep)}update(k2,fn){if(!(k2 in this.data))return;this.data[k2]=fn(this.data[k2]),this.notify(k2);for(let dep of DEPENDENTS.get(k2)??[])this.invalidate(dep)}close(){this.gen++;for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.subs.clear(),this.inflight.clear(),this.rev.clear(),this.data={}}reset(){this.gen++;for(let ws of this.watchers.values())for(let w2 of ws)w2.close();for(let t2 of this.debounce.values())clearTimeout(t2);this.watchers.clear(),this.debounce.clear(),this.inflight.clear(),this.rev.clear(),this.data={};for(let k2 of this.subs.keys())if(this.subs.get(k2)?.size)this.ensure(k2)}notify(k2){let set2=this.subs.get(k2);if(set2)for(let cb of set2)cb()}startWatch(k2,watchFn){if(!watchFn||this.watchers.has(k2))return;let paths=watchFn(),ws=[],fire=()=>{let prev=this.debounce.get(k2);if(prev)clearTimeout(prev);this.debounce.set(k2,setTimeout(()=>this.invalidate(k2),DEBOUNCE_MS))};for(let p of paths){let dir=dirname7(p),name=basename8(p);try{if(existsSync17(p)&&statSync6(p).isDirectory())dir=p,name=null}catch{}if(!existsSync17(dir))continue;try{ws.push(this.watcher(dir,(file)=>{if(name===null||file?.toString()===name)fire()}))}catch{}}this.watchers.set(k2,ws)}}var home3=new HomeStore;function useHome(k2){let v2=import_react57.useSyncExternalStore((cb)=>home3.subscribe(k2,cb),()=>home3.get(k2));return import_react57.useEffect(()=>{home3.ensure(k2)},[k2]),v2}var cmp=(s)=>{let k2=(r)=>s==="started"?r.started_at:r.detail?.last_active??r.started_at;return(a,b2)=>k2(b2)-k2(a)},WORD={api:"API",cli:"CLI",tui:"TUI",whatsapp:"WhatsApp"},badge=(s)=>s.split(/[_-]+/).filter(Boolean).map((w2)=>WORD[w2.toLowerCase()]??(w2[0]?.toUpperCase()??"")+w2.slice(1)).join(" ")||"\u2014",label=(r)=>r.title.trim()||(r.live?"-":"Untitled"),src=(r)=>r.detail?.sessionSource||r.source||"",fallback=(msg)=>{let s=msg.trim();if(/\b(?:timeout|timed out)\b/i.test(s))return!1;return/^(method not found|unknown method(?::|\b)|gateway not running\b|gateway exited(?:\s*\(|$))/i.test(s)},HOME4="conversations",HBAR={visible:!1},ROW={flexDirection:"row"},sid=(s)=>`source:${s}`,chip=(id)=>`sessions-source-${id.replace(/[^a-z0-9_-]/gi,"_")}`,tick2=(r)=>r.detail?.last_active??r.started_at,FilterRow=import_react58.memo((p)=>{let theme=useTheme().theme,ref=import_react58.useRef(null),renderer=useRenderer();return import_react58.useEffect(()=>{let move=()=>{let node=ref.current,idx=p.views.findIndex((v2)=>v2.id===p.view);if(!node||idx<0)return;let left=p.views.slice(0,idx).reduce((n,v2,i)=>n+(i===0?0:1)+`${v2.label} ${v2.count}`.length+2,0),w2=`${p.views[idx].label} ${p.views[idx].count}`.length+2,port2=Math.max(1,node.viewport.width-4),pos=node.scrollLeft;node.scrollLeft=Math.max(0,left<pos?left:left+w2>pos+port2?left+w2-port2:pos)};move();let frames=0,frame=async()=>{if(move(),++frames>=2)renderer.removeFrameCallback(frame)};return renderer.setFrameCallback(frame),()=>renderer.removeFrameCallback(frame)},[p.view,p.views,renderer]),$jsx("scrollbox",{ref,scrollX:!0,height:1,paddingLeft:2,horizontalScrollbarOptions:HBAR,contentOptions:ROW,children:p.views.map((v2,i)=>$jsx(FilterChip,{id:chip(v2.id),label:`${v2.label} ${v2.count}`,state:p.view===v2.id?"in":"off",gap:i===0?0:1,color:theme.primary,textColor:theme.primary,onMouseDown:()=>p.setView(v2.id)},v2.id))})}),line=(s)=>(s??"").replace(/\s+/g," ").trim(),fold=(msgs)=>{let turns=[],tools=0;for(let m2 of msgs){if(m2.role==="tool"){tools++;continue}if(m2.role!=="user"&&m2.role!=="assistant")continue;let text4=line(m2.content);if(!text4)continue;turns.push({role:m2.role,text:text4})}return{turns,tools}},PeekRow=import_react58.memo((props)=>{let theme=useTheme().theme,[hot,setHot]=import_react58.useState(!1),left=props.row.role==="user",color=left?theme.primary:theme.accent,fg2=left?theme.text:theme.markdownText,bar=(side)=>$jsx("box",{width:2,flexShrink:0,height:1,border:[side],borderColor:color,customBorderChars:SIDE_PIPE});return $jsxs("box",{height:1,flexDirection:"row",backgroundColor:hot?theme.backgroundElement:void 0,onMouseOver:()=>setHot(!0),onMouseOut:()=>setHot(!1),children:[left?bar("left"):null,$jsx(Ticker,{active:hot,speed:35,hold:150,fg:fg2,children:inline(props.row.text).map((s,i)=>s.c?$jsx("span",{fg:theme.warning,children:s.t},i):s.b?$jsx("span",{fg:fg2,children:$jsx("strong",{children:s.t})},i):s.i?$jsx("span",{fg:fg2,children:$jsx("u",{children:s.t})},i):$jsx("span",{fg:fg2,children:s.t},i))}),left?null:bar("right")]})}),Peek=import_react58.memo((props)=>{let theme=useTheme().theme,[data2,setData]=import_react58.useState(null),[err,setErr]=import_react58.useState(""),sb=import_react58.useRef(null),gen=import_react58.useRef(0);if(import_react58.useEffect(()=>{let current=++gen.current;return setData(null),setErr(""),Promise.resolve(props.peek(props.sid)).then((m2)=>{if(gen.current===current)setData(fold(m2))}).catch((e)=>{if(gen.current===current)setErr(e instanceof Error?e.message:String(e))}),()=>{gen.current++}},[props.sid,props.peek]),import_react58.useEffect(()=>{if(data2&&sb.current)sb.current.scrollTop=sb.current.scrollHeight},[data2]),err)return $jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:err})});if(data2===null)return null;if(data2.turns.length===0&&data2.tools===0)return $jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local transcript)"})});let gap=props.total>4;return $jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:5,border:!0,borderStyle:"single",borderColor:theme.border,title:` Transcript${gap?" \xB7 first 2 / last 2":""} `,titleAlignment:"left",children:[$jsx("scrollbox",{ref:sb,scrollY:!0,flexGrow:1,minHeight:3,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.turns.map((r,i)=>$jsxs(import_react58.Fragment,{children:[$jsx(PeekRow,{row:r}),gap&&i===1?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:" \u2026"})}):null]},i))})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${data2.turns.length} turn${data2.turns.length===1?"":"s"} \xB7 ${data2.tools} tool call${data2.tools===1?"":"s"}`})})]})}),Detail=import_react58.memo((props)=>{let theme=useTheme().theme,r=props.row,d2=r.detail,lastActive=d2?.last_active??d2?.ended_at??null,subs2=d2?.subagent_count??0,[info,setInfo]=import_react58.useState({}),[lineageErr,setLineageErr]=import_react58.useState(""),lineageGen=import_react58.useRef(0);import_react58.useEffect(()=>{let current=++lineageGen.current;return setInfo({}),setLineageErr(""),Promise.resolve(props.lineage(r.id)).then((next)=>{if(lineageGen.current===current)setInfo(next)}).catch((e)=>{if(lineageGen.current===current)setLineageErr(e instanceof Error?e.message:String(e))}),()=>{lineageGen.current++}},[r.id,props.lineage]);let hasLineage=info.continuesFrom||info.compressedTo||subs2>0,go=(sid2)=>()=>props.onSwitch?.(sid2);return $jsx(TabShell,{title:"Session Detail",grow:2,children:$jsxs("box",{flexDirection:"column",width:"100%",flexGrow:1,overflow:"hidden",children:[$jsxs("box",{flexDirection:"column",flexShrink:0,children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:label(r)})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["ID",r.id],["Source",badge(src(r))],["Model",d2?.model??"\u2014"],["Started",when(r.started_at)],["Last active",lastActive?`${when(lastActive)} (${ago(lastActive)})`:"\u2014"],["Duration",lastActive?span(r.started_at,lastActive):"\u2014"],["Ended",d2?.ended_at?`${when(d2.ended_at)} \xB7 ${d2.end_reason??"\u2014"}`:void 0]]}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Messages",String(r.message_count)],["Tool calls",d2?String(d2.tool_call_count):void 0],["Input",d2?`${fmt(d2.input_tokens)} tok`:void 0],["Output",d2?`${fmt(d2.output_tokens)} tok`:void 0],["Cache",d2?`${fmt(d2.cache_read_tokens)} r / ${fmt(d2.cache_write_tokens)} w`:void 0],["Reasoning",d2?`${fmt(d2.reasoning_tokens)} tok`:void 0],["Cost",d2?cost2(d2.estimated_cost_usd):void 0,theme.success]]}),hasLineage?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,children:"Lineage"})}),info.continuesFrom?$jsx("box",{height:1,onMouseDown:go(info.continuesFrom.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2190 continues from "}),$jsx("span",{fg:theme.accent,children:info.continuesFrom.title||info.continuesFrom.id})]})}):null,info.compressedTo?$jsx("box",{height:1,onMouseDown:go(info.compressedTo.id),children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2192 compressed to "}),$jsx("span",{fg:theme.accent,children:info.compressedTo.title||info.compressedTo.id})]})}):null,subs2>0?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:" \u2387 spawned "}),$jsx("span",{fg:theme.text,children:String(subs2)}),$jsx("span",{fg:theme.textMuted,children:` subagent${subs2===1?"":"s"}`})]})}):null]}):null,lineageErr?$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:lineageErr})}):null,!d2?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"(no local detail \u2014 state.db mismatch)"})})]}):null,$jsx("box",{height:1})]}),$jsx(Peek,{sid:r.id,total:r.message_count,peek:props.peek})]})})}),SearchDetail=import_react58.memo((props)=>{let theme=useTheme().theme,r=props.result,parts2=[],rest=r.snippet;while(rest.length){let start=rest.indexOf(">>>");if(start<0){parts2.push({text:rest,hi:!1});break}if(start>0)parts2.push({text:rest.slice(0,start),hi:!1});let end=rest.indexOf("<<<",start+3);if(end<0){parts2.push({text:rest.slice(start+3),hi:!0});break}parts2.push({text:rest.slice(start+3,end),hi:!0}),rest=rest.slice(end+3)}return $jsx(TabShell,{title:"Search Match",grow:2,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:r.title??"Untitled"})})})}),$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Source",badge(r.source)],["Model",r.model??"\u2014"],["Time",when(r.started_at)]]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Snippet"})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:parts2.map((p,i)=>p.hi?$jsx("span",{fg:theme.accent,children:$jsx("strong",{children:p.text})},i):$jsx("span",{fg:theme.text,children:p.text},i))})})]})})})}),HeaderRow=import_react58.memo((props)=>{let theme=useTheme().theme,fg2=theme.textMuted,on=theme.accent,by=props.sort;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:8,fg:by==="started"?on:fg2,bold:!0,onClick:()=>props.onSort("started"),children:by==="started"?"Start \u25BE":"Start"}),$jsx(Col,{w:10,fg:by==="active"?on:fg2,bold:!0,right:!0,onClick:()=>props.onSort("active"),children:by==="active"?"Active \u25BE":"Active"}),$jsx(Col,{w:7,fg:fg2,bold:!0,right:!0,children:"Msgs"}),$jsx("box",{width:3})]})}),Item=import_react58.memo((props)=>{let theme=useTheme().theme,{row:r,idx:i}=props,[x2,setX]=import_react58.useState(!1),active=r.detail?.last_active??r.detail?.ended_at??null,locked=props.locked||props.indent||Boolean(r.live),subs2=!props.indent&&(r.detail?.subagent_count??0)>0,leader=props.indent?"\u2514\u2500":props.selected?"\u25B8 ":" ",muted=props.indent&&!props.selected?theme.textMuted:void 0;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:muted??theme.text,children:leader}),$jsx(Marquee,{grow:!0,active:props.selected,fg:props.selected?theme.accent:muted??theme.text,bold:props.selected,underline:props.selected&&subs2,children:label(r)}),$jsx(Col,{w:9,fg:muted??theme.info,children:badge(src(r))}),$jsx(Col,{w:8,fg:theme.textMuted,children:stamp(r.started_at)}),$jsx(Col,{w:10,fg:theme.textMuted,right:!0,children:active?ago(active):"\u2014"}),$jsx(Col,{w:7,fg:theme.textMuted,right:!0,children:subs2?`${r.detail?.subagent_count} subs`:String(r.message_count)}),locked?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{children:$jsx("span",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})})]})}),SearchHeaderRow=import_react58.memo(()=>{let fg2=useTheme().theme.textMuted;return $jsxs(Hdr,{children:[$jsx(Col,{w:2,fg:fg2,children:" "}),$jsx(Col,{grow:!0,fg:fg2,bold:!0,children:"Title"}),$jsx(Col,{w:9,fg:fg2,bold:!0,children:"Source"}),$jsx(Col,{w:10,fg:fg2,bold:!0,children:"When"}),$jsx(Col,{w:20,fg:fg2,bold:!0,children:"Model"})]})}),SearchItem=import_react58.memo((props)=>{let theme=useTheme().theme,{result:r,idx:i}=props;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseDown:()=>props.onActivate(i),onMouseMove:()=>props.onHover(i),children:[$jsx(Col,{w:2,fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "}),$jsx(Col,{grow:!0,fg:props.selected?theme.accent:theme.text,bold:props.selected,children:r.title??"Untitled"}),$jsx(Col,{w:9,fg:theme.info,children:badge(r.source)}),$jsx(Col,{w:10,fg:theme.textMuted,children:ago(r.started_at)}),$jsx(Col,{w:20,fg:theme.textMuted,children:r.model??"\u2014"})]})}),last={rows:[],kids:new Map},Sessions=import_react58.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),cached2=props.io==null,io2=import_react58.useMemo(()=>({list:props.io?.list??io.roots,search:props.io?.search??io.search,subagents:props.io?.subagents??io.children,lineage:props.io?.lineage??io.lineage,peek:props.io?.peek??io.peek,remove:props.io?.remove??exports_sessions_db.remove,rename:props.io?.rename??exports_sessions_db.rename}),[props.io]),[rows2,setRows]=import_react58.useState(cached2?last.rows:[]),[liveRows,setLiveRows]=import_react58.useState([]),[warn,setWarn]=import_react58.useState(""),[searchErr,setSearchErr]=import_react58.useState(""),[pending3,setPending]=import_react58.useState(rows2.length===0),sort=exports_preferences.usePref("sessions")?.sort??"active",setSort=import_react58.useCallback((s)=>exports_preferences.set("sessions",{sort:s}),[]),[view,setView]=import_react58.useState(HOME4),active=import_react58.useMemo(()=>[...liveRows].sort((a,b2)=>Number(Boolean(b2.live?.current))-Number(Boolean(a.live?.current))||(b2.live?.last_active??b2.started_at)-(a.live?.last_active??a.started_at)),[liveRows]),ids=import_react58.useMemo(()=>new Set(active.flatMap((r)=>[r.id,r.live?.session_key].filter((x2)=>Boolean(x2)))),[active]),sorted=import_react58.useMemo(()=>rows2.filter((r)=>!ids.has(r.id)).sort(cmp(sort)),[rows2,ids,sort]),views=import_react58.useMemo(()=>{let stats=sorted.reduce((m2,r)=>{let s=src(r);if(!s)return m2;let prev=m2.get(s);return m2.set(s,{count:(prev?.count??0)+1,last:Math.max(prev?.last??0,tick2(r))}),m2},new Map),conv=sorted.filter((r)=>src(r)!=="cron").length;return[...conv>0?[{id:HOME4,label:"Conversations",count:conv,aggregate:"conversations"}]:[],...[...stats.entries()].sort((a,b2)=>b2[1].last-a[1].last||badge(a[0]).localeCompare(badge(b2[0]))).map(([source,stat2])=>({id:sid(source),label:badge(source),count:stat2.count,source}))]},[sorted]),cur=views.find((v2)=>v2.id===view)??views[0],chosen=cur?.id??view,hist=import_react58.useMemo(()=>{if(!cur)return[];if(cur.aggregate===HOME4)return sorted.filter((r)=>src(r)!=="cron");return sorted.filter((r)=>src(r)===cur.source)},[sorted,cur]),listed=import_react58.useMemo(()=>[...active,...hist],[active,hist]);import_react58.useEffect(()=>{if(views.length>0&&!views.some((v2)=>v2.id===view))setView(views[0].id)},[views,view]);let[anchor,setAnchor]=import_react58.useState(null),[open2,setOpen]=import_react58.useState(null),[searching,setSearching]=import_react58.useState(!1),[query,setQuery]=import_react58.useState(""),[results,setResults]=import_react58.useState([]),[searchSel,setSearchSel]=import_react58.useState(0),[kids,setKids]=import_react58.useState(cached2?last.kids:new Map),debounce=import_react58.useRef(null),searchGen=import_react58.useRef(0),vscroll=import_react58.useRef(null),seen=import_react58.useRef(!1),gen=import_react58.useRef(0),anchored=anchor&&listed.find((r)=>r.id===anchor.id),branch2=open2?listed.find((r)=>r.id===open2):void 0,owner=branch2&&(anchor?.indent?kids.get(branch2.id)?.some((c)=>c.id===anchor.id):anchored?.id===branch2.id)?branch2:void 0,showDetailPanel=dims.width>=120,visible2=listed.flatMap((r,i)=>r.id===owner?.id?[{row:r,indent:!1,parentIdx:i},...(kids.get(r.id)??[]).map((c)=>({row:c,indent:!0,parentIdx:i}))]:[{row:r,indent:!1,parentIdx:i}]),sel=anchor?Math.max(0,visible2.findIndex((v2)=>v2.row.id===anchor.id&&v2.indent===anchor.indent)):0,live=import_react58.useRef({rows:listed,visible:visible2,anchor,results,searching,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId});live.current={rows:listed,visible:visible2,anchor,results,searching,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId};let setSel=import_react58.useCallback((arg)=>{let cur2=live.current,prev=cur2.visible.findIndex((v3)=>v3.row.id===cur2.anchor?.id&&v3.indent===cur2.anchor.indent),n=typeof arg==="function"?arg(Math.max(0,prev)):arg,v2=cur2.visible[Math.max(0,Math.min(cur2.visible.length-1,n))];if(v2)setAnchor({id:v2.row.id,indent:v2.indent})},[]),LIMIT=2000,keep=(d2)=>d2.message_count>0||d2.lineage_root_id!=null,toRow2=(d2)=>({id:d2.id,title:d2.title??"",preview:d2.lastMessage??"",message_count:d2.message_count,started_at:d2.started_at,source:d2.sessionSource,detail:d2}),toLiveRow=(s,d2,r)=>({id:s.id,title:s.title?.trim()||d2?.title||"",preview:s.preview??"",message_count:s.message_count??d2?.message_count??r?.message_count??0,started_at:s.started_at??d2?.started_at??r?.started_at??s.last_active??0,source:d2?.sessionSource??r?.source??s.source??"",detail:d2,live:s}),pick=(m2,s)=>m2.get(s.id)??m2.get(s.session_key??""),patchTitle=import_react58.useCallback((id,title)=>{if(!id||title===void 0)return;home3.update("recentSessions",(rows3)=>rows3.map((r)=>r.id===id?{...r,title}:r)),setRows((prev)=>prev.map((row3)=>row3.id===id?{...row3,title,detail:row3.detail?{...row3.detail,title}:row3.detail}:row3)),setLiveRows((prev)=>prev.map((row3)=>row3.id===id||row3.live?.session_key===id?{...row3,title,live:row3.live?{...row3.live,title}:row3.live}:row3))},[]);useGatewayEvent((ev)=>{if(ev.type==="session.title")patchTitle(ev.payload.session_id,ev.payload.title)});let load4=import_react58.useCallback(async()=>{let current=++gen.current;setPending(!0);let rpc=gw.request("session.list",{limit:LIMIT}).then((r2)=>({ok:!0,v:r2})).catch((e)=>({ok:!1,e})),active2=gw.request("session.active_list",{current_session_id:props.currentId}).then((r2)=>({ok:!0,v:r2})).catch((e)=>({ok:!1,e})),disk=await Promise.resolve(io2.list(LIMIT)).catch(()=>[]);if(gen.current!==current)return;let local=new Map(disk.map((r2)=>[r2.id,r2])),diskRows=disk.filter(keep).map(toRow2);if(setRows(diskRows),cached2)last.rows=diskRows;let[a,r]=await Promise.all([active2,rpc]);if(gen.current!==current)return;let live2=a.ok?a.v.sessions??[]:[];if(a.ok)setLiveRows(live2.map((s)=>toLiveRow(s,pick(local,s))));let final=diskRows;if(r.ok&&r.v.sessions?.length){let seen2=new Set(diskRows.map((s)=>s.id)),merged=[...diskRows,...r.v.sessions.filter((s)=>(s.message_count??0)>0&&!seen2.has(s.id)).map((s)=>({...s,detail:local.get(s.id)}))];if(final=merged,setRows(merged),cached2)last.rows=merged;let found=new Map(merged.map((s)=>[s.id,s]));if(live2.length)setLiveRows(live2.map((s)=>toLiveRow(s,pick(local,s),pick(found,s))))}let kidsError="";try{let parents=final.filter((row3)=>(row3.detail?.subagent_count??0)>0),children2=[];for(let i=0;i<parents.length;i+=8)if(children2.push(...await Promise.all(parents.slice(i,i+8).map((row3)=>io2.subagents(row3.id)))),gen.current!==current)return;if(gen.current!==current)return;let next=new Map(parents.map((row3,i)=>[row3.id,children2[i].map(toRow2)]));if(setKids(next),cached2)last.kids=next}catch(err){kidsError=err instanceof Error?err.message:String(err)}if(gen.current!==current)return;setPending(!1);let listError=!r.ok?local.size?`gateway session.list failed (${r.e.message}) \u2014 listing state.db directly; rows may not resume`:r.e.message:"";setWarn([listError,kidsError].filter(Boolean).join(" \xB7 "))},[gw,props.currentId,io2,cached2]);import_react58.useEffect(()=>{load4()},[load4]),import_react58.useEffect(()=>()=>{gen.current++},[]),import_react58.useEffect(()=>{let on=active.length>0,fresh=on&&!seen.current;if(!listed.length){seen.current=on;return}if(!anchor||!visible2.some((v2)=>v2.row.id===anchor.id&&v2.indent===anchor.indent)){setAnchor({id:listed[0].id,indent:!1}),seen.current=on;return}if(fresh&&active[0]&&hist[0]?.id===anchor.id&&!anchor.indent)setAnchor({id:active[0].id,indent:!1});seen.current=on},[listed,active,hist,anchor]),import_react58.useEffect(()=>{let current=++searchGen.current;if(setSearchErr(""),!searching||!query.trim()){setResults([]);return}return setResults([]),setSearchSel(0),debounce.current=setTimeout(()=>{Promise.resolve(io2.search(query,30)).then((r)=>{if(searchGen.current!==current)return;setResults(r),setSearchSel(0),setSearchErr("")}).catch((err)=>{if(searchGen.current===current)setSearchErr(err instanceof Error?err.message:String(err))})},150),()=>{if(debounce.current)clearTimeout(debounce.current)}},[query,searching,io2]);let rowHover=import_react58.useCallback((i)=>{live.current.searching?setSearchSel(i):setSel(i)},[setSel]),rowActivate=import_react58.useCallback((i)=>{let l=live.current;l.searching?setSearchSel(i):setSel(i);let hit=l.searching?l.results[i]:l.visible[i]?.row,id=l.searching?hit?.session_id:hit?.id;if(!id)return;if(!l.searching&&hit?.live){if(l.onActivateLive)return l.onActivateLive(id);return l.onSwitch?.(id)}if(!l.onSwitch)return;if(id===l.currentId)return l.onSwitch(id);let title=hit?.title||"Untitled",n=l.searching?void 0:hit.message_count;openConfirm(dialog,{title:"Load session?",body:`${trunc5(title,60)}${n!=null?` \xB7 ${n} msg${n===1?"":"s"}`:""}
4090
4090
 
4091
4091
  Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(id)})},[dialog]),rowDelete=import_react58.useCallback((i)=>{let v2=live.current.visible[i];if(v2&&!v2.indent&&!v2.row.live&&v2.row.id!==live.current.currentId)confirmDeleteRef.current(v2.row)},[]),lineageSwitch=import_react58.useCallback((sid2)=>{let l=live.current;if(!l.onSwitch)return;if(sid2===l.currentId)return l.onSwitch(sid2);openConfirm(dialog,{title:"Load session?",body:`Switch to ${trunc5(sid2,24)}?
4092
4092
 
4093
- Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(sid2)})},[dialog]),confirmDeleteRef=import_react58.useRef(()=>{}),confirmDelete=import_react58.useCallback((r)=>{openConfirm(dialog,{title:"Delete Session?",body:trunc5(label(r),46),yes:"Delete",danger:!0}).then(async(ok)=>{if(!ok)return;if(!await gw.request("session.delete",{session_id:r.id}).then(()=>!0).catch((e)=>{if(/cannot delete an active session/i.test(e.message))return toast.show({variant:"error",message:"Can't delete the active session"}),!1;if(/method not found|unknown method|gateway not running|gateway exited/i.test(e.message))return io2.remove(r.id);return toast.show({variant:"error",message:e.message}),!1}))return;home3.invalidate("recentSessions"),toast.show({variant:"success",message:"Session deleted"}),load4()})},[gw,dialog,toast,load4]);confirmDeleteRef.current=confirmDelete;let rename2=import_react58.useCallback(async()=>{let v2=live.current.visible[sel];if(!v2||v2.indent)return;let r=v2.row,name=await openTextPrompt(dialog,{title:`Rename: ${trunc5(label(r),42)}`,label:"Title",initial:r.title||""});if(name===null)return;Promise.resolve().then(async()=>{let title=r.live?(await gw.request("session.title",{session_id:r.id,title:name})).title??name:name;if(!r.live&&!io2.rename(r.id,title))throw Error("not found");let ids2=[r.id,r.live?.session_key].filter((id)=>Boolean(id));home3.invalidate("recentSessions"),ids2.forEach((id)=>patchTitle(id,title)),toast.show({variant:"success",message:"Renamed"})}).catch((e)=>toast.show({variant:"error",message:`Rename failed: ${e.message}`}))},[gw,dialog,toast,sel,patchTitle]),toggle=import_react58.useCallback(()=>{let v2=visible2[sel];if(!v2)return;if(v2.indent){let p=listed.find((r)=>kids.get(r.id)?.some((c)=>c.id===v2.row.id));if(!p)return;setAnchor({id:p.id,indent:!1}),setOpen(null);return}if((v2.row.detail?.subagent_count??0)<=0)return;setOpen((id)=>id===v2.row.id?null:v2.row.id)},[visible2,sel,listed,kids]),count3=searching?results.length:visible2.length,rowId=(i)=>{if(searching)return`sess-s-${results[i]?.session_id??i}`;let v2=visible2[i];return v2?`sess-${v2.indent?"c":"p"}-${v2.row.id}`:`sess-empty-${i}`},keys=useKeys();useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(searching){if(key3.name==="escape"){setSearching(!1),setQuery(""),setResults([]),setSearchSel(0);return}if(key3.name==="backspace")return setQuery((p)=>p.slice(0,-1));if(key3.name==="return")return rowActivate(searchSel);if(key3.name==="up")return setSearchSel((p)=>Math.max(0,p-1));if(key3.name==="down")return setSearchSel((p)=>Math.min(count3-1,p+1));if(key3.raw&&key3.raw.length===1&&key3.raw>=" ")return setQuery((p)=>p+key3.raw);return}if(handleListKey(keys,key3,{count:count3,setSel,page:Math.max(1,(vscroll.current?.viewport.height??10)-1),scrollTo:(n)=>vscroll.current?.scrollChildIntoView(rowId(n)),onActivate:()=>rowActivate(sel),onToggle:toggle,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})},onDelete:()=>{let v2=visible2[sel];if(v2&&!v2.indent&&!v2.row.live&&v2.row.id!==props.currentId)confirmDelete(v2.row)},onSearch:()=>{setSearching(!0),setQuery(""),setResults([]),setSearchSel(0)}}))return;if(keys.match("sessions.sort",key3))return setSort(sort==="active"?"started":"active");if(keys.match("sessions.rename",key3))return void rename2();let prev=keys.match("sessions.prev",key3),next=keys.match("sessions.next",key3);if(prev||next){if(views.length<2)return;let dir=prev?-1:1;setView((v2)=>{let list2=views.map((x2)=>x2.id),i=list2.indexOf(v2);return list2[((i<0?0:i)+dir+list2.length)%list2.length]});return}});let empty=searching?results.length===0&&query.length>0:active.length===0&&sorted.length===0,action=visible2[sel]?.row.live?"activate live":"switch",top=(i)=>Boolean(visible2[i]?.row.live&&(i===0||!visible2[i-1]?.row.live)),tabs=(i)=>Boolean(views.length>0&&hist[0]&&!visible2[i]?.indent&&visible2[i]?.row.id===hist[0].id),gap=(i)=>active.length>0&&tabs(i),blank=cur?.aggregate===HOME4?"No conversations found":cur?`No ${cur.label} sessions found`:"No sessions found",nav=views.length>1?[["\u2190\u2192","filter"]]:[],sub2=visible2[sel]?.indent||(visible2[sel]?.row.detail?.subagent_count??0)>0?[[keys.print("list.toggle"),visible2[sel]?.indent||open2===visible2[sel]?.row.id?"hide subs":"show subs"]]:[];return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs(TabShell,{title:searching?`Search Results (${results.length})`:`Sessions (${listed.length}${pending3?"\u2026":""})`,error:[warn,searchErr].filter(Boolean).join(" \xB7 ")||null,grow:3,children:[searching?$jsx("box",{height:1,marginBottom:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"/ "}),$jsx("span",{fg:theme.text,children:query}),$jsx("span",{fg:theme.accent,children:"\u2588"})]})}):null,empty?$jsx("box",{flexGrow:1,padding:2,children:pending3&&!searching?$jsx(Spinner,{color:theme.textMuted,label:"loading sessions\u2026"}):$jsx("text",{fg:theme.textMuted,children:searching?"No matching sessions found":"No sessions found"})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[searching?$jsx(SearchHeaderRow,{}):$jsx(HeaderRow,{sort,onSort:setSort}),$jsx("box",{height:1}),$jsxs("scrollbox",{ref:vscroll,scrollY:!0,viewportCulling:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:[searching?results.map((r,i)=>$jsx(SearchItem,{id:rowId(i),idx:i,result:r,selected:i===searchSel,onActivate:rowActivate,onHover:rowHover},r.session_id)):visible2.map((v2,i)=>$jsxs("box",{flexDirection:"column",height:1+(top(i)?1:0)+(tabs(i)?2:0)+(gap(i)?1:0),children:[top(i)?$jsx("box",{height:1,paddingLeft:2,children:$jsx("text",{fg:theme.primary,children:active.length===1?"Active Session":"Active Sessions"})}):null,gap(i)?$jsx("box",{height:1}):null,tabs(i)?$jsxs($Fragment,{children:[$jsx(FilterRow,{views,view:chosen,setView}),$jsx("box",{height:1})]}):null,$jsx(Item,{id:rowId(i),idx:i,row:v2.row,selected:i===sel,indent:v2.indent,locked:v2.row.id===props.currentId,onActivate:rowActivate,onHover:rowHover,onDelete:rowDelete})]},`${v2.row.id}-${v2.indent?"c":"p"}`)),!searching&&views.length>0&&hist.length===0?$jsxs("box",{flexDirection:"column",height:3+(active.length>0?1:0),children:[active.length>0?$jsx("box",{height:1}):null,$jsx(FilterRow,{views,view:chosen,setView}),$jsx("box",{height:1}),$jsx("box",{height:1,paddingLeft:2,children:$jsx("text",{fg:theme.textMuted,children:blank})})]},"sessions-empty-filter"):null]})]},"table")]}),showDetailPanel&&searching&&results[searchSel]?$jsx(SearchDetail,{result:results[searchSel]}):showDetailPanel&&!searching&&visible2[sel]?.row?$jsx(Detail,{row:visible2[sel].row,lineage:io2.lineage,peek:io2.peek,onSwitch:lineageSwitch},visible2[sel].row.id):null]}),$jsx(HintBar,{pairs:searching?[["\u2191\u2193","navigate"],["Enter/click","switch"],["Esc","cancel"]]:[["\u2191\u2193","navigate"],...nav,...sub2,[`${keys.print("list.activate")}/click`,action],[keys.print("list.search"),"search"],[keys.print("sessions.sort"),`sort: ${sort}`],[keys.print("sessions.rename"),"rename"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react61=__toESM(require_react_production(),1);var GRID=256,CPT=4,MEMORY_IDS=new Set(["soul","memory","user","mem0"]),SYSTEM_PROMPT_IDS=new Set(["project","meta","other"]);function parse4(text4){if(!text4)return[];let sections=[],used=Array(text4.length).fill(!1),mark2=(start2,end,id,label2,source)=>{let slice=text4.slice(start2,end);if(slice.trim().length===0)return;for(let i=start2;i<end;i++)used[i]=!0;sections.push({id,label:label2,chars:slice.length,tokens:count2(slice),text:slice,source})},bar1=text4.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550");if(bar1>0)mark2(0,bar1,"soul","SOUL.md",makeSource("SOUL.md"));let memH=text4.indexOf("MEMORY (your personal notes)");if(memH>=0){let s=text4.lastIndexOf("\u2550\u2550\u2550\u2550\u2550\u2550",memH),after=text4.indexOf(`
4093
+ Current chat will be replaced.`,yes:"load"}).then((ok)=>{if(ok)l.onSwitch?.(sid2)})},[dialog]),confirmDeleteRef=import_react58.useRef(()=>{}),confirmDelete=import_react58.useCallback((r)=>{openConfirm(dialog,{title:"Delete Session?",body:trunc5(label(r),46),yes:"Delete",danger:!0}).then(async(ok)=>{if(!ok)return;if(!await gw.request("session.delete",{session_id:r.id}).then(()=>!0).catch((e)=>{if(/cannot delete an active session/i.test(e.message))return toast.show({variant:"error",message:"Can't delete the active session"}),!1;if(fallback(e.message))return io2.remove(r.id);return toast.show({variant:"error",message:e.message}),!1}))return;home3.invalidate("recentSessions"),toast.show({variant:"success",message:"Session deleted"}),load4()})},[gw,dialog,toast,load4]);confirmDeleteRef.current=confirmDelete;let rename2=import_react58.useCallback(async()=>{let v2=live.current.visible[sel];if(!v2||v2.indent)return;let r=v2.row,name=await openTextPrompt(dialog,{title:`Rename: ${trunc5(label(r),42)}`,label:"Title",initial:r.title||""});if(name===null)return;Promise.resolve().then(async()=>{let title=r.live?(await gw.request("session.title",{session_id:r.id,title:name})).title??name:name;if(!r.live&&!io2.rename(r.id,title))throw Error("not found");let ids2=[r.id,r.live?.session_key].filter((id)=>Boolean(id));home3.invalidate("recentSessions"),ids2.forEach((id)=>patchTitle(id,title)),toast.show({variant:"success",message:"Renamed"})}).catch((e)=>toast.show({variant:"error",message:`Rename failed: ${e.message}`}))},[gw,dialog,toast,sel,patchTitle]),toggle=import_react58.useCallback(()=>{let v2=visible2[sel];if(!v2)return;if(v2.indent){let p=listed.find((r)=>kids.get(r.id)?.some((c)=>c.id===v2.row.id));if(!p)return;setAnchor({id:p.id,indent:!1}),setOpen(null);return}if((v2.row.detail?.subagent_count??0)<=0)return;setOpen((id)=>id===v2.row.id?null:v2.row.id)},[visible2,sel,listed,kids]),count3=searching?results.length:visible2.length,rowId=(i)=>{if(searching)return`sess-s-${results[i]?.session_id??i}`;let v2=visible2[i];return v2?`sess-${v2.indent?"c":"p"}-${v2.row.id}`:`sess-empty-${i}`},keys=useKeys();useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(searching){if(key3.name==="escape"){setSearching(!1),setQuery(""),setResults([]),setSearchSel(0);return}if(key3.name==="backspace")return setQuery((p)=>p.slice(0,-1));if(key3.name==="return")return rowActivate(searchSel);if(key3.name==="up")return setSearchSel((p)=>Math.max(0,p-1));if(key3.name==="down")return setSearchSel((p)=>Math.min(count3-1,p+1));if(key3.raw&&key3.raw.length===1&&key3.raw>=" ")return setQuery((p)=>p+key3.raw);return}if(handleListKey(keys,key3,{count:count3,setSel,page:Math.max(1,(vscroll.current?.viewport.height??10)-1),scrollTo:(n)=>vscroll.current?.scrollChildIntoView(rowId(n)),onActivate:()=>rowActivate(sel),onToggle:toggle,onRefresh:()=>{load4(),toast.show({variant:"info",message:"Reloaded",duration:1000})},onDelete:()=>{let v2=visible2[sel];if(v2&&!v2.indent&&!v2.row.live&&v2.row.id!==props.currentId)confirmDelete(v2.row)},onSearch:()=>{setSearching(!0),setQuery(""),setResults([]),setSearchSel(0)}}))return;if(keys.match("sessions.sort",key3))return setSort(sort==="active"?"started":"active");if(keys.match("sessions.rename",key3))return void rename2();let prev=keys.match("sessions.prev",key3),next=keys.match("sessions.next",key3);if(prev||next){if(views.length<2)return;let dir=prev?-1:1;setView((v2)=>{let list2=views.map((x2)=>x2.id),i=list2.indexOf(v2);return list2[((i<0?0:i)+dir+list2.length)%list2.length]});return}});let empty=searching?results.length===0&&query.length>0:active.length===0&&sorted.length===0,action=visible2[sel]?.row.live?"activate live":"switch",top=(i)=>Boolean(visible2[i]?.row.live&&(i===0||!visible2[i-1]?.row.live)),tabs=(i)=>Boolean(views.length>0&&hist[0]&&!visible2[i]?.indent&&visible2[i]?.row.id===hist[0].id),gap=(i)=>active.length>0&&tabs(i),blank=cur?.aggregate===HOME4?"No conversations found":cur?`No ${cur.label} sessions found`:"No sessions found",nav=views.length>1?[["\u2190\u2192","filter"]]:[],sub2=visible2[sel]?.indent||(visible2[sel]?.row.detail?.subagent_count??0)>0?[[keys.print("list.toggle"),visible2[sel]?.indent||open2===visible2[sel]?.row.id?"hide subs":"show subs"]]:[];return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs(TabShell,{title:searching?`Search Results (${results.length})`:`Sessions (${listed.length}${pending3?"\u2026":""})`,error:[warn,searchErr].filter(Boolean).join(" \xB7 ")||null,grow:3,children:[searching?$jsx("box",{height:1,marginBottom:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.accent,children:"/ "}),$jsx("span",{fg:theme.text,children:query}),$jsx("span",{fg:theme.accent,children:"\u2588"})]})}):null,empty?$jsx("box",{flexGrow:1,padding:2,children:pending3&&!searching?$jsx(Spinner,{color:theme.textMuted,label:"loading sessions\u2026"}):$jsx("text",{fg:theme.textMuted,children:searching?"No matching sessions found":"No sessions found"})},"empty"):$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[searching?$jsx(SearchHeaderRow,{}):$jsx(HeaderRow,{sort,onSort:setSort}),$jsx("box",{height:1}),$jsxs("scrollbox",{ref:vscroll,scrollY:!0,viewportCulling:!0,flexGrow:1,verticalScrollbarOptions:VBAR,children:[searching?results.map((r,i)=>$jsx(SearchItem,{id:rowId(i),idx:i,result:r,selected:i===searchSel,onActivate:rowActivate,onHover:rowHover},r.session_id)):visible2.map((v2,i)=>$jsxs("box",{flexDirection:"column",height:1+(top(i)?1:0)+(tabs(i)?2:0)+(gap(i)?1:0),children:[top(i)?$jsx("box",{height:1,paddingLeft:2,children:$jsx("text",{fg:theme.primary,children:active.length===1?"Active Session":"Active Sessions"})}):null,gap(i)?$jsx("box",{height:1}):null,tabs(i)?$jsxs($Fragment,{children:[$jsx(FilterRow,{views,view:chosen,setView}),$jsx("box",{height:1})]}):null,$jsx(Item,{id:rowId(i),idx:i,row:v2.row,selected:i===sel,indent:v2.indent,locked:v2.row.id===props.currentId,onActivate:rowActivate,onHover:rowHover,onDelete:rowDelete})]},`${v2.row.id}-${v2.indent?"c":"p"}`)),!searching&&views.length>0&&hist.length===0?$jsxs("box",{flexDirection:"column",height:3+(active.length>0?1:0),children:[active.length>0?$jsx("box",{height:1}):null,$jsx(FilterRow,{views,view:chosen,setView}),$jsx("box",{height:1}),$jsx("box",{height:1,paddingLeft:2,children:$jsx("text",{fg:theme.textMuted,children:blank})})]},"sessions-empty-filter"):null]})]},"table")]}),showDetailPanel&&searching&&results[searchSel]?$jsx(SearchDetail,{result:results[searchSel]}):showDetailPanel&&!searching&&visible2[sel]?.row?$jsx(Detail,{row:visible2[sel].row,lineage:io2.lineage,peek:io2.peek,onSwitch:lineageSwitch},visible2[sel].row.id):null]}),$jsx(HintBar,{pairs:searching?[["\u2191\u2193","navigate"],["Enter/click","switch"],["Esc","cancel"]]:[["\u2191\u2193","navigate"],...nav,...sub2,[`${keys.print("list.activate")}/click`,action],[keys.print("list.search"),"search"],[keys.print("sessions.sort"),`sort: ${sort}`],[keys.print("sessions.rename"),"rename"],[keys.print("list.delete"),"delete"],[keys.print("list.refresh"),"refresh"]]})]})});var import_react61=__toESM(require_react_production(),1);var GRID=256,CPT=4,MEMORY_IDS=new Set(["soul","memory","user","mem0"]),SYSTEM_PROMPT_IDS=new Set(["project","meta","other"]);function parse4(text4){if(!text4)return[];let sections=[],used=Array(text4.length).fill(!1),mark2=(start2,end,id,label2,source)=>{let slice=text4.slice(start2,end);if(slice.trim().length===0)return;for(let i=start2;i<end;i++)used[i]=!0;sections.push({id,label:label2,chars:slice.length,tokens:count2(slice),text:slice,source})},bar1=text4.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550");if(bar1>0)mark2(0,bar1,"soul","SOUL.md",makeSource("SOUL.md"));let memH=text4.indexOf("MEMORY (your personal notes)");if(memH>=0){let s=text4.lastIndexOf("\u2550\u2550\u2550\u2550\u2550\u2550",memH),after=text4.indexOf(`
4094
4094
  `,text4.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550",memH+1)),next=text4.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550",after>0?after:memH+40),e=next>0?text4.lastIndexOf(`
4095
4095
  `,next)+1:text4.length;if(s>=0)mark2(s,e,"memory","Memory Notes",makeSource("memories/MEMORY.md","MEMORY.md"))}let userH=text4.indexOf("USER PROFILE (who the user is)");if(userH>=0){let s=text4.lastIndexOf("\u2550\u2550\u2550\u2550\u2550\u2550",userH),after=text4.indexOf(`
4096
4096
  `,text4.indexOf("\u2550\u2550\u2550\u2550\u2550\u2550",userH+1)),next=text4.slice(after>0?after:userH+40).search(/\n#\s/),e=next>=0?(after>0?after:userH+40)+next+1:text4.length;if(s>=0)mark2(s,e,"user","User Profile",makeSource("memories/USER.md","USER.md"))}let m0=text4.indexOf("# Mem0 Memory");if(m0>=0){let next=text4.slice(m0+1).search(/\n##?\s/);mark2(m0,next>=0?m0+1+next+1:text4.length,"mem0","Mem0 Memory")}let skH=text4.indexOf("## Skills (mandatory)"),skE=text4.indexOf("</available_skills>");if(skH>=0&&skE>=0){let end=text4.indexOf(`
4097
4097
  `,skE);while(end<text4.length&&end>=0){let nl=text4.indexOf(`
4098
4098
  `,end+1);if(nl<0){end=text4.length;break}let line2=text4.slice(end+1,nl).trim();if(line2.startsWith("#"))break;if(line2===""){if(text4.slice(nl+1,text4.indexOf(`
4099
- `,nl+1)).trim().startsWith("#")){end=nl;break}}end=nl}mark2(skH,end+1,"skills","Skills Catalog",makeSource("skills","skills/"))}let proj=text4.indexOf("# Project Context");if(proj>=0){let conv2=text4.indexOf("Conversation started:");mark2(proj,conv2>proj?conv2:text4.length,"project","Project Context",makeSource("AGENTS.md"))}let conv=text4.indexOf("Conversation started:");if(conv>=0)mark2(conv,text4.length,"meta","Session Metadata");let start=-1;for(let i=0;i<=text4.length;i++)if(i<text4.length&&!used[i]){if(start<0)start=i}else if(start>=0){let slice=text4.slice(start,i);if(slice.trim().length>0)sections.push({id:"other",label:"Other",chars:slice.length,tokens:count2(slice),text:slice});start=-1}return sections.sort((a,b2)=>text4.indexOf(a.text)-text4.indexOf(b2.text))}function classifyTools(tools){let system=[],mcp=[];for(let t2 of tools)if(t2.name.startsWith("mcp_"))mcp.push(t2);else system.push(t2);return{system,mcp}}function toolTokens(tool){return Math.ceil((tool.descriptionLength+tool.paramsLength)/CPT)}function build(opts){let pct=(t2)=>opts.contextLength>0?t2/opts.contextLength*100:0,result=[],byId2=new Map;for(let s of opts.sections)byId2.set(s.id,s);let promptChildren=opts.sections.filter((sec)=>SYSTEM_PROMPT_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),promptTok=promptChildren.reduce((s,c)=>s+c.tokens,0);if(promptTok>0)result.push({id:"system_prompt",label:"System Prompt",tokens:promptTok,percent:pct(promptTok),children:promptChildren});let{system:sysTools,mcp:mcpTools}=classifyTools(opts.tools),sysToolsTok=sysTools.reduce((s,t2)=>s+toolTokens(t2),0);if(sysToolsTok>0)result.push({id:"system_tools",label:"System Tools",tokens:sysToolsTok,percent:pct(sysToolsTok)});let mcpToolsTok=mcpTools.reduce((s,t2)=>s+toolTokens(t2),0);if(mcpToolsTok>0)result.push({id:"mcp_tools",label:"MCP Tools",tokens:mcpToolsTok,percent:pct(mcpToolsTok)});let memChildren=opts.sections.filter((sec)=>MEMORY_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),memTok=memChildren.reduce((s,c)=>s+c.tokens,0);if(memTok>0)result.push({id:"memory",label:"Memory",tokens:memTok,percent:pct(memTok),children:memChildren});let skillsSec=byId2.get("skills"),skillsTok=skillsSec?.tokens??opts.skillsTokens??0;if(skillsTok>0)result.push({id:"skills",label:"Skills",tokens:skillsTok,percent:pct(skillsTok),section:skillsSec});if(opts.conversationTokens>0){let ct=opts.conversationTokens;result.push({id:"conversation",label:"~Conversation",tokens:ct,percent:pct(ct)})}let taken=result.reduce((s,g)=>s+g.tokens,0),used=opts.usedTokens;if(typeof used!=="number"){let unknown2=Math.max(0,opts.contextLength-taken);if(unknown2>0)result.push({id:"unknown",label:"Unknown (live unavailable)",tokens:unknown2,percent:pct(unknown2)});return result}let unknown=Math.max(0,used-taken);if(unknown>0)result.push({id:"unknown",label:"Unknown / Provider Overhead",tokens:unknown,percent:pct(unknown)});let overage=Math.max(0,taken-used);if(overage>0)result.push({id:"overage",label:"Estimate Overage",tokens:overage,percent:pct(overage)});let free=Math.max(0,opts.contextLength-used);return result.push({id:"free",label:"Free",tokens:free,percent:pct(free)}),result}function drill(group2){if(!group2.children||group2.children.length===0)return[];let total=group2.tokens;return group2.children.map((c)=>({...c,percent:total>0?c.tokens/total*100:0}))}function cells(segments,fallback="free"){let filled=segments.flatMap((seg)=>Array.from({length:Math.round(seg.percent/100*GRID)},()=>({id:seg.id}))),pad=Array.from({length:Math.max(0,GRID-filled.length)},()=>({id:fallback}));return[...filled,...pad].slice(0,GRID)}var import_react60=__toESM(require_react_production(),1);var FileLink=import_react60.memo(({source,children:children2})=>{let theme=useTheme().theme,[hovered,setHovered]=import_react60.useState(!1);return $jsx("box",{height:1,onMouseDown:()=>openFile(source.file),onMouseOver:()=>setHovered(!0),onMouseOut:()=>setHovered(!1),children:$jsx("text",{fg:theme.info,attributes:hovered?TextAttributes.UNDERLINE:TextAttributes.NONE,children:children2??source.label})})}),KVLink=(props)=>{let theme=useTheme().theme;return $jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:props.label})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx(FileLink,{source:props.source,children:props.text??props.source.label})})]})};var GOLDEN_ANGLE=137.50776405003785;function luminance(c){return 0.299*c.r+0.587*c.g+0.114*c.b}function rgbaToHsl(c){let{r,g,b:b2}=c,max=Math.max(r,g,b2),min=Math.min(r,g,b2),l=(max+min)/2,d2=max-min;if(d2===0)return[0,0,l];let s=l>0.5?d2/(2-max-min):d2/(max+min),h2;switch(max){case r:h2=(g-b2)/d2+(g<b2?6:0);break;case g:h2=(b2-r)/d2+2;break;default:h2=(r-g)/d2+4}return[h2*60,s,l]}function hslToRgba(h2,s,l){if(h2=(h2%360+360)%360/360,s===0)return RGBA.fromValues(l,l,l,1);let q3=l<0.5?l*(1+s):l+s-l*s,p=2*l-q3,ch=(t2)=>{if(t2<0)t2+=1;if(t2>1)t2-=1;if(t2<0.16666666666666666)return p+(q3-p)*6*t2;if(t2<0.5)return q3;if(t2<0.6666666666666666)return p+(q3-p)*(0.6666666666666666-t2)*6;return p};return RGBA.fromValues(ch(h2+0.3333333333333333),ch(h2),ch(h2-0.3333333333333333),1)}function categorical(seed,bg2,n){let[h0]=rgbaToHsl(seed),dark=luminance(bg2)<0.5,s=dark?0.6:0.7,l=dark?0.62:0.42,out=[];for(let i=0;i<n;i++)out.push(hslToRgba(h0+i*GOLDEN_ANGLE,s,l));return out}var DEFAULT_CTX=128000,COLS2=16,SLOTS2=["system_prompt","system_tools","mcp_tools","memory","skills","conversation","soul","mem0","user","project","meta","other","unknown","overage"],SLOT=Object.fromEntries(SLOTS2.map((id,i)=>[id,i])),REMOTE={tool_definitions:"system_tools",mcp:"mcp_tools",rules:"system_prompt",subagent_definitions:"system_tools"},ORDER2=["system_prompt","system_tools","mcp_tools","memory","skills","conversation"],LABEL2={system_prompt:"System Prompt",system_tools:"System Tools",mcp_tools:"MCP Tools",memory:"Memory",skills:"Skills",conversation:"Conversation"},rampCache=new WeakMap;function ramp2(theme){let r=rampCache.get(theme);if(!r)rampCache.set(theme,r=categorical(theme.primary,theme.background,SLOTS2.length));return r}function clr(id,theme){if(id==="free")return theme.borderSubtle;return ramp2(theme)[SLOT[id]??SLOT.other]}var fmt2=(n)=>{if(n>=1e6)return`${(n/1e6).toFixed(1)}M`;if(n>=1e4)return`${Math.round(n/1000)}k`;if(n>=1000)return`${(n/1000).toFixed(1)}k`;return String(n)},est=(s)=>s?count2(s):0,bar=(pct,w2=20)=>{let f=Math.round(Math.max(0,Math.min(100,pct))/100*w2);return`[${"\u2588".repeat(f)}${"\u2591".repeat(Math.max(0,w2-f))}]`},SectionPanel=import_react61.memo(({seg,theme})=>{let{syntaxStyle}=useTheme(),sec=seg.section;if(!sec)return null;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsxs("text",{children:[sec.chars.toLocaleString()," chars \xB7 ~",fmt2(sec.tokens)," tokens"]}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsx("markdown",{content:sec.text,fg:theme.markdownText,syntaxStyle})]})}),MemoryPanel=import_react61.memo(({seg,theme,label:label2,chars,limit,pct,entries:entries2,source})=>$jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:$jsx("strong",{children:label2})}),source?$jsxs($Fragment,{children:[$jsx("text",{children:" ("}),$jsx(FileLink,{source}),$jsx("text",{children:")"})]}):null]}),$jsxs("text",{children:[chars.toLocaleString()," / ",limit.toLocaleString()," chars (",pct,"%)"]}),$jsxs("text",{children:[bar(pct,25),pct>=95?" \u26A0 near limit":""]}),$jsx("text",{children:" "}),$jsxs("text",{children:[entries2.length," entries:"]}),entries2.map((e,i)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",e]},i))]})),SkillsPanel=import_react61.memo(({seg,theme})=>{let sec=seg.section;if(!sec)return null;let cats={};for(let line2 of sec.text.split(`
4099
+ `,nl+1)).trim().startsWith("#")){end=nl;break}}end=nl}mark2(skH,end+1,"skills","Skills Catalog",makeSource("skills","skills/"))}let proj=text4.indexOf("# Project Context");if(proj>=0){let conv2=text4.indexOf("Conversation started:");mark2(proj,conv2>proj?conv2:text4.length,"project","Project Context",makeSource("AGENTS.md"))}let conv=text4.indexOf("Conversation started:");if(conv>=0)mark2(conv,text4.length,"meta","Session Metadata");let start=-1;for(let i=0;i<=text4.length;i++)if(i<text4.length&&!used[i]){if(start<0)start=i}else if(start>=0){let slice=text4.slice(start,i);if(slice.trim().length>0)sections.push({id:"other",label:"Other",chars:slice.length,tokens:count2(slice),text:slice});start=-1}return sections.sort((a,b2)=>text4.indexOf(a.text)-text4.indexOf(b2.text))}function classifyTools(tools){let system=[],mcp=[];for(let t2 of tools)if(t2.name.startsWith("mcp_"))mcp.push(t2);else system.push(t2);return{system,mcp}}function toolTokens(tool){return Math.ceil((tool.descriptionLength+tool.paramsLength)/CPT)}function build(opts){let pct=(t2)=>opts.contextLength>0?t2/opts.contextLength*100:0,result=[],byId2=new Map;for(let s of opts.sections)byId2.set(s.id,s);let promptChildren=opts.sections.filter((sec)=>SYSTEM_PROMPT_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),promptTok=promptChildren.reduce((s,c)=>s+c.tokens,0);if(promptTok>0)result.push({id:"system_prompt",label:"System Prompt",tokens:promptTok,percent:pct(promptTok),children:promptChildren});let{system:sysTools,mcp:mcpTools}=classifyTools(opts.tools),sysToolsTok=sysTools.reduce((s,t2)=>s+toolTokens(t2),0);if(sysToolsTok>0)result.push({id:"system_tools",label:"System Tools",tokens:sysToolsTok,percent:pct(sysToolsTok)});let mcpToolsTok=mcpTools.reduce((s,t2)=>s+toolTokens(t2),0);if(mcpToolsTok>0)result.push({id:"mcp_tools",label:"MCP Tools",tokens:mcpToolsTok,percent:pct(mcpToolsTok)});let memChildren=opts.sections.filter((sec)=>MEMORY_IDS.has(sec.id)&&sec.tokens>0).map((sec)=>({id:sec.id,label:sec.label,tokens:sec.tokens,percent:pct(sec.tokens),section:sec})),memTok=memChildren.reduce((s,c)=>s+c.tokens,0);if(memTok>0)result.push({id:"memory",label:"Memory",tokens:memTok,percent:pct(memTok),children:memChildren});let skillsSec=byId2.get("skills"),skillsTok=skillsSec?.tokens??opts.skillsTokens??0;if(skillsTok>0)result.push({id:"skills",label:"Skills",tokens:skillsTok,percent:pct(skillsTok),section:skillsSec});if(opts.conversationTokens>0){let ct=opts.conversationTokens;result.push({id:"conversation",label:"~Conversation",tokens:ct,percent:pct(ct)})}let taken=result.reduce((s,g)=>s+g.tokens,0),used=opts.usedTokens;if(typeof used!=="number"){let unknown2=Math.max(0,opts.contextLength-taken);if(unknown2>0)result.push({id:"unknown",label:"Unknown (live unavailable)",tokens:unknown2,percent:pct(unknown2)});return result}let unknown=Math.max(0,used-taken);if(unknown>0)result.push({id:"unknown",label:"Unknown / Provider Overhead",tokens:unknown,percent:pct(unknown)});let overage=Math.max(0,taken-used);if(overage>0)result.push({id:"overage",label:"Estimate Overage",tokens:overage,percent:pct(overage)});let free=Math.max(0,opts.contextLength-used);return result.push({id:"free",label:"Free",tokens:free,percent:pct(free)}),result}function drill(group2){if(!group2.children||group2.children.length===0)return[];let total=group2.tokens;return group2.children.map((c)=>({...c,percent:total>0?c.tokens/total*100:0}))}function cells(segments,fallback2="free"){let filled=segments.flatMap((seg)=>Array.from({length:Math.round(seg.percent/100*GRID)},()=>({id:seg.id}))),pad=Array.from({length:Math.max(0,GRID-filled.length)},()=>({id:fallback2}));return[...filled,...pad].slice(0,GRID)}var import_react60=__toESM(require_react_production(),1);var FileLink=import_react60.memo(({source,children:children2})=>{let theme=useTheme().theme,[hovered,setHovered]=import_react60.useState(!1);return $jsx("box",{height:1,onMouseDown:()=>openFile(source.file),onMouseOver:()=>setHovered(!0),onMouseOut:()=>setHovered(!1),children:$jsx("text",{fg:theme.info,attributes:hovered?TextAttributes.UNDERLINE:TextAttributes.NONE,children:children2??source.label})})}),KVLink=(props)=>{let theme=useTheme().theme;return $jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:13,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:props.label})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx(FileLink,{source:props.source,children:props.text??props.source.label})})]})};var GOLDEN_ANGLE=137.50776405003785;function luminance(c){return 0.299*c.r+0.587*c.g+0.114*c.b}function rgbaToHsl(c){let{r,g,b:b2}=c,max=Math.max(r,g,b2),min=Math.min(r,g,b2),l=(max+min)/2,d2=max-min;if(d2===0)return[0,0,l];let s=l>0.5?d2/(2-max-min):d2/(max+min),h2;switch(max){case r:h2=(g-b2)/d2+(g<b2?6:0);break;case g:h2=(b2-r)/d2+2;break;default:h2=(r-g)/d2+4}return[h2*60,s,l]}function hslToRgba(h2,s,l){if(h2=(h2%360+360)%360/360,s===0)return RGBA.fromValues(l,l,l,1);let q3=l<0.5?l*(1+s):l+s-l*s,p=2*l-q3,ch=(t2)=>{if(t2<0)t2+=1;if(t2>1)t2-=1;if(t2<0.16666666666666666)return p+(q3-p)*6*t2;if(t2<0.5)return q3;if(t2<0.6666666666666666)return p+(q3-p)*(0.6666666666666666-t2)*6;return p};return RGBA.fromValues(ch(h2+0.3333333333333333),ch(h2),ch(h2-0.3333333333333333),1)}function categorical(seed,bg2,n){let[h0]=rgbaToHsl(seed),dark=luminance(bg2)<0.5,s=dark?0.6:0.7,l=dark?0.62:0.42,out=[];for(let i=0;i<n;i++)out.push(hslToRgba(h0+i*GOLDEN_ANGLE,s,l));return out}var DEFAULT_CTX=128000,COLS2=16,SLOTS2=["system_prompt","system_tools","mcp_tools","memory","skills","conversation","soul","mem0","user","project","meta","other","unknown","overage"],SLOT=Object.fromEntries(SLOTS2.map((id,i)=>[id,i])),REMOTE={tool_definitions:"system_tools",mcp:"mcp_tools",rules:"system_prompt",subagent_definitions:"system_tools"},ORDER2=["system_prompt","system_tools","mcp_tools","memory","skills","conversation"],LABEL2={system_prompt:"System Prompt",system_tools:"System Tools",mcp_tools:"MCP Tools",memory:"Memory",skills:"Skills",conversation:"Conversation"},rampCache=new WeakMap;function ramp2(theme){let r=rampCache.get(theme);if(!r)rampCache.set(theme,r=categorical(theme.primary,theme.background,SLOTS2.length));return r}function clr(id,theme){if(id==="free")return theme.borderSubtle;return ramp2(theme)[SLOT[id]??SLOT.other]}var fmt2=(n)=>{if(n>=1e6)return`${(n/1e6).toFixed(1)}M`;if(n>=1e4)return`${Math.round(n/1000)}k`;if(n>=1000)return`${(n/1000).toFixed(1)}k`;return String(n)},est=(s)=>s?count2(s):0,bar=(pct,w2=20)=>{let f=Math.round(Math.max(0,Math.min(100,pct))/100*w2);return`[${"\u2588".repeat(f)}${"\u2591".repeat(Math.max(0,w2-f))}]`},SectionPanel=import_react61.memo(({seg,theme})=>{let{syntaxStyle}=useTheme(),sec=seg.section;if(!sec)return null;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsxs("text",{children:[sec.chars.toLocaleString()," chars \xB7 ~",fmt2(sec.tokens)," tokens"]}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsx("markdown",{content:sec.text,fg:theme.markdownText,syntaxStyle})]})}),MemoryPanel=import_react61.memo(({seg,theme,label:label2,chars,limit,pct,entries:entries2,source})=>$jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(seg.id,theme),children:"\u25FC"})," ",seg.label," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:$jsx("strong",{children:label2})}),source?$jsxs($Fragment,{children:[$jsx("text",{children:" ("}),$jsx(FileLink,{source}),$jsx("text",{children:")"})]}):null]}),$jsxs("text",{children:[chars.toLocaleString()," / ",limit.toLocaleString()," chars (",pct,"%)"]}),$jsxs("text",{children:[bar(pct,25),pct>=95?" \u26A0 near limit":""]}),$jsx("text",{children:" "}),$jsxs("text",{children:[entries2.length," entries:"]}),entries2.map((e,i)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",e]},i))]})),SkillsPanel=import_react61.memo(({seg,theme})=>{let sec=seg.section;if(!sec)return null;let cats={};for(let line2 of sec.text.split(`
4100
4100
  `)){if(line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)){let cat=line2.match(/^\s{2}(\S[\w-]*(?:\/\S+)?):\s/)[1];if(!cats[cat])cats[cat]=0}if(line2.match(/^\s{4}- \S+:/)){let last2=Object.keys(cats).pop();if(last2)cats[last2]++}}let sorted=Object.entries(cats).sort((a,b2)=>b2[1]-a[1]),total=sorted.reduce((s,[,n])=>s+n,0);return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("skills",theme),children:"\u25FC"})," Skills Catalog \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),sec.source?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx("text",{children:"Source: "}),$jsx(FileLink,{source:sec.source})]}):null,$jsx("text",{children:" "}),$jsxs("text",{children:[total," skills in ",sorted.length," categories \xB7 ",sec.chars.toLocaleString()," chars"]}),$jsx("text",{fg:theme.textMuted,children:"Largest context section \u2014 skill names + descriptions injected every turn."}),$jsx("text",{children:" "}),sorted.map(([cat,n])=>$jsxs("text",{fg:theme.text,children:["\xB7 ",cat," (",n,")"]},cat))]})}),ToolsPanel=import_react61.memo(({seg,theme,tools,kind:kind2})=>{let sorted=[...tools].sort((a,b2)=>b2.descriptionLength+b2.paramsLength-(a.descriptionLength+a.paramsLength)),label2=kind2==="mcp_tools"?"MCP Tools":"System Tools",blurb=kind2==="mcp_tools"?"MCP-loaded tools \u2014 schemas injected via mcp_ prefix.":"Built-in tool schemas sent with every API call.";return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr(kind2,theme),children:"\u25FC"})," ",label2," \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:[tools.length," tools \u2014 ",blurb]}),$jsx("text",{children:" "}),sorted.map((t2)=>$jsxs("text",{fg:theme.text,children:["\xB7 ",t2.name," (",fmt2(toolTokens(t2))," tok)"]},t2.name))]})}),ConvPanel=import_react61.memo(({seg,theme,messages,output})=>{let user=messages.filter((m2)=>m2.role==="user"),asst=messages.filter((m2)=>m2.role==="assistant"),non=messages.filter((m2)=>m2.role!=="system");return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("conversation",theme),children:"\u25FC"})," Conversation \u2014 ",fmt2(seg.tokens)," tokens (",seg.percent.toFixed(1),"%)"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["User: ",user.length," msgs (~",fmt2(est(user.map((m2)=>text2(m2)).join("")))," tok)"]}),$jsxs("text",{children:["Agent: ",asst.length," msgs (~",fmt2(est(asst.map((m2)=>text2(m2)).join("")))," tok)"]}),output>0?$jsxs("text",{children:["Output generated: ",fmt2(output)," tokens"]}):null,$jsx("text",{children:" "}),non.length>0?$jsxs($Fragment,{children:[$jsx("text",{fg:theme.info,children:"Messages:"}),$jsx("text",{children:" "}),non.map((m2,i)=>$jsxs("text",{children:[$jsx("span",{fg:m2.role==="user"?theme.info:theme.success,children:m2.role==="user"?"\u25B8 You":"\u25C2 Agent"})," ","(",fmt2(est(text2(m2))),") ",text2(m2).replace(/\n/g," ")]},i))]}):$jsx("text",{fg:theme.warning,children:"No messages yet"})]})}),FreePanel=import_react61.memo(({seg,theme,ctxLen,comp,onEditThreshold})=>{let used=ctxLen-seg.tokens,threshold=Math.round(ctxLen*(comp?.threshold??0.5)),pct=threshold>0?Math.min(100,Math.round(used/threshold*100)):0;return $jsxs("scrollbox",{borderStyle:"single",padding:1,flexGrow:1,scrollY:!0,children:[$jsx("text",{children:$jsxs("strong",{children:[$jsx("span",{fg:clr("free",theme),children:"\u25FB"})," Free Space \u2014 ",fmt2(seg.tokens)," tokens"]})}),$jsx("text",{children:" "}),$jsxs("text",{children:["Context window: ",fmt2(ctxLen)]}),$jsxs("text",{children:["Used: ",fmt2(used)," (",Math.round(used/ctxLen*100),"%)"]}),$jsxs("text",{children:["Available: ",fmt2(seg.tokens)," (",seg.percent.toFixed(1),"%)"]}),$jsx("text",{children:" "}),comp?$jsxs($Fragment,{children:[$jsx("text",{children:$jsx("strong",{children:"Compression"})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsxs("text",{children:[comp.enabled?"\u2713 Enabled":"\u2717 Disabled"," \xB7 threshold "]}),$jsx("box",{flexShrink:0,onMouseDown:onEditThreshold,children:$jsx("text",{fg:theme.info,children:$jsxs("u",{children:[Math.round(comp.threshold*100),"%"]})})}),$jsxs("text",{children:[" (",fmt2(threshold),")"]})]}),$jsxs("text",{children:[bar(pct)," ",pct,"%"]}),$jsxs("text",{children:["Protect last ",comp.protect_last_n," messages \xB7 target ratio ",Math.round(comp.target_ratio*100),"%"]}),comp.summary_model?$jsxs("text",{children:["Summary model: ",comp.summary_model]}):null]}):null]})}),NO_MESSAGES=Object.freeze([]),toolsFromInfo=(info)=>{if(!info||info.tools===void 0)return null;let tools=Object.entries(info.tools).flatMap(([group2,names])=>names.map((name)=>({name,descriptionLength:0,paramsLength:group2.length})));return{source:makeSource("state.db","session.info"),tools}},configuredContextLength=(config)=>{let n=config?.model?.context_length;return typeof n==="number"&&n>0?n:void 0},contextMeter=(usage,info,config)=>({max:usage?.context_max??info?.usage?.context_max??info?.context_max??configuredContextLength(config)??DEFAULT_CTX,used:usage?.context_used??info?.usage?.context_used??info?.context_used}),contextBreakdown=(data2)=>{if(!data2||typeof data2!=="object")return null;let raw=data2,max=Number(raw.context_max),used=Number(raw.context_used);if(!Number.isFinite(max)||max<=0||!Number.isFinite(used)||used<0)return null;if(!Array.isArray(raw.categories))return null;return{categories:raw.categories.flatMap((cat)=>{if(!cat||typeof cat!=="object")return[];let id=typeof cat.id==="string"?cat.id.trim():"",label2=typeof cat.label==="string"?cat.label.trim():"",tokens3=Number(cat.tokens);if(!id||!label2||!Number.isFinite(tokens3)||tokens3<0)return[];return[{id,label:label2,tokens:tokens3,color:typeof cat.color==="string"?cat.color:void 0}]}),context_max:max,context_used:Math.min(used,max),estimated_total:Number.isFinite(Number(raw.estimated_total))?Math.max(0,Number(raw.estimated_total)):0,model:typeof raw.model==="string"?raw.model:void 0}},remoteSegments=(data2,local)=>{let byId2=new Map(local.map((seg)=>[seg.id,seg])),bucket=new Map;for(let cat of data2.categories){let id=REMOTE[cat.id]??cat.id,prev=bucket.get(id);bucket.set(id,{label:byId2.get(id)?.label??prev?.label??cat.label,tokens:(prev?.tokens??0)+cat.tokens})}let pct=(n)=>data2.context_max>0?n/data2.context_max*100:0,segs=[...ORDER2,...bucket.keys().filter((id)=>!ORDER2.includes(id))].flatMap((id)=>{let cat=bucket.get(id);if(!cat||cat.tokens<=0)return[];let seg=byId2.get(id);return[{...seg??{},id,label:seg?.label??LABEL2[id]??cat.label,tokens:cat.tokens,percent:pct(cat.tokens)}]}),taken=segs.reduce((sum,seg)=>sum+seg.tokens,0),unknown=Math.max(0,data2.context_used-taken);if(unknown>0)segs.push({id:"unknown",label:"Unknown / Provider Overhead",tokens:unknown,percent:pct(unknown)});let free=Math.max(0,data2.context_max-data2.context_used);return segs.push({id:"free",label:"Free",tokens:free,percent:pct(free)}),segs},Context=import_react61.memo(({messages=NO_MESSAGES,info,usage,focused})=>{let config=useHome("config"),memory=useHome("memory"),userProfile=useHome("userProfile"),gw=useGateway(),dialog=useDialog(),toast=useToast(),systemPrompt2=useHome("systemPrompt"),toolsInfo=useHome("toolsInfo"),soul=useHome("soul"),[wire,setWire]=import_react61.useState({input:0,output:0,total:0,calls:0}),wireRef=import_react61.useRef(wire),theme=useTheme().theme,[hovered,setHovered]=import_react61.useState(null),[selected,setSelected]=import_react61.useState(null),[drilled,setDrilled]=import_react61.useState(null),[remote2,setRemote]=import_react61.useState(null);import_react61.useEffect(()=>{let input=0,output2=0,total=0,calls=0;for(let m2 of messages)if(m2.usage)input+=m2.usage.input,output2+=m2.usage.output,total+=m2.usage.total,calls++;let next={input,output:output2,total,calls};wireRef.current=next,setWire(next)},[messages]);let rev2=usage?.context_used??info?.usage?.context_used??info?.context_used;import_react61.useEffect(()=>{let sid2=info?.session_id;if(!sid2){setRemote(null);return}let done=!1,timer2=setTimeout(()=>{gw.request("session.context_breakdown",{session_id:sid2}).then((data2)=>{if(!done)setRemote(contextBreakdown(data2))}).catch(()=>{if(!done)setRemote(null)})},300);return()=>{done=!0,clearTimeout(timer2)}},[gw,info?.session_id,info?.usage?.compressions,messages.length,rev2]);let localMeter=contextMeter(usage,info,config??null),meter=remote2?{max:remote2.context_max,used:remote2.context_used}:localMeter,ctxLen=meter.max,used=meter.used,reliable=typeof used==="number",output=wire.output,pct=reliable&&ctxLen>0?Math.round(used/ctxLen*100):0,thresholdPct=config?.compression?.threshold??0.5,thresholdIdx=Math.min(COLS2*COLS2,Math.max(0,Math.round(thresholdPct*COLS2*COLS2))),compressions=info?.usage?.compressions??0,promptText=info?.system_prompt??systemPrompt2?.text??"",sections=import_react61.useMemo(()=>parse4(promptText),[promptText]),convTok=import_react61.useMemo(()=>est(messages.filter((m2)=>m2.role!=="system").map((m2)=>text2(m2)).join("")),[messages]),currentTools=import_react61.useMemo(()=>{let liveTools=toolsFromInfo(info);if(liveTools)return liveTools;if(info?.tools!==void 0)return liveTools;return toolsInfo},[info,toolsInfo]),local=import_react61.useMemo(()=>build({contextLength:ctxLen,usedTokens:used,sections,conversationTokens:convTok,tools:currentTools?.tools??[]}),[ctxLen,used,sections,convTok,currentTools]),top=import_react61.useMemo(()=>remote2?remoteSegments(remote2,local):local,[remote2,local]),drilledGroup=drilled?top.find((s)=>s.id===drilled):null,view=drilledGroup?drill(drilledGroup):top,grid=import_react61.useMemo(()=>cells(view,drilledGroup?drilledGroup.children?.[0]?.id??"other":reliable?"free":"unknown"),[view,drilledGroup,reliable]),findSeg=(id)=>{if(drilledGroup)return view.find((s)=>s.id===id);return top.find((s)=>s.id===id)},memEntries=import_react61.useMemo(()=>(memory?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[memory?.content]),userEntries=import_react61.useMemo(()=>(userProfile?.content??"").split("\xA7").map((s)=>s.trim()).filter(Boolean),[userProfile?.content]),click=(id)=>{if(drilled){setSelected(selected===id?null:id);return}let seg=top.find((s)=>s.id===id);if(seg?.children&&seg.children.length>0){setDrilled(id),setSelected(null);return}setSelected(selected===id?null:id)},lastEsc=import_react61.useRef(0),segs=view.filter((s)=>s.tokens>0),idx=selected?segs.findIndex((s)=>s.id===selected):-1,setSel=(v2)=>{let n=Math.max(0,Math.min(segs.length-1,typeof v2==="function"?v2(idx):v2));setSelected(segs[n]?.id??null)},keys=useKeys();useKeyboard((key3)=>{if(!focused||dialog.open())return;if(handleListKey(keys,key3,{count:segs.length,setSel,onActivate:()=>{if(drilled||!selected)return;if(top.find((s)=>s.id===selected)?.children?.length)setDrilled(selected),setSelected(null)}}))return;if(key3.name==="right")return setSel((p)=>p+1);if(key3.name==="left")return setSel((p)=>p-1);if(key3.name!=="escape")return;let now=Date.now();if(now-lastEsc.current<400){setSelected(null),setDrilled(null),lastEsc.current=0;return}if(lastEsc.current=now,selected)return setSelected(null);if(drilled)return setDrilled(null)});let editThreshold=async()=>{let cur=Math.round((config?.compression?.threshold??0.5)*100),v2=await openTextPrompt(dialog,{title:"Compression threshold",label:"Percent (10\u201395)",initial:String(cur)});if(v2===null)return;let n=Math.max(10,Math.min(95,Number(v2)||cur)),{writeConfig:writeConfig2}=await Promise.resolve().then(() => (init_lane(),exports_lane)),r=await writeConfig2(gw,[{key:"compression.threshold",to:n/100}]);if(r.failed.length)return toast.show({variant:"error",message:r.failed[0].err});home3.invalidate("config"),toast.show({variant:"success",message:`Threshold \u2192 ${n}%`})},detail=()=>{if(!selected)return null;let seg=findSeg(selected);if(!seg)return null;if(selected==="memory"&&drilled==="memory"&&memory)return $jsx(MemoryPanel,{seg,theme,label:"Agent Notes",chars:memory.charCount,limit:memory.charLimit,pct:memory.usagePercent,entries:memEntries,source:memory.source});if(selected==="user"&&userProfile)return $jsx(MemoryPanel,{seg,theme,label:"User Profile",chars:userProfile.charCount,limit:userProfile.charLimit,pct:userProfile.usagePercent,entries:userEntries,source:userProfile.source});if(selected==="skills")return $jsx(SkillsPanel,{seg,theme});if(selected==="system_tools"&&currentTools){let{system}=classifyTools(currentTools.tools);return $jsx(ToolsPanel,{seg,theme,tools:system,kind:"system_tools"})}if(selected==="mcp_tools"&&currentTools){let{mcp}=classifyTools(currentTools.tools);return $jsx(ToolsPanel,{seg,theme,tools:mcp,kind:"mcp_tools"})}if(selected==="soul"&&soul){let soulSeg={...seg,section:{id:"soul",label:"SOUL.md",chars:soul.charCount,tokens:soul.tokenEstimate,text:soul.content,source:soul.source}};return $jsx(SectionPanel,{seg:soulSeg,theme})}if(selected==="conversation")return $jsx(ConvPanel,{seg,theme,messages,output});if(selected==="free")return $jsx(FreePanel,{seg,theme,ctxLen,comp:config?.compression,onEditThreshold:editThreshold});return $jsx(SectionPanel,{seg,theme})},breakdown=()=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsxs("text",{children:[$jsx("strong",{children:"Breakdown"}),drilledGroup?$jsxs("span",{fg:theme.info,children:[" \xB7 ",drilledGroup.label," (",fmt2(drilledGroup.tokens)," tok)"]}):reliable?$jsx("span",{fg:theme.info,children:" (click group to expand)"}):$jsxs("span",{fg:theme.warning,children:[" \xB7 live usage unavailable \xB7 limit ",fmt2(ctxLen)]})]}),view.filter((s)=>s.tokens>0).map((s)=>$jsxs("text",{children:[$jsx("span",{fg:clr(s.id,theme),children:s.id==="free"?"\u25FB":"\u25FC"})," ",s.label," \u2014 ",fmt2(s.tokens)," (",s.percent.toFixed(1),"%)",s.children?$jsx("span",{fg:theme.textMuted,children:" \u25B8"}):null]},s.id)),output>0&&!drilled?$jsxs("text",{children:[$jsx("span",{fg:theme.success,children:"\u25FC"})," Output \u2014 ",fmt2(output)," tokens"]}):null,reliable&&!drilled?$jsx("text",{children:$jsxs("span",{fg:theme.textMuted,children:["\u25FC Beyond compression threshold (",Math.round(thresholdPct*100),"%)"]})}):null]}),crumb=drilled?`${drilledGroup?.label}${selected?` \xB7 ${findSeg(selected)?.label}`:""}`:reliable?"\u2191\u2193 nav \xB7 click a group to drill in":"live usage unavailable \xB7 estimates shown with ~",escHint=selected||drilled?" \xB7 Esc back":"",focus=selected||hovered,focusSeg=focus?findSeg(focus):null;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:reliable?`Context \xB7 ${fmt2(used)} / ${fmt2(ctxLen)} (${pct}%)`:`Context \xB7 live usage unavailable \xB7 limit ${fmt2(ctxLen)}`,children:[$jsx("box",{height:1,children:focusSeg?$jsxs("text",{fg:clr(focusSeg.id,theme),children:["\u25FC ",focusSeg.label," \u2014 ",fmt2(focusSeg.tokens)," tok (",focusSeg.percent.toFixed(1),"%)"]}):$jsx("text",{children:" "})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsxs("box",{flexDirection:"column",marginRight:2,flexShrink:0,children:[!drilled&&compressions>0?$jsx("box",{height:1,marginBottom:1,children:$jsxs("text",{fg:theme.warning,children:["\xD7",compressions," compressed"]})}):null,$jsx("box",{border:!0,customBorderChars:CORNERS,borderColor:theme.border,children:[...Array(COLS2)].map((_2,row3)=>$jsx("box",{flexDirection:"row",height:1,children:[...Array(COLS2)].map((_3,col)=>{let cell=grid[row3*COLS2+col],hl=selected?selected===cell.id:hovered===cell.id,past=!drilled&&row3*COLS2+col>=thresholdIdx,glyph=!past&&cell.id==="free"?"\u25FB":"\u25FC";return $jsx("box",{height:1,width:2,backgroundColor:hl?clr(cell.id,theme):void 0,onMouseOver:()=>setHovered(cell.id),onMouseOut:()=>setHovered(null),onMouseDown:()=>click(cell.id),children:$jsx("text",{fg:past?theme.textMuted:clr(cell.id,theme),children:glyph})},col)})},row3))})]}),$jsx("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:selected?detail():breakdown()})]})]}),$jsx(HintBar,{raw:crumb+escHint})]})});var import_react64=__toESM(require_react_production(),1);init_hermes_analytics();var import_react63=__toESM(require_react_production(),1);init_hermes_analytics();var query=(days,opts)=>Promise.resolve(io.analytics(days,opts));function useAnalyticsData(days,tick3,load4=query){let[data2,setData]=import_react63.useState(()=>cache3.get(days)??null),[tools,setTools]=import_react63.useState(()=>cache3.get(days)?.byTool??null),[error,setError]=import_react63.useState(""),gen=import_react63.useRef(0);return import_react63.useEffect(()=>{let hit=cache3.get(days);setData(hit??null),setTools(hit?.byTool??null),setError("");let current=++gen.current;return load4(days,{tools:!1}).then((fast)=>{if(gen.current!==current)return;return setData(fast),load4(days).then((full)=>{if(gen.current!==current)return;cache3.set(days,full),setData(full),setTools(full.byTool)})}).catch((err)=>{if(gen.current===current)setError(err instanceof Error?err.message:String(err))}),()=>{gen.current++}},[days,tick3,load4]),{data:data2,tools,error}}var BLOCKS=" \u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588",rows2=(vals,h2)=>{let peak=Math.max(1,...vals),ticks=vals.map((v2)=>Math.round(h2*8*v2/peak));return Array.from({length:h2},(_2,r)=>{let floor=(h2-1-r)*8;return ticks.map((t2)=>BLOCKS[Math.max(0,Math.min(8,t2-floor))]).join("")})},Chart=import_react64.memo((p)=>{let theme=useTheme().theme,days=p.data.byDay,vals=days.map((d2)=>d2.cost),peak=Math.max(...vals,0.01),axis=(v2)=>cost2(v2).padStart(7),md=(s)=>s.slice(5);return $jsxs("box",{flexDirection:"column",children:[rows2(vals,p.h).map((line2,i)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:i===0?axis(peak):i===p.h-1?axis(0):""})}),$jsx("text",{fg:theme.primary,children:line2})]},i)),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:8,flexShrink:0}),$jsx("text",{fg:theme.textMuted,children:days.length>0?`${md(days[0].date)}${" ".repeat(Math.max(0,days.length-10))}${md(days[days.length-1].date)}`:""})]})]})}),Rank=import_react64.memo((p)=>{let theme=useTheme().theme;if(p.rows===null)return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),$jsx("box",{height:1,children:$jsx(Spinner,{label:"aggregating\u2026"})})]});let top=p.rows.slice(0,p.n??10),peak=Math.max(1,...top.map((r)=>r.n)),total=p.rows.reduce((a,r)=>a+r.n,0);return $jsxs("box",{flexDirection:"column",flexGrow:1,flexBasis:0,minWidth:0,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.title})}),top.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"\u2014"})}):top.map((r)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{w:18,children:trunc5(r.name,17)}),$jsx(Col,{w:12,fg:p.fg,children:"\u2587".repeat(Math.max(1,Math.round(10*r.n/peak)))}),$jsx(Col,{w:7,right:!0,children:fmt(r.n)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:total?`${Math.round(100*r.n/total)}%`:""})]},r.name))]})}),Analytics=import_react64.memo((props)=>{let theme=useTheme().theme,dialog=useDialog(),dims=useTerminalDimensions(),[days,setDays]=import_react64.useState(7),[tick3,setTick]=import_react64.useState(0),{data:data2,tools,error}=useAnalyticsData(days,tick3,props.load),keys=useKeys();useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(keys.match("list.refresh",key3))return cache3.delete(days),setTick((n)=>n+1);if(key3.raw==="1")return setDays(1);if(key3.raw==="7")return setDays(7);if(key3.raw==="3")return setDays(30);if(key3.raw==="9")return setDays(90)});let t2=data2?.total,tok=(t2?.input??0)+(t2?.output??0),title=import_react64.useMemo(()=>!t2?`Analytics \xB7 ${days}d`:`Analytics \xB7 ${days}d \xB7 ${t2.sessions} sess \xB7 ${fmt(tok)} tok \xB7 ${cost2(t2.cost)}`,[days,t2,tok]),wide=dims.width>=110,chartH=dims.height>=40?8:6;if(!data2)return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsx("box",{height:1,children:error?$jsx("text",{fg:theme.error,children:error}):$jsx(Spinner,{label:`aggregating ${days}d\u2026`})})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]});let nTools=8,nSrc=6,ranksH=wide?Math.max(nTools,nSrc)+1:nTools+nSrc+3;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(TabShell,{title,children:$jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,overflow:"hidden",children:[error?$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:error})}):null,$jsxs("box",{flexShrink:0,flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`Cost per day \xB7 ${fmt(t2.input)} in \xB7 ${fmt(t2.output)} out \xB7 ${fmt(t2.cache)} cache \xB7 ${fmt(t2.calls)} tool calls`})}),$jsx(Chart,{data:data2,h:chartH})]}),$jsx("box",{height:1,flexShrink:0}),$jsx("box",{flexShrink:0,children:$jsxs(Hdr,{children:[$jsx(Col,{grow:!0,min:18,fg:theme.textMuted,children:"Model"}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:"sess"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"in"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"out"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cache"}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:"cost"})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,flexShrink:1,minHeight:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:data2.byModel.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"no sessions in range"})}):data2.byModel.map((m2)=>$jsxs("box",{height:1,flexDirection:"row",children:[$jsx(Col,{grow:!0,min:18,children:trunc5(m2.model,40)}),$jsx(Col,{w:6,right:!0,fg:theme.textMuted,children:String(m2.sessions)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.input)}),$jsx(Col,{w:9,right:!0,children:fmt(m2.output)}),$jsx(Col,{w:9,right:!0,fg:theme.textMuted,children:fmt(m2.cache)}),$jsx(Col,{w:9,right:!0,fg:theme.accent,children:cost2(m2.cost)})]},m2.model))})}),$jsx("box",{height:1,flexShrink:0}),$jsxs("box",{flexShrink:0,height:ranksH,flexDirection:wide?"row":"column",gap:wide?2:1,children:[$jsx(Rank,{title:"Tools",rows:tools,fg:theme.success,n:nTools}),$jsx(Rank,{title:"Sources",rows:data2.bySource,fg:theme.info,n:nSrc})]})]})}),$jsx(HintBar,{pairs:[["1/7/3/9","period"],[keys.print("list.refresh"),"reload"]]})]})});var import_react66=__toESM(require_react_production(),1);import{tmpdir as tmpdir3}from"os";import{join as join12}from"path";import{rm}from"fs/promises";async function editInEditor(renderer,seed,suffix2=".md"){let cmd=process.env.VISUAL||process.env.EDITOR;if(!cmd)return;let path4=join12(tmpdir3(),`herm-${Date.now()}${suffix2}`);await Bun.write(path4,seed);let suspended=!1;try{renderer.suspend(),suspended=!0,renderer.currentRenderBuffer.clear();let argv=process.platform==="win32"?["cmd.exe","/d","/s","/c",`${cmd} "${path4.replaceAll('"','""')}"`]:["/bin/sh","-c",`exec ${cmd} "$1"`,"herm-editor",path4],code=await Bun.spawn(argv,{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(code!==0)throw Error(`editor exited ${code}`);return(await Bun.file(path4).text().catch(()=>"")).trim()||void 0}finally{if(await rm(path4,{force:!0}).catch(()=>{}),suspended&&!renderer.isDestroyed)try{renderer.currentRenderBuffer.clear()}finally{renderer.resume(),renderer.requestRender()}}}function buildJourneyRows(buckets){return buckets.flatMap((bucket,b2)=>[...b2>0?[{kind:"gap"}]:[],{kind:"slice",bucket},...bucket.nodes.map((node,i)=>({kind:"node",bucket,node,last:i===bucket.nodes.length-1}))])}var style=(theme,key3,hex2)=>{if(hex2&&/^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/.test(hex2))return RGBA.fromHex(hex2);if(key3==="skill")return theme.primary;if(key3==="memory")return theme.accent;if(key3==="label")return theme.text;if(key3==="dim")return theme.textMuted;if(key3==="bg")return theme.borderSubtle;return theme.textMuted},last2=(data2)=>data2?.frames.at(-1)?.grid??[],latest2=(rows3)=>{let i=[...rows3].reverse().findIndex((r)=>r.kind==="node");return i>=0?rows3.length-1-i:Math.max(0,rows3.length-1)},snap=(rows3,i,dir=1)=>{if(rows3.length===0)return 0;let at=Math.max(0,Math.min(rows3.length-1,i));if(rows3[at]?.kind!=="gap")return at;let rev2=[...rows3].reverse().findIndex((r,n)=>rows3.length-1-n<at&&r.kind!=="gap");if(dir<0&&rev2>=0)return rows3.length-1-rev2;let fwd=rows3.findIndex((r,n)=>n>at&&r.kind!=="gap");if(fwd>=0)return fwd;return rev2>=0?rows3.length-1-rev2:at},message=(err)=>err instanceof Error?err.message:String(err),rid=(r,i)=>{if(!r)return`empty-${i}`;if(r.kind==="slice")return`slice-${r.bucket.index}-${r.bucket.date??r.bucket.label}`;if(r.kind==="node")return`node-${r.bucket.index}-${r.node.id}`;return`gap-${i}`},Journey=import_react66.memo((props)=>{let gw=useGateway(),theme=useTheme().theme,dialog=useDialog(),toast=useToast(),renderer=useRenderer(),dims=useTerminalDimensions(),keys=useKeys(),[data2,setData]=import_react66.useState(null),[err,setErr]=import_react66.useState(null),[sel,setSel]=import_react66.useState(0),[detail,setDetail]=import_react66.useState(null),[pane,setPane]=import_react66.useState("list"),[busy,setBusy]=import_react66.useState(!1),[tick3,setTick]=import_react66.useState(0),rows3=import_react66.useMemo(()=>buildJourneyRows(data2?.buckets??[]),[data2]),row3=rows3[Math.min(sel,Math.max(0,rows3.length-1))],node=row3?.kind==="node"?row3.node:void 0,chart=last2(data2),h2=Math.max(5,Math.min(8,Math.floor(dims.height*0.2))),cols=Math.max(40,dims.width-8),follow=useFollow("journey",(i)=>rid(rows3[i],i)),scroll=import_react66.useRef(null),seq=import_react66.useRef(0),jump=import_react66.useCallback((i)=>{let n=snap(rows3,i);setSel(n),follow.opts.scrollTo(n)},[rows3]),setListSel=import_react66.useCallback((next)=>{setSel((prev)=>{let target=typeof next==="function"?next(prev):next,n=snap(rows3,target,target-prev);return follow.opts.scrollTo(n),n})},[rows3]);import_react66.useEffect(()=>{let n=0,cb=async()=>{if(n++,n<2)return;follow.opts.scrollTo(sel),renderer.removeFrameCallback(cb)};return renderer.setFrameCallback(cb),()=>renderer.removeFrameCallback(cb)},[renderer,rows3,sel]),import_react66.useEffect(()=>{let n=++seq.current;setErr(null),setBusy(!0);let timer2=setTimeout(()=>{gw.request("learning.frames",{cols,rows:h2,frames:2}).then((r)=>{if(n!==seq.current)return;setData(r);let tree=buildJourneyRows(r.buckets??[]);setSel(latest2(tree)),setDetail(null),setPane("list")}).catch((e)=>{if(n===seq.current)setErr(message(e))}).finally(()=>{if(n===seq.current)setBusy(!1)})},120);return()=>{clearTimeout(timer2),seq.current++}},[gw,cols,h2,tick3]);let open2=import_react66.useCallback(async(target)=>{setBusy(!0),setErr(null);try{let r=await gw.request("learning.detail",{id:target.id});if(setDetail(r),setPane("detail"),!r.ok)toast.show({variant:"warning",message:r.message})}catch(e){setErr(message(e))}finally{setBusy(!1)}},[gw,toast]),edit=import_react66.useCallback(async()=>{if(!node)return;setBusy(!0),setErr(null);try{let info=await gw.request("learning.detail",{id:node.id});if(!info.ok){toast.show({variant:"warning",message:info.message});return}let text4=await editInEditor(renderer,info.content,info.kind==="skill"?".md":".txt");if(text4===void 0||text4.trim()===info.content.trim()){toast.show({variant:"info",message:"no changes"});return}let req={id:node.id,content:text4},r=await gw.request("learning.edit",req);if(toast.show({variant:r.ok?"success":"warning",message:r.message}),r.ok||/stale|refresh/i.test(r.message))setTick((n)=>n+1)}catch(e){setErr(message(e))}finally{setBusy(!1)}},[gw,node,renderer,toast]),del=import_react66.useCallback(async()=>{if(!node)return;if(!await openConfirm(dialog,{title:`Delete ${node.label}?`,body:`${node.fullLabel||node.label}
4101
4101
 
4102
4102
  This mutates the learning source through learning.delete.`,yes:"delete",danger:!0}))return;setBusy(!0),setErr(null);try{let req={id:node.id},r=await gw.request("learning.delete",req);if(toast.show({variant:r.ok?"success":"warning",message:r.message}),r.ok||/stale|refresh/i.test(r.message))setTick((n)=>n+1)}catch(e){setErr(message(e))}finally{setBusy(!1)}},[dialog,gw,node,toast]);useKeyboard((key3)=>{if(!props.focused||dialog.open()||busy)return;if(detail&&(key3.name==="tab"||keys.match("focus.cycle",key3))){setPane((p)=>p==="list"?"detail":"list");return}if(detail&&pane==="detail"){let page=Math.max(1,(scroll.current?.viewport.height??10)-1);if(key3.name==="escape"){setPane("list");return}if(key3.name==="up"||key3.name==="k"||key3.raw==="k"){scroll.current?.scrollBy(-1);return}if(key3.name==="down"||key3.name==="j"||key3.raw==="j"){scroll.current?.scrollBy(1);return}if(key3.name==="pageup"){scroll.current?.scrollBy(-page);return}if(key3.name==="pagedown"){scroll.current?.scrollBy(page);return}if(key3.name==="home"||key3.name==="g"){scroll.current?.scrollTo(0);return}if(key3.name==="end"||key3.raw==="G"||key3.name==="g"&&key3.shift){scroll.current?.scrollTo(scroll.current.scrollHeight);return}return}if(key3.name==="escape"&&detail){setDetail(null),setPane("list");return}if(handleListKey(keys,key3,{count:rows3.length,setSel:setListSel,...follow.opts,onActivate:()=>{if(node)open2(node)},onToggle:()=>{if(node)open2(node)},onRefresh:()=>setTick((n)=>n+1),onDelete:()=>void del()}))return;if(key3.name==="e"||key3.raw==="e"){edit();return}});let rowPick=import_react66.useCallback((i)=>jump(i),[jump]),rowOpen=import_react66.useCallback((i)=>{jump(i);let r=rows3[i];if(r?.kind==="node")open2(r.node)},[jump,open2,rows3]),hint=detail&&pane==="detail"?`\u2191\u2193/jk scroll ${keys.print("list.pageUp")}/${keys.print("list.pageDown")} page Tab list Esc list`:`${keys.print("list.activate")} detail ${keys.print("list.toggle")} detail e edit ${keys.print("list.delete")} delete ${keys.print("list.refresh")} reload${detail?" Tab detail Esc close":""}`;return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,minWidth:0,children:[$jsxs(TabShell,{title:data2?`Journey \xB7 ${data2.count} learned item${data2.count===1?"":"s"}`:"Journey",error:err,focus:pane==="list",grow:detail?2:1,children:[!data2&&!err?$jsx(Loading,{}):null,!data2&&err?$jsx(ErrorState,{err}):null,data2&&data2.count===0?$jsx(Empty,{}):null,data2&&data2.count>0?$jsxs("box",{flexDirection:"column",flexGrow:1,minHeight:0,children:[$jsx(Legend,{data:data2}),$jsx(Chart2,{rows:chart,theme}),$jsx("box",{height:1}),$jsx("scrollbox",{ref:follow.ref,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",children:rows3.map((r,i)=>$jsx(Row2,{id:follow.id(i),row:r,index:i,active:i===sel,theme,pick:rowPick,open:rowOpen},rid(r,i)))})})]}):null]}),detail?$jsx(Detail2,{detail,box:scroll,focus:pane==="detail",theme}):null]}),$jsx(HintBar,{raw:busy?"loading\u2026":hint})]})}),Loading=()=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.textMuted,children:"assembling learning map\u2026"})})},Empty=()=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.textMuted,children:"No learning yet \u2014 skills and memories will appear here."})})},ErrorState=({err})=>{let theme=useTheme().theme;return $jsx("box",{flexGrow:1,justifyContent:"center",alignItems:"center",children:$jsx("text",{fg:theme.error,wrapMode:"word",children:err})})},Legend=({data:data2})=>{let theme=useTheme().theme,text4=[...data2.legend??[],...data2.categories??[]].map((i)=>`${i.glyph} ${i.label}`).join(" ")||data2.summary.join(" ");return $jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:text4})})},Chart2=({rows:rows3,theme})=>$jsx("box",{flexDirection:"column",flexShrink:0,children:rows3.map((row3,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsx("text",{wrapMode:"none",children:row3.map((run,n)=>$jsx("span",{fg:style(theme,run[1],run[3]),children:run[0]},n))})},i))}),Row2=import_react66.memo((props)=>{let bg2=props.active?props.theme.backgroundElement:void 0,caret=props.active?"\u25B8 ":" ";if(props.row.kind==="gap")return $jsx("box",{id:props.id,height:1});if(props.row.kind==="slice")return $jsx("box",{id:props.id,height:1,backgroundColor:bg2,onMouseMove:()=>props.pick(props.index),onMouseDown:()=>props.open(props.index),overflow:"hidden",children:$jsxs("text",{wrapMode:"none",children:[$jsx("span",{fg:props.theme.textMuted,children:caret}),$jsx("span",{fg:props.active?props.theme.accent:props.theme.primary,children:props.row.bucket.label}),$jsx("span",{fg:props.theme.textMuted,children:` ${props.row.bucket.total} total \xB7 ${props.row.bucket.memories} memories \xB7 ${props.row.bucket.skills} skills`})]})});return $jsx("box",{id:props.id,height:1,backgroundColor:bg2,onMouseMove:()=>props.pick(props.index),onMouseDown:()=>props.open(props.index),overflow:"hidden",children:$jsxs("text",{wrapMode:"none",children:[$jsx("span",{fg:props.theme.textMuted,children:caret}),$jsx("span",{fg:props.theme.textMuted,children:props.row.last?" \u2514\u2500 ":" \u251C\u2500 "}),$jsx("span",{fg:props.active?props.theme.accent:style(props.theme,props.row.node.style),children:`${props.row.node.glyph} ${trunc5(props.row.node.fullLabel||props.row.node.label,54)}`}),$jsx("span",{fg:props.theme.textMuted,children:props.row.node.meta?` ${props.row.node.meta}`:""})]})})}),Detail2=(props)=>$jsx(TabShell,{title:props.detail.ok?`${props.detail.kind} \xB7 ${props.detail.label}`:"Detail",focus:props.focus,grow:1,children:props.detail.ok?$jsx("scrollbox",{ref:props.box,scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:props.detail.content.split(/\r?\n/).map((line2,i)=>$jsx("box",{minHeight:1,children:$jsx("text",{fg:props.theme.text,wrapMode:"word",children:line2||" "})},i))})}):$jsx("text",{fg:props.theme.warning,wrapMode:"word",children:props.detail.message})});var import_react68=__toESM(require_react_production(),1);var SubTabBar=import_react68.memo((props)=>$jsx(TabStrip,{...props}));var TABS=[{name:"Chat",description:"Main chat interface"},{name:"Sessions",description:"Sessions, context, analytics"},{name:"Profiles & Automation",description:"Profiles, cron jobs, kanban boards"},{name:"Config",description:"Config, env, skills, toolsets, memory"},{name:"Eikon",description:"Avatar studio & library"}],TAB_MAX=TABS.length-1,CHAT_TAB=0,SESSIONS_TAB=1,AUTOMATION_TAB=2,CONFIG_TAB=3,EIKON_TAB=4,SUB_TABS={[1]:["List","Context","Analytics","Journey"],[2]:["Kanban","Profiles","Cron"],[3]:["Config","Skills","Toolsets","Env","Memory"],[4]:["Library","Catalog","Studio"]},TAB_SLASH={chat:{tab:0,sub:0},sessions:{tab:1,sub:0},context:{tab:1,sub:1},analytics:{tab:1,sub:2},insights:{tab:1,sub:2},journey:{tab:1,sub:3},learning:{tab:1,sub:3},"memory-graph":{tab:1,sub:3},kanban:{tab:2,sub:0},automation:{tab:2,sub:0},profiles:{tab:2,sub:1},agents:{tab:2,sub:1},cron:{tab:2,sub:2},config:{tab:3,sub:0},skills:{tab:3,sub:1},toolsets:{tab:3,sub:2},env:{tab:3,sub:3},memory:{tab:3,sub:4},library:{tab:4,sub:0},catalog:{tab:4,sub:1},studio:{tab:4,sub:2}};var SessionsGroup=import_react69.memo((props)=>{let labels=SUB_TABS[SESSIONS_TAB];import_react69.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint="shift+\u2190/\u2192 sub";return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane,{visible:props.sub===0,children:$jsx(Sessions,{focused:!!props.focused&&props.sub===0,onSwitch:props.onSwitch,onActivateLive:props.onActivateLive,currentId:props.currentId})}),$jsx(Pane,{visible:props.sub===1,children:$jsx(Context,{focused:!!props.focused&&props.sub===1,messages:props.messages,sessionStart:props.sessionStart,info:props.info,usage:props.usage})}),$jsx(Pane,{visible:props.sub===2,children:$jsx(Analytics,{focused:!!props.focused&&props.sub===2})}),$jsx(Pane,{visible:props.sub===3,children:$jsx(Journey,{focused:!!props.focused&&props.sub===3})})]})]})}),Pane=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react94=__toESM(require_react_production(),1);var import_react83=__toESM(require_react_production(),1);var acc=new Map;function record(ev,p){let id=p.subagent_id;if(!id)return;let now=Date.now()/1000;if(ev==="start"){acc.set(id,{subagent_id:id,parent_id:p.parent_id??null,depth:p.depth??0,goal:p.goal,model:p.model,started_at:now,tool_count:0,status:"running",trail:[]});return}let r=acc.get(id);if(!r)return;if(ev==="tool"&&p.tool_name){r.tool_count++,r.trail=[...r.trail??[],{name:p.tool_name,preview:p.tool_preview}].slice(-20);return}if(ev==="complete")r.status=p.status??"completed",r.finished_at=now,r.input_tokens=p.input_tokens,r.output_tokens=p.output_tokens,r.cost_usd=p.cost_usd}function trail(id){return acc.get(id)?.trail??[]}function flush(gw,sessionId){if(acc.size===0)return;let subagents=[...acc.values()];acc.clear();let label2=(subagents.filter((s)=>s.parent_id==null).slice(0,2).map((s)=>s.goal).join(" \xB7 ")||`${subagents.length} subagents`).slice(0,120),started=Math.min(...subagents.map((s)=>s.started_at));gw.request("spawn_tree.save",{session_id:sessionId,label:label2,started_at:started,finished_at:Date.now()/1000,subagents}).catch(()=>{})}var import_react72=__toESM(require_react_production(),1);var import_react70=__toESM(require_react_production(),1);var DialogSelect=(props)=>{let filterable=props.filterable??!0,[filter,setFilter]=import_react70.useState(""),[cursor,setCursor]=import_react70.useState(0),mode2=import_react70.useRef("kb"),moved=import_react70.useRef(!1),sb=import_react70.useRef(null),theme=useTheme().theme,opts=import_react70.useMemo(()=>props.options.map((o)=>({name:`${props.current==null?"":o.value===props.current?"\u25CF ":" "}${o.title}`,description:o.hint?[o.description,o.hint].filter(Boolean).join(" \u2014 "):o.description??"",value:o.value})),[props.current,props.options]),sel=props.current==null?0:Math.max(0,props.options.findIndex((o)=>o.value===props.current)),desc=props.options.some((o)=>!!o.description||!!o.hint),filtered=import_react70.useMemo(()=>{let lower=filter.toLowerCase();return props.options.filter((o)=>o.title.toLowerCase().includes(lower)||(o.description??"").toLowerCase().includes(lower))},[filter,props.options]),groups=import_react70.useMemo(()=>{let map=new Map;return filtered.forEach((o)=>{let cat=o.category??"",arr=map.get(cat)??[];arr.push(o),map.set(cat,arr)}),map},[filtered]),rowId=(i)=>`ds-row-${i}`,scrollTo=(i)=>sb.current?.scrollChildIntoView(rowId(i));import_react70.useEffect(()=>{if(cursor>=filtered.length)setCursor(Math.max(0,filtered.length-1))},[filtered.length,cursor]),import_react70.useEffect(()=>{if(!props.current){setCursor(0);return}let i=filtered.findIndex((o)=>o.value===props.current),n=Math.max(0,i);setCursor(n),scrollTo(n)},[props.current,filtered]),import_react70.useEffect(()=>{if(!moved.current)return;moved.current=!1;let item=filtered[cursor];if(item&&props.onMove)props.onMove(item)},[cursor,filtered,props.onMove]);let keys=useKeys();useKeyboard((key3)=>{if(!filterable)return;if(handleListKey(keys,key3,{count:filtered.length,setSel:(fn)=>{mode2.current="kb",moved.current=!0,setCursor(fn)},scrollTo,page:Math.max(1,(sb.current?.viewport.height??10)-1),onActivate:()=>{let item=filtered[cursor];if(item)props.onSelect(item)}}))return;if(props.onKey?.(key3))return});let idx=0,entries2=Array.from(groups.entries());if(!filterable)return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),$jsx("select",{focused:!0,width:58,height:Math.min(16,Math.max(1,props.options.length*(desc?2:1))),options:opts,selectedIndex:sel,showDescription:desc,showScrollIndicator:props.options.length>8,backgroundColor:theme.backgroundPanel,focusedBackgroundColor:theme.backgroundPanel,textColor:theme.textMuted,focusedTextColor:theme.text,selectedBackgroundColor:theme.backgroundElement,selectedTextColor:theme.text,descriptionColor:theme.textMuted,selectedDescriptionColor:theme.textMuted,fastScrollStep:Math.max(1,props.options.length),keyBindings:[{name:"home",action:"move-up-fast"},{name:"end",action:"move-down-fast"},{name:"pageup",action:"move-up-fast"},{name:"pagedown",action:"move-down-fast"},{name:"space",action:"select-current"},{name:" ",action:"select-current"}],onChange:(i)=>{let item=props.options[i];if(item&&props.onMove)props.onMove(item)},onSelect:(i)=>{let item=props.options[i];if(item)props.onSelect(item)}}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]});return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.title})}),$jsx("box",{height:1}),filterable?$jsxs($Fragment,{children:[$jsx("input",{value:filter,onInput:(v2)=>{mode2.current="kb",setFilter(v2)},placeholder:props.placeholder??"Type to filter...",focused:!0,textColor:theme.text,placeholderColor:theme.textMuted,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}),$jsx("box",{height:1})]}):null,$jsxs("scrollbox",{ref:sb,scrollY:!0,maxHeight:16,focused:!filterable,contentOptions:{flexDirection:"column"},paddingRight:1,children:[filtered.length===0?$jsx("text",{fg:theme.textMuted,children:"No results found"}):null,entries2.map(([cat,items])=>{let elements=[];if(cat)elements.push($jsx("text",{fg:theme.textMuted,children:$jsx("strong",{children:cat})},`cat-${cat}`));return items.forEach((item)=>{let i=idx++,active=i===cursor,current=item.value===props.current;elements.push($jsxs("box",{id:rowId(i),flexDirection:"row",backgroundColor:active?theme.backgroundElement:void 0,onMouseMove:()=>{mode2.current="mouse",moved.current=!0,setCursor((c)=>c===i?c:i)},onMouseOver:()=>{if(mode2.current==="mouse")moved.current=!0,setCursor(i)},onMouseDown:()=>props.onSelect(item),paddingLeft:1,paddingRight:1,children:[$jsx("box",{flexGrow:1,height:1,overflow:"hidden",children:$jsxs("text",{fg:active?theme.text:theme.textMuted,children:[current?"\u25CF ":" ",item.title,item.description?` \u2014 ${item.description}`:""]})}),item.hint?$jsx("box",{flexShrink:0,height:1,children:$jsx("text",{fg:theme.textMuted,children:item.hint})}):null]},item.value))}),elements}).flat()]}),props.footer!=null?$jsx("box",{paddingTop:1,children:props.footer}):null]})};var Ctx6=import_react72.createContext(null),CommandProvider=({children:children2})=>{let registry=import_react72.useRef(new Map),enabled2=import_react72.useRef(!0),dialog=useDialog(),keys=useKeys(),all=import_react72.useCallback(()=>{let out=[];return registry.current.forEach((cmds)=>cmds.forEach((c)=>out.push(c))),out},[]),register=import_react72.useCallback((cmds)=>{let id=String(Date.now())+Math.random();return registry.current.set(id,cmds),()=>{registry.current.delete(id)}},[]),setEnabled=import_react72.useCallback((val)=>{enabled2.current=val},[]),open2=import_react72.useCallback(()=>{let cmds=all(),options=cmds.map((c)=>({title:c.title,value:c.value,description:c.description,hint:c.action?keys.print(c.action):void 0,category:c.category}));dialog.replace($jsx(DialogSelect,{title:"Command Palette",options,onSelect:(opt)=>{dialog.clear();let found=cmds.find((c)=>c.value===opt.value);if(found)found.onSelect()},placeholder:"Search commands..."}))},[all,dialog,keys]);useKeyboard((key3)=>{if(!enabled2.current||dialog.open())return;if(keys.match("palette.open",key3))return open2();for(let c of all())if(c.action&&keys.match(c.action,key3))return c.onSelect()});let value=import_react72.useMemo(()=>({register,setEnabled}),[register,setEnabled]);return $jsx(Ctx6.Provider,{value,children:children2})},useCommand=makeUse(Ctx6,"useCommand");var import_react74=__toESM(require_react_production(),1);function openAlert(dialog,title,body){dialog.replace($jsx(Alert,{title,body,onClose:()=>dialog.clear()}))}var Alert=(props)=>{let theme=useTheme().theme,keys=useKeys(),[copied2,setCopied]=import_react74.useState(!1),doCopy=()=>{copy2(props.body),setCopied(!0),setTimeout(()=>setCopied(!1),900)};return useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))props.onClose();if(keys.match("dialog.copy",key3))doCopy()}),$jsxs("box",{flexDirection:"column",width:84,maxHeight:28,border:["left"],borderColor:theme.info,customBorderChars:LEFT_BAR,backgroundColor:theme.backgroundPanel,paddingLeft:2,paddingRight:2,paddingY:1,gap:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.info,children:"\u25C8 "}),$jsx("span",{fg:theme.text,children:props.title})]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:props.body})}),$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:`${keys.print("dialog.cancel")} close \xB7 ${keys.print("dialog.copy")} `})}),$jsx("box",{flexShrink:0,onMouseDown:(e)=>{e.stopPropagation(),doCopy()},children:$jsx("text",{fg:copied2?theme.success:theme.textMuted,children:$jsx("u",{children:copied2?"copied":"copy"})})})]})]})};var Status=({s})=>{let theme=useTheme().theme,fg2=s==="completed"?theme.success:s==="failed"?theme.error:s==="error"?theme.error:s==="timeout"?theme.error:s==="interrupted"?theme.warning:theme.textMuted;return $jsx("span",{fg:fg2,children:s})},SnapshotView=(props)=>{let theme=useTheme().theme,subs2=props.snap.subagents??[],tok=subs2.reduce((n,s)=>n+(s.input_tokens??0)+(s.output_tokens??0),0),span2=props.snap.started_at&&props.snap.finished_at?dur2(props.snap.finished_at-props.snap.started_at):"\u2014";return $jsxs("box",{flexDirection:"column",width:80,children:[$jsx("text",{fg:theme.text,children:$jsx("strong",{children:props.entry.label||`${subs2.length} subagents`})}),$jsxs("text",{fg:theme.textMuted,children:[when(props.entry.finished_at)," \xB7 ",span2," \xB7 ",subs2.length," agents \xB7 ",fmt(tok)," tok"]}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,maxHeight:20,contentOptions:{flexDirection:"column"},children:subs2.map((s)=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "+"\xB7 ".repeat(s.depth)}),$jsx("span",{fg:theme.text,children:trunc5(s.goal.replace(/\s+/g," "),60)})]})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:["\u2503 "+" ".repeat(2*s.depth+2),$jsx(Status,{s:s.status}),` \xB7 ${s.tool_count}t`,s.finished_at?` \xB7 ${dur2(s.finished_at-s.started_at)}`:"",s.model?` \xB7 ${s.model}`:""]})})]},s.subagent_id))})]})};function openSpawnHistory(dialog,gw,sessionId){dialog.replace($jsx("box",{width:40,height:3,children:$jsx("text",{children:"Loading spawn history\u2026"})}));let listToken=dialog.version();gw.request("spawn_tree.list",{session_id:sessionId,limit:50}).then((r)=>{if(dialog.version()!==listToken)return;let entries2=r.entries??[];dialog.replace($jsx(DialogSelect,{title:"Spawn history",placeholder:entries2.length?"filter\u2026":"no saved spawn trees",options:entries2.map((e)=>({value:e.path,title:`${e.count.toString().padStart(2)}\xD7 ${trunc5(e.label||"(unlabeled)",40)}`,description:when(e.finished_at),category:e.session_id===sessionId?"This session":e.session_id})),onSelect:(opt)=>{let entry2=entries2.find((e)=>e.path===opt.value);dialog.replace($jsx("box",{width:40,height:3,children:$jsx("text",{children:"Loading spawn tree\u2026"})}));let token=dialog.version();gw.request("spawn_tree.load",{path:entry2.path}).then((snap2)=>{if(dialog.version()===token)dialog.replace($jsx(SnapshotView,{entry:entry2,snap:snap2}))}).catch((e)=>{if(dialog.version()===token)openAlert(dialog,"Spawn history",e instanceof Error?e.message:String(e))})}}))}).catch((e)=>{if(dialog.version()===listToken)openAlert(dialog,"Spawn history",e instanceof Error?e.message:String(e))})}var import_react77=__toESM(require_react_production(),1);var Dialog=(props)=>{let theme=useTheme().theme,keys=useKeys();useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.accept",key3))return props.onClose()});let d2=props.d,req=d2.env_requires.filter((e)=>e.required),opt=d2.env_requires.filter((e)=>!e.required),link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs("box",{flexDirection:"column",minWidth:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:`Distribution \xB7 ${props.profile}`})})}),$jsxs("box",{flexDirection:"column",children:[$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0],["Author",d2.author||void 0],["License",d2.license||void 0],["Description",d2.description||void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed",Number.isFinite(when2)?ago(when2/1000):void 0],["Owned",d2.distribution_owned.length?d2.distribution_owned.join(", "):void 0]]})]}),d2.env_requires.length?$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Environment variables"})})}),req.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Required"})}),req.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null,opt.length?$jsxs($Fragment,{children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Optional"})}),opt.map((e)=>$jsx(EnvRow,{name:e.name,desc:e.description,fallback:e.default},e.name))]}):null]}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.borderSubtle,children:`[${keys.print("dialog.cancel")}] close`})})]})},EnvRow=(props)=>{let theme=useTheme().theme,tail=[props.desc,props.fallback?`default: ${props.fallback}`:""].filter(Boolean).join(" \xB7 ");return $jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:2,flexShrink:0,children:$jsx("text",{fg:theme.textMuted,children:" "})}),$jsx("box",{width:22,flexShrink:0,children:$jsx("text",{fg:theme.accent,children:props.name})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:tail})})]})};function openDistributionInfo(dialog,opts){dialog.replace($jsx(Dialog,{profile:opts.profile,d:opts.d,yaml:opts.yaml,onClose:()=>dialog.clear()}))}function openProfileMenu(dialog,p,ops){let opts=[...ops.switch&&!p.is_active?[{category:"Switch",value:"switch",title:`Switch to '${p.name}'`,description:"restart gateway under this HERMES_HOME \u2014 ends current session"}]:[],{category:"Open",value:"soul",title:"SOUL.md",description:"edit persona/system prompt"},{category:"Open",value:"config",title:"config.yaml",description:"model, provider, toolsets"},...p.has_env?[{category:"Open",value:"env",title:".env",description:"API keys + secrets"}]:[],{category:"Open",value:"dir",title:"Directory",description:p.path},...p.distribution?[{category:"Distribution",value:"dist-info",title:"Info",description:`v${p.distribution.version}${p.distribution.source?` \xB7 ${p.distribution.source}`:""}`},{category:"Distribution",value:"dist-update",title:"Update",description:`hermes profile update ${p.name}${p.is_active?" \xB7 ends current session":""}`}]:[],...p.is_sticky?[{category:"Default",value:"unsticky",title:"Clear sticky default",description:"hermes profile use --clear"}]:[{category:"Default",value:"sticky",title:"Set as sticky default",description:`hermes profile use ${p.name}`}],{category:"Manage",value:"export",title:"Export",description:`hermes profile export ${p.name}`},...p.is_default||p.is_active?[]:[{category:"Manage",value:"delete",title:"Delete",description:"irreversible \u2014 removes config, env, memory, sessions"}]];dialog.replace($jsx(DialogSelect,{title:`Profile \xB7 ${p.name}${p.is_active?" (active)":""}`,options:opts,onSelect:(o)=>{if(o.value==="dist-info"){if(!p.distribution)return dialog.clear();return openDistributionInfo(dialog,{profile:p.name,d:p.distribution,yaml:p.sources.distribution})}if(o.value==="dist-update"){if(!p.distribution)return dialog.clear();return openUpdateDistribution(dialog,p,(force)=>ops.update(p,force))}if(dialog.clear(),o.value==="switch")return ops.switch?.();if(o.value==="soul")return openFile(p.sources.soul.file);if(o.value==="config")return openFile(p.sources.config.file);if(o.value==="env")return openFile(p.sources.env.file);if(o.value==="dir")return openFile(p.path);if(o.value==="sticky")return ops.sticky(p);if(o.value==="unsticky")return ops.unsticky();if(o.value==="export")return ops.export(p);if(o.value==="delete")return ops.remove(p)}}))}var UpdateForm=(props)=>{let theme=useTheme().theme,keys=useKeys(),[force,setForce]=import_react77.useState(!1);useKeyboard((key3)=>{if(keys.match("dialog.cancel",key3)||keys.match("dialog.deny",key3))return props.done(null);if(keys.match("dialog.confirm",key3)||keys.match("dialog.accept",key3))return props.done(force);if(key3.name==="space"||key3.name===" ")return setForce((f)=>!f)});let d2=props.p.distribution;return $jsxs("box",{flexDirection:"column",width:62,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:"Update distribution?"})})}),$jsxs("box",{flexDirection:"column",children:[$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:`'${props.p.name}' \xB7 v${d2.version}${d2.source?` \xB7 ${d2.source}`:""}`})}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:"Re-pulls from source; distribution-owned files are overwritten."})}),props.p.is_active?$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.warning,children:"\u26A0 This is the active profile. The gateway will re-spawn "+"and the current session will end."})}):null]}),$jsx("box",{height:1,children:$jsx("text",{fg:force?theme.warning:theme.textMuted,children:`${force?"[x]":"[ ]"} --force-config \xB7 also overwrite config.yaml`})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`[${keys.print("dialog.confirm")}] update [Space] toggle force [${keys.print("dialog.cancel")}] cancel`})})]})};function openUpdateDistribution(dialog,p,onConfirm){dialog.replace($jsx(UpdateForm,{p,done:(force)=>{if(dialog.clear(),force!==null)onConfirm(force)}}))}var import_react79=__toESM(require_react_production(),1);import{existsSync as existsSync18,readFileSync as readFileSync11}from"fs";import{readdir as readdir2}from"fs/promises";import{homedir as homedir7}from"os";import{join as join13,basename as basename9,dirname as dirname8}from"path";import{Database as Database2}from"bun:sqlite";var home4=()=>process.env.HOME||homedir7(),hermesHome=()=>process.env.HERMES_HOME||join13(home4(),".hermes");function root2(){let hh=hermesHome(),parent2=dirname8(hh);return basename9(parent2)==="profiles"?dirname8(parent2):hh}function profileNameFrom(hh){let parent2=dirname8(hh);return basename9(parent2)==="profiles"?basename9(hh):"default"}function activeProfileName(){return profileNameFrom(hermesHome())}function stickyDefault(){try{return readFileSync11(join13(root2(),"active_profile"),"utf-8").trim()||null}catch{return null}}var ID_RE=/^[a-z0-9][a-z0-9_-]{0,63}$/;function resolveProfileHome(name){if(name==="default")return root2();if(!ID_RE.test(name))return null;let dir=join13(root2(),"profiles",name);return existsSync18(dir)?dir:null}function readModel(dir){try{let raw=readFileSync11(join13(dir,"config.yaml"),"utf-8"),block=raw.split(/^model:\s*$/m)[1]?.split(/^\S/m)[0]??"",m2=block.match(/^\s+(?:default|model):\s*(.+)$/m)?.[1]?.trim()??raw.match(/^model:\s*(\S.+)$/m)?.[1]?.trim(),p=block.match(/^\s+provider:\s*(.+)$/m)?.[1]?.trim(),clean3=(s)=>s?.replace(/^["']|["']$/g,"")??null;return[clean3(m2),clean3(p)]}catch{return[null,null]}}async function countSkills(dir){let glob=new Bun.Glob("**/SKILL.md"),n=0;try{for await(let _2 of glob.scan({cwd:join13(dir,"skills"),onlyFiles:!0}))n++}catch{}return n}function gatewayRunning(dir){try{let raw=readFileSync11(join13(dir,"gateway.pid"),"utf-8").trim(),pid2=raw.startsWith("{")?Number(JSON.parse(raw).pid):Number(raw);if(!Number.isFinite(pid2)||pid2<=0)return!1;return process.kill(pid2,0),!0}catch{return!1}}function soul(dir){try{return readFileSync11(join13(dir,"SOUL.md"),"utf-8").replace(/^#[^\n]*\n+/,"").replace(/^\s+/,"").slice(0,400)}catch{return""}}function readDistributionManifest(dir){let path4=join13(dir,"distribution.yaml");if(!existsSync18(path4))return null;let data2=(()=>{try{return $parse(readFileSync11(path4,"utf-8"))}catch{return null}})();if(!data2||typeof data2!=="object"||Array.isArray(data2))return null;let d2=data2,name=typeof d2.name==="string"?d2.name.trim():"";if(!name)return null;let envs=(Array.isArray(d2.env_requires)?d2.env_requires:[]).flatMap((e)=>{if(!e||typeof e!=="object")return[];let r=e,n=typeof r.name==="string"?r.name.trim():"";if(!n)return[];return[{name:n,description:typeof r.description==="string"?r.description:"",required:r.required===void 0?!0:Boolean(r.required),default:typeof r.default==="string"?r.default:null}]}),owned=(Array.isArray(d2.distribution_owned)?d2.distribution_owned:[]).map((p)=>typeof p==="string"?p.trim().replace(/\/+$/,""):"").filter((p)=>p.length>0);return{name,version:typeof d2.version==="string"?d2.version:"0.1.0",description:typeof d2.description==="string"?d2.description:"",hermes_requires:typeof d2.hermes_requires==="string"?d2.hermes_requires:"",author:typeof d2.author==="string"?d2.author:"",license:typeof d2.license==="string"?d2.license:"",env_requires:envs,distribution_owned:owned,source:typeof d2.source==="string"?d2.source:"",installed_at:typeof d2.installed_at==="string"?d2.installed_at:""}}var src2=(file,label2)=>({file,relative:file.replace(home4()+"/","~/"),label:label2});async function info(name,dir,active,sticky){let[model,provider]=readModel(dir),alias=join13(home4(),".local","bin",name);return{name,path:dir,is_default:name==="default",is_active:name===active,is_sticky:name===sticky,gateway_running:gatewayRunning(dir),model,provider,has_env:existsSync18(join13(dir,".env")),skill_count:await countSkills(dir),has_alias:name!=="default"&&existsSync18(alias),soul_preview:soul(dir),distribution:readDistributionManifest(dir),sources:{dir:src2(dir,dir.replace(home4()+"/","~/")),config:src2(join13(dir,"config.yaml"),"config.yaml"),soul:src2(join13(dir,"SOUL.md"),"SOUL.md"),env:src2(join13(dir,".env"),".env"),distribution:src2(join13(dir,"distribution.yaml"),"distribution.yaml")}}}async function listProfiles(activeHome){let r=root2(),active=profileNameFrom(activeHome??hermesHome()),sticky=stickyDefault(),jobs=[];if(existsSync18(r))jobs.push(info("default",r,active,sticky));let pr=join13(r,"profiles");if(existsSync18(pr))for(let e of await readdir2(pr,{withFileTypes:!0})){if(!e.isDirectory()||!ID_RE.test(e.name))continue;jobs.push(info(e.name,join13(pr,e.name),active,sticky))}return Promise.all(jobs)}function validateName(name,existing){if(!ID_RE.test(name))return"must match [a-z0-9][a-z0-9_-]{0,63}";if(existing.includes(name))return"already exists";if(["hermes","default","test","tmp","root","sudo"].includes(name))return"reserved name";return null}function readPrefs(dir){try{let raw=JSON.parse(readFileSync11(join13(dir,"herm","tui.json"),"utf-8"));return{theme:raw.theme,eikon:raw.eikon??(raw.eikonPath?basename9(raw.eikonPath,".eikon"):void 0),keys:raw.keys?Object.keys(raw.keys).length:0}}catch{return null}}async function profileStats(dir){let sessions=null,messages=null,dbPath=join13(dir,"state.db");if(existsSync18(dbPath))try{let db=new Database2(dbPath,{readwrite:!0,create:!1}),r=db.query("SELECT COUNT(*) AS s FROM sessions WHERE message_count > 0").get(),m2=db.query("SELECT COALESCE(SUM(message_count), 0) AS m FROM sessions").get();sessions=r.s,messages=m2.m,db.close()}catch{}let crons=null;try{let jobs=await Bun.file(join13(dir,"cron","jobs.json")).json();crons=Array.isArray(jobs)?jobs.length:jobs&&typeof jobs==="object"&&Array.isArray(jobs.jobs)?jobs.jobs.length:0}catch{crons=existsSync18(join13(dir,"cron"))?0:null}return{sessions,messages,crons,prefs:readPrefs(dir)}}var ORDER3=["name","clone","alias"];function openCreateProfile(dialog,opts){return new Promise((resolve4)=>{let done=(r)=>{dialog.clear(),resolve4(r)};dialog.replace($jsx(Form,{existing:opts.existing,done}))})}var Form=({existing,done})=>{let theme=useTheme().theme,[name,setName]=import_react79.useState(""),[cloneIdx,setCloneIdx]=import_react79.useState(0),[alias,setAlias]=import_react79.useState(!0),[field,setField]=import_react79.useState("name"),options=["(fresh)",...existing],err=name?validateName(name,existing):null,valid=!!name&&!err,submit2=()=>{if(!valid)return;done({name,cloneFrom:cloneIdx===0?null:options[cloneIdx],alias})},moveField=(dir)=>{let i=ORDER3.indexOf(field);setField(ORDER3[(i+dir+ORDER3.length)%ORDER3.length])};useKeyboard((key3)=>{if(key3.name==="escape")return done(null);if(key3.name==="tab")return moveField(key3.shift?-1:1);if(key3.name==="return")return submit2();if(field==="name"){if(key3.name==="backspace")return setName((n)=>n.slice(0,-1));if(key3.raw&&key3.raw.length===1&&/[a-z0-9_-]/.test(key3.raw))return setName((n)=>n+key3.raw);return}if(field==="clone"){if(key3.name==="up")return setCloneIdx((i)=>Math.max(0,i-1));if(key3.name==="down")return setCloneIdx((i)=>Math.min(options.length-1,i+1));return}if(field==="alias"){if(key3.name==="space"||key3.name===" ")return setAlias((a)=>!a)}});let focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"New Profile"})})}),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name"})}),$jsxs("text",{children:[$jsx("span",{fg:valid||!name?theme.text:theme.error,children:name}),field==="name"?$jsx("span",{fg:theme.accent,children:"\u2588"}):null]})]}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:" a-z 0-9 _ - \xB7 lowercase"})}),$jsx("box",{height:1}),$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsx("text",{fg:theme.textMuted,children:"Clone from (\u2191\u2193)"})}),options.map((o,i)=>$jsx("box",{height:1,backgroundColor:focusBg("clone"),children:$jsxs("text",{fg:i===cloneIdx?theme.accent:theme.text,children:[i===cloneIdx?"\u25B8 ":" ",o]})},o)),$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] shell alias":"[ ] shell alias"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:valid?"Enter create \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel":err??"type a name"})})]})};var import_react81=__toESM(require_react_production(),1);import{rmSync as rmSync3,mkdtempSync as mkdtempSync4}from"fs";import{join as join14}from"path";import{tmpdir as tmpdir4}from"os";var shq=(s)=>`'${s.replace(/'/g,"'\\''")}'`;function openInstallDistribution(dialog,gw){return new Promise((resolve4)=>{askSource(dialog,gw,(r)=>{dialog.clear(),resolve4(r)})})}function askSource(dialog,gw,done){dialog.replace($jsx(Step1,{onSubmit:(source)=>preview(dialog,gw,source,done),onCancel:()=>done(null)}))}async function preview(dialog,gw,source,done){let tmp=mkdtempSync4(join14(tmpdir4(),"herm-dist-preview-")),cleanup=()=>{try{rmSync3(tmp,{recursive:!0,force:!0})}catch{}},state2={cancelled:!1},cancel=()=>{state2.cancelled=!0,cleanup(),done(null)};dialog.replace($jsx(Loading2,{label:`Cloning ${source}\u2026`,onCancel:cancel}),void 0,{ownCancel:!0});let cmd=`git clone --depth 1 --quiet ${shq(source)} ${shq(tmp)} 2>&1`,r=await gw.request("shell.exec",{command:cmd}).catch((e)=>({stdout:"",stderr:e.message,code:-1}));if(state2.cancelled)return;if(r.code!==0){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Clone failed",body:(r.stderr||r.stdout||`exit ${r.code}`).trim(),onClose:()=>done(null)}));return}let manifest3=readDistributionManifest(tmp);if(!manifest3){cleanup(),dialog.replace($jsx(ErrorBox,{title:"Not a distribution",body:`No valid distribution.yaml at the root of ${source}. A manifest must declare at minimum a 'name:' key.`,onClose:()=>done(null)}));return}dialog.replace($jsx(ConfirmStep,{source,manifest:manifest3,onConfirm:(r2)=>{cleanup(),done(r2)},onCancel:()=>{cleanup(),done(null)}}),void 0,{ownCancel:!0})}var Step1=(p)=>{let theme=useTheme().theme,[value,setValue]=import_react81.useState("");return useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:64,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Source \u2014 git URL, github.com/owner/repo, or local directory"})}),$jsxs("box",{height:1,flexDirection:"row",overflow:"hidden",children:[$jsx("box",{flexShrink:0,children:$jsx("text",{fg:theme.accent,children:"\u2503 "})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("input",{value,onInput:setValue,onSubmit:()=>{let v2=value.trim();if(v2)p.onSubmit(v2)},focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement})})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value.trim()?"Enter preview \xB7 Esc cancel":"Esc cancel"})})]})},Loading2=(p)=>{let theme=useTheme().theme;return useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel()}),$jsxs("box",{flexDirection:"column",width:54,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx(Spinner,{color:theme.accent,label:p.label})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Esc to cancel"})})]})},ErrorBox=(p)=>{let theme=useTheme().theme,keys=useKeys();return useKeyboard((key3)=>{if(keys.match("dialog.accept",key3)||keys.match("dialog.cancel",key3))return p.onClose()}),$jsxs("box",{flexDirection:"column",width:68,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.text,children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter / Esc to close"})})]})},ORDER4=["name","alias"],ConfirmStep=(p)=>{let theme=useTheme().theme,keys=useKeys(),[name,setName]=import_react81.useState(""),[alias,setAlias]=import_react81.useState(!1),[field,setField]=import_react81.useState("name"),fire=()=>p.onConfirm({source:p.source,manifest:p.manifest,name:name.trim()||null,alias}),move=(dir)=>{let i=ORDER4.indexOf(field);setField(ORDER4[(i+dir+ORDER4.length)%ORDER4.length])};useKeyboard((key3)=>{if(key3.name==="escape")return p.onCancel();if(key3.name==="tab")return move(key3.shift?-1:1);if(field!=="name"&&keys.match("dialog.accept",key3))return fire();if(field==="alias"&&(key3.name==="space"||key3.name===" "))return setAlias((a)=>!a)});let m2=p.manifest,reqEnv=m2.env_requires.filter((e)=>e.required),optEnv=m2.env_requires.filter((e)=>!e.required),focusBg=(f)=>field===f?theme.backgroundElement:void 0;return $jsxs("box",{flexDirection:"column",width:72,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Install Distribution"})})}),$jsx("box",{height:1}),$jsx(KV2,{label:"Name",value:`${m2.name}${m2.version?` v${m2.version}`:""}`,theme}),m2.description?$jsx(KV2,{label:"About",value:m2.description,theme,wrap:!0}):null,m2.author?$jsx(KV2,{label:"Author",value:m2.author,theme}):null,m2.license?$jsx(KV2,{label:"License",value:m2.license,theme}):null,m2.hermes_requires?$jsx(KV2,{label:"Requires",value:`hermes ${m2.hermes_requires}`,theme}):null,$jsx(KV2,{label:"Source",value:p.source,theme}),m2.distribution_owned.length>0?$jsx(KV2,{label:"Owns",value:m2.distribution_owned.join(", "),theme,wrap:!0}):null,m2.env_requires.length>0?$jsx(KV2,{label:"Env",value:envSummary(reqEnv,optEnv),theme}):null,$jsx("box",{height:1}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("name"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Name as"})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:field==="name"?$jsx("input",{value:name,onInput:setName,onSubmit:fire,focused:!0,textColor:theme.text,backgroundColor:theme.backgroundElement,focusedBackgroundColor:theme.backgroundElement}):$jsx("text",{fg:name?theme.text:theme.textMuted,children:name||`(${m2.name})`})})]}),$jsxs("box",{height:1,flexDirection:"row",backgroundColor:focusBg("alias"),children:[$jsx("box",{width:11,children:$jsx("text",{fg:theme.textMuted,children:"Alias"})}),$jsx("text",{fg:alias?theme.accent:theme.textMuted,children:alias?"[x] create shell wrapper":"[ ] create shell wrapper"})]}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Enter install \xB7 Tab next field \xB7 Space toggle \xB7 Esc cancel"})})]})},KV2=(p)=>$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:11,flexShrink:0,children:$jsx("text",{fg:p.theme.textMuted,children:p.label})}),$jsx("box",{flexGrow:1,minWidth:0,children:$jsx("text",{fg:p.theme.text,wrapMode:p.wrap?"word":"none",children:p.value})})]});function envSummary(req,opt){return[req.length>0?`${req.length} required (${req.map((e)=>e.name).join(", ")})`:"",opt.length>0?`${opt.length} optional`:""].filter(Boolean).join(" \xB7 ")}var running=(s)=>!s||s==="running"||s==="queued";function tree(recs,live,now){let ids=new Set(recs.map((r)=>r.subagent_id)),by=new Map;for(let r of recs){let k2=r.parent_id&&ids.has(r.parent_id)?r.parent_id:"";(by.get(k2)??by.set(k2,[]).get(k2)).push(r)}let build2=(r)=>{let kids=(by.get(r.subagent_id)??[]).map(build2),lv=live.get(r.subagent_id)??{},dur3=r.started_at!=null?Math.max(0,now-r.started_at):0,a={agents:1,tools:lv.tool_count??r.tool_count??0,dur:dur3,tok:(lv.input_tokens??0)+(lv.output_tokens??0),cost:lv.cost_usd??0,active:running(lv.status??r.status)?1:0,depth:0,hot:0};for(let k2 of kids)a={agents:a.agents+k2.agg.agents,tools:a.tools+k2.agg.tools,dur:a.dur+k2.agg.dur,tok:a.tok+k2.agg.tok,cost:a.cost+k2.agg.cost,active:a.active+k2.agg.active,depth:Math.max(a.depth,k2.agg.depth+1),hot:0};return a.hot=a.dur>0?a.tools/a.dur:0,{rec:r,agg:a,kids}};return(by.get("")??[]).map(build2)}function totals(nodes){let z2={agents:0,tools:0,dur:0,tok:0,cost:0,active:0,depth:0,hot:0};for(let n of nodes)z2.agents+=n.agg.agents,z2.tools+=n.agg.tools,z2.dur+=n.agg.dur,z2.tok+=n.agg.tok,z2.cost+=n.agg.cost,z2.active+=n.agg.active,z2.depth=Math.max(z2.depth,n.agg.depth+1);return z2.hot=z2.dur>0?z2.tools/z2.dur:0,z2}var SPARK=["\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];function spark(nodes){let w2=[],walk2=(ns,d2)=>{if(ns.length===0)return;w2[d2]=(w2[d2]??0)+ns.length;for(let n of ns)walk2(n.kids,d2+1)};if(walk2(nodes,0),w2.length===0)return"";let max=Math.max(...w2);return w2.map((v2)=>v2<=0?" ":SPARK[Math.min(7,Math.ceil(v2/max*7))]).join("")}var tk=(n)=>n<1000?String(Math.round(n)):n<1e4?`${(n/1000).toFixed(1)}k`:`${Math.round(n/1000)}k`,$$=(n)=>n<=0?"":n<0.01?"<$0.01":n<10?`$${n.toFixed(2)}`:`$${n.toFixed(1)}`,sec=(s)=>{if(s<60)return`${Math.round(s)}s`;let m2=Math.floor(s/60),r=Math.round(s-m2*60);return r===0?`${m2}m`:`${m2}m${r}s`};function summary(a){let p=[`d${a.depth}`,`${a.agents} agent${a.agents===1?"":"s"}`];if(a.tools>0)p.push(`${a.tools} tools`);if(a.dur>0)p.push(sec(a.dur));if(a.tok>0)p.push(`${tk(a.tok)} tok`);if(a.cost>0)p.push($$(a.cost));if(a.active>0)p.push(`\u26A1${a.active}`);return p.join(" \xB7 ")}function heat(hot,peak,buckets){if(hot<=0||peak<=0||buckets<=1)return 0;return Math.min(buckets-1,Math.round(Math.min(1,hot/peak)*(buckets-1)))}function peak(nodes){let p=0,walk2=(ns)=>{for(let n of ns)p=Math.max(p,n.agg.hot),walk2(n.kids)};return walk2(nodes),p}var ProfileRow=import_react83.memo((props)=>{let theme=useTheme().theme,{p,idx:i}=props,[x2,setX]=import_react83.useState(!1);return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),onMouseDown:()=>props.onEnter(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:p.is_active?theme.accent:theme.text,children:p.is_active?$jsx("strong",{children:p.name}):p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605"}):null,p.distribution?$jsx("span",{fg:theme.info,children:" \u2B22"}):null,p.gateway_running?$jsx("span",{fg:theme.success,children:" \u25CF"}):null]})}),$jsx("box",{width:4,height:1,children:$jsx("text",{fg:theme.textMuted,children:p.is_active?" you":""})}),p.is_default||p.is_active?$jsx("box",{width:3}):$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onDelete(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})}),DistBlock=import_react83.memo((props)=>{let theme=useTheme().theme,d2=props.d,req=d2.env_requires.filter((e)=>e.required).length,opt=d2.env_requires.length-req,link2=d2.source?{file:d2.source,relative:d2.source,label:d2.source}:props.yaml,when2=d2.installed_at?Date.parse(d2.installed_at):NaN;return $jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.info,children:$jsx("strong",{children:"Distribution"})})}),$jsx(KVBlock,{rows:[["Name",d2.name],["Version",`v${d2.version}`],["Requires",d2.hermes_requires?`Hermes ${d2.hermes_requires}`:void 0]]}),$jsx(KVLink,{label:"Source",source:link2,text:d2.source||props.yaml.label}),$jsx(KVBlock,{rows:[["Installed at",Number.isFinite(when2)?ago(when2/1000):void 0],["Env vars",d2.env_requires.length?`${req} required, ${opt} optional`:void 0]]})]})}),ProfileDetail=import_react83.memo((props)=>{let{theme,syntaxStyle}=useTheme(),p=props.p,s=props.stats;return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{height:1,children:$jsxs("text",{fg:theme.accent,children:[$jsx("strong",{children:p.name}),p.is_sticky?$jsx("span",{fg:theme.warning,children:" \u2605 sticky default"}):null]})}),$jsx("box",{height:1}),$jsx(KVLink,{label:"Path",source:p.sources.dir,text:p.sources.dir.relative}),$jsx(KV,{label:"Active",value:p.is_active?"yes (this session)":"no",fg:p.is_active?theme.accent:theme.textMuted}),$jsx(KV,{label:"Model",value:p.model??"\u2014"}),$jsx(KV,{label:"Provider",value:p.provider??"\u2014"}),$jsx(KV,{label:"Skills",value:String(p.skill_count)}),$jsx(KV,{label:"Sessions",value:s?s.sessions==null?"\u2014":`${fmt(s.sessions)} (${fmt(s.messages??0)} msgs)`:"\u2026"}),$jsx(KV,{label:"Cron jobs",value:s?s.crons==null?"\u2014":String(s.crons):"\u2026"}),$jsx(KV,{label:"Theme",value:s?s.prefs?.theme??"\u2014":"\u2026"}),$jsx(KV,{label:"Avatar",value:s?s.prefs?.eikon??"\u2014":"\u2026"}),s?.prefs?.keys?$jsx(KV,{label:"Keybinds",value:`${s.prefs.keys} overrides`}):null,$jsx(KV,{label:"Gateway",value:p.gateway_running?"running":"stopped",fg:p.gateway_running?theme.success:theme.textMuted}),p.has_alias?$jsx(KV,{label:"Alias",value:`${p.name} (shell)`}):null,p.distribution?$jsx(DistBlock,{d:p.distribution,yaml:p.sources.distribution}):null,$jsx("box",{height:1}),$jsx(KVLink,{label:"Config",source:p.sources.config}),$jsx(KVLink,{label:"Soul",source:p.sources.soul}),p.has_env?$jsx(KVLink,{label:"Env",source:p.sources.env}):$jsx(KV,{label:"Env",value:"\u2014"}),p.soul_preview?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"SOUL.md"})}),$jsx("markdown",{content:p.soul_preview,fg:theme.markdownText,syntaxStyle})]}):null]})})}),HOT=["\u2800","\u2801","\u2803","\u2807","\u280F","\u281F","\u283F","\u287F","\u28FF"],DelegRow=import_react83.memo((props)=>{let theme=useTheme().theme,{r,idx:i,now}=props,[x2,setX]=import_react83.useState(!1),up=r.started_at?dur2(now-r.started_at):"\u2014",hotFg=[theme.textMuted,theme.textMuted,theme.text,theme.info,theme.info,theme.accent,theme.accent,theme.warning,theme.error][props.hot]??theme.textMuted;return $jsxs("box",{id:props.id,flexDirection:"row",height:1,backgroundColor:props.selected?theme.backgroundElement:void 0,onMouseOver:()=>props.onHover(i),children:[$jsx("box",{width:2,children:$jsx("text",{fg:props.selected?theme.primary:theme.text,children:props.selected?"\u25B8 ":" "})}),$jsx("box",{width:2,children:$jsxs("text",{fg:hotFg,children:[HOT[props.hot]," "]})}),$jsx("box",{flexGrow:1,minWidth:8,height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\xB7 ".repeat(r.depth)}),$jsx("span",{fg:theme.text,children:r.goal.replace(/\s+/g," ")})]})}),$jsx("box",{width:14,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:trunc5(r.model??"",13)})}),$jsx("box",{width:5,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:String(r.tool_count??0)})}),$jsx("box",{width:8,height:1,flexDirection:"row",justifyContent:"flex-end",children:$jsx("text",{fg:theme.textMuted,children:up})}),$jsx("box",{width:3,onMouseDown:(e)=>{e.stopPropagation(),props.onKill(i)},onMouseOver:()=>setX(!0),onMouseOut:()=>setX(!1),children:$jsx("text",{fg:x2?theme.error:theme.textMuted,children:" \u2715"})})]})});function preorder(recs){let byParent=new Map;for(let r of recs){let k2=r.parent_id??null;(byParent.get(k2)??byParent.set(k2,[]).get(k2)).push(r)}let out=[],seen=new Set,walk2=(k2)=>{for(let r of byParent.get(k2)??[]){if(seen.has(r.subagent_id))continue;seen.add(r.subagent_id),out.push(r),walk2(r.subagent_id)}};walk2(null);for(let r of recs)if(!seen.has(r.subagent_id))out.push(r);return out}var DelegDetail=import_react83.memo((props)=>{let theme=useTheme().theme,{r,live,agg,now}=props,tc=live?.tool_count??r.tool_count??0,tr=trail(r.subagent_id);return $jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsxs("box",{flexDirection:"column",width:"100%",children:[$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.accent,wrapMode:"word",children:$jsx("strong",{children:r.goal})})}),agg&&agg.agents>1?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:summary(agg)})}):null,$jsx("box",{height:1}),$jsx(KVBlock,{rows:[["Status",live?.status??r.status??"running"],["Model",r.model??"\u2014"],["Depth",String(r.depth)],["Parent",r.parent_id??"(root)"],["Uptime",r.started_at?dur2(now-r.started_at):"\u2014"],["Tools",String(tc)],["Tokens",live?`${fmt(live.input_tokens??0)} in / ${fmt(live.output_tokens??0)} out`:void 0],["Cost",live?.cost_usd!=null?`$${live.cost_usd.toFixed(4)}`:void 0]]}),live?.thinking?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"thinking"})}),$jsx("box",{minHeight:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:trunc5(live.thinking,200)})})]}):null,tr.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"recent tools"})}),tr.slice(-8).map((t2,i)=>$jsx("box",{height:1,overflow:"hidden",children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:"\u2503 "}),$jsx("span",{fg:theme.text,children:t2.name.padEnd(14)}),$jsx("span",{fg:theme.textMuted,children:t2.preview?trunc5(t2.preview.replace(/\s+/g," "),40):""})]})},i))]}):null]})})}),Agents=import_react83.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),[pane,setPane]=import_react83.useState("profiles"),[pView,setPView]=import_react83.useState("list"),[profiles,setProfiles]=import_react83.useState([]),[deleg,setDeleg]=import_react83.useState(null),[liveMap,setLiveMap]=import_react83.useState(()=>new Map),[now,setNow]=import_react83.useState(()=>Date.now()/1000),[pSel,setPSel]=import_react83.useState(0),[dSel,setDSel]=import_react83.useState(0),[err,setErr]=import_react83.useState(""),[delegErr,setDelegErr]=import_react83.useState(""),delegGen=import_react83.useRef(0),active=preorder(deleg?.active??[]),nodes=tree(deleg?.active??[],liveMap,now),all=totals(nodes),hotPeak=peak(nodes),aggOf=new Map;{let walk2=(ns)=>{for(let n of ns)aggOf.set(n.rec.subagent_id,n.agg),walk2(n.kids)};walk2(nodes)}let live=import_react83.useRef({profiles,active});live.current={profiles,active};let gwHome=import_react83.useRef(void 0),[stats,setStats]=import_react83.useState(()=>new Map),[sticky,setSticky]=import_react83.useState(stickyDefault),loadProfiles=import_react83.useCallback(()=>{setStats(new Map),setSticky(stickyDefault()),listProfiles(gwHome.current).then((ps)=>{setProfiles(ps),setErr("")}).catch((e)=>setErr(`profiles: ${e.message}`))},[]);import_react83.useEffect(()=>{gw.request("config.get",{key:"profile"}).then((r)=>{gwHome.current=r.home}).catch(()=>{}).finally(loadProfiles)},[gw,loadProfiles]);let loadDeleg=import_react83.useCallback(()=>{let current=++delegGen.current;gw.request("delegation.status").then((r)=>{if(delegGen.current!==current)return;setDeleg(r),setNow(Date.now()/1000),setDelegErr("")}).catch((e)=>{if(delegGen.current===current)setDelegErr(e instanceof Error?e.message:String(e))})},[gw]);import_react83.useEffect(loadDeleg,[loadDeleg]),import_react83.useEffect(()=>()=>{delegGen.current++},[]),import_react83.useEffect(()=>{if(!props.focused)return;let ms2=(deleg?.active.length??0)>0?1500:5000,t2=setInterval(loadDeleg,ms2);return()=>clearInterval(t2)},[props.focused,deleg?.active.length,loadDeleg]),useGatewayEvent((ev)=>{if(!ev.type.startsWith("subagent."))return;let p=ev.payload,id=p.subagent_id;if(!id)return;if(setLiveMap((prev)=>{let next=new Map(prev),cur=next.get(id)??{tool_count:0};switch(ev.type){case"subagent.start":next.set(id,{tool_count:0});break;case"subagent.tool":next.set(id,{...cur,tool_count:cur.tool_count+1,last_tool:p.tool_name,last_preview:p.tool_preview});break;case"subagent.thinking":next.set(id,{...cur,thinking:p.text});break;case"subagent.complete":next.set(id,{...cur,status:p.status,input_tokens:p.input_tokens,output_tokens:p.output_tokens,cost_usd:p.cost_usd});break}return next}),ev.type==="subagent.start"||ev.type==="subagent.complete")loadDeleg()});let sh=import_react83.useCallback((cmd2)=>gw.request("shell.exec",{command:cmd2}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||"exit "+r.code).trim());return r.stdout}),[gw]),pHover=import_react83.useCallback((i)=>setPSel(i),[]),dHover=import_react83.useCallback((i)=>setDSel(i),[]),pDelete=import_react83.useCallback(async(i)=>{let p=live.current.profiles[i];if(!p||p.is_default||p.is_active)return;let warn=p.gateway_running?`
@@ -4120,7 +4120,7 @@ ${r.stdout}`.toLowerCase();return r.code!==0&&s.includes("--kind")&&(s.includes(
4120
4120
  `)[0].slice(0,200)}`}):null]},r.id)})]}):null,d2.events.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Events (${d2.events.length})`})}),d2.events.map((e)=>$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.textMuted,children:`${ago(e.created_at).padEnd(10)} `}),$jsx("span",{fg:theme.text,children:e.kind}),e.payload?$jsx("span",{fg:theme.textMuted,children:` ${JSON.stringify(e.payload)}`}):null]})},e.id))]}):null,d2.comments.length>0?$jsxs($Fragment,{children:[$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.textMuted,children:`Comments (${d2.comments.length})`})}),d2.comments.map((c,i)=>$jsxs("box",{flexDirection:"column",children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${c.author} \xB7 ${ago(c.at)}`})}),$jsx("text",{wrapMode:"word",children:c.body})]},i))]}):null,p.on&&cur==="comment"?$jsx("box",{height:1,marginTop:1,children:$jsx("text",{fg:theme.accent,children:"Enter add comment"})}):null]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.on?"Tab/\u2191\u2193 field Enter edit Esc grid a assign c comment l log":"Tab into pane a assign c comment u unblock d archive l log N child"})})]})}),Kanban=import_react92.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),dialog=useDialog(),toast=useToast(),dims=useTerminalDimensions(),keys=useKeys(),[boards,setBoards]=import_react92.useState(listBoards),[data2,setData]=import_react92.useState(()=>new Map(boards.map((b2)=>[b2.slug,boardStateOf(b2.slug)]))),diagnostics=useKanbanDiagnostics(gw),diags=diagnostics.data,[masks,setMasks]=import_react92.useState(()=>maskFromPrefs(load2().kanban?.masks)),[open3,setOpen]=import_react92.useState(()=>{let saved=load2().kanban?.open;if(saved)return new Set(saved);let init=currentBoard();return new Set(listBoards().filter((b2)=>{let state3=boardStateOf(b2.slug);return b2.slug===init||[...state3.columns.values()].some((v2)=>v2.length>0)||!!state3.error}).map((b2)=>b2.slug))}),[at,setAt]=import_react92.useState(currentBoard),[tier,setTier]=import_react92.useState("grid"),[col,setCol]=import_react92.useState(0),[row3,setRow]=import_react92.useState(0),[chip2,setChip]=import_react92.useState(0),[paneSel,setPaneSel]=import_react92.useState(0),[pane,setPane]=import_react92.useState(null),[blocks,setBlocks]=import_react92.useState(()=>new Map),outer=import_react92.useRef(null),load4=import_react92.useCallback(()=>{let bs=listBoards();setBoards(bs),setData(new Map(bs.map((b2)=>[b2.slug,boardStateOf(b2.slug)]))),setPane((p)=>p?.kind==="detail"?((d2)=>d2?{...p,d:d2}:null)(detailOf(p.slug,p.d.id)):p),diagnostics.refresh(bs)},[diagnostics.refresh]);import_react92.useEffect(load4,[load4]),import_react92.useEffect(()=>{persist(masks,open3)},[masks,open3]);let maskOf=(s)=>masks.get(s)??EMPTY2,wide=dims.width>=160,maxH=Math.max(8,dims.height-16),sections=import_react92.useMemo(()=>{let built=boards.map((b2)=>{let state3=data2.get(b2.slug)??boardStateOf(b2.slug),d2=state3.columns,flat=STATUSES.flatMap((s)=>d2.get(s)??[]),total=flat.length,who=[...new Set(flat.map((t2)=>t2.assignee).filter((v2)=>!!v2))].sort(),pri=[...new Set(flat.map((t2)=>t2.priority).filter((n)=>n>0))].sort((a,z2)=>z2-a),chips=[...who.map((v2)=>({kind:"who",v:v2})),...pri.map((v2)=>({kind:"pri",v:v2})),...STATUSES.map((v2)=>({kind:"status",v:v2}))],m2=maskOf(b2.slug),cols3=STATUSES.filter((s)=>admits(m2.status,s)).map((s)=>({status:s,tasks:(d2.get(s)??[]).filter((t2)=>pass(t2,m2))})).filter((c)=>wide||c.tasks.length>0),shown=cols3.reduce((a,c)=>a+c.tasks.length,0),tall=cols3.reduce((a,c)=>Math.max(a,c.tasks.length),0);return{board:b2,cols:cols3,chips,total,shown,running:d2.get("running")?.length??0,cap:Math.min(maxH,Math.max(5,3+2*tall)),error:state3.error,corruptBackups:state3.corruptBackups}});return[...built.filter((s)=>s.total>0),...built.filter((s)=>s.total===0)]},[boards,data2,masks,wide,maxH]),idx=sections.findIndex((s)=>s.board.slug===at),sec3=sections[idx]??sections[0],cols2=sec3?.cols??[],clampCol=Math.min(col,Math.max(0,cols2.length-1)),cur=cols2[clampCol],task=tier==="grid"||tier==="pane"?cur?.tasks[Math.min(row3,Math.max(0,(cur?.tasks.length??1)-1))]:void 0,grand=sections.reduce((a,s)=>a+s.total,0),running2=sections.reduce((a,s)=>a+s.running,0);import_react92.useEffect(()=>{if(pane?.kind!=="detail")return;if(tier!=="grid"&&tier!=="pane"){setPane(null);return}if(!task){setPane(null);return}if(pane.slug===at&&pane.d.id===task.id)return;let d2=detailOf(at,task.id);setPane(d2?{kind:"detail",slug:at,d:d2}:null),setPaneSel(0)},[task?.id,at,tier]),import_react92.useEffect(()=>{if(!props.focused||running2===0)return;let t2=setInterval(load4,3000);return()=>clearInterval(t2)},[props.focused,running2,load4]),import_react92.useEffect(()=>{outer.current?.scrollChildIntoView(`kb-sec-${at}`)},[at,open3]);let sh=import_react92.useCallback((argv,ok)=>gw.request("shell.exec",{command:`hermes kanban --board ${q3(at)} ${argv}`}).then((r)=>{if(r.code!==0)throw Error((r.stderr||r.stdout||`exit ${r.code}`).trim());if(ok)toast.show({variant:"success",message:ok});return resetKanban(),load4(),r.stdout}).catch((e)=>void toast.show({variant:"error",message:trunc5(e.message,120)})),[gw,toast,load4,at]),blockSupport=import_react92.useCallback(async(s)=>{let cur2=blocks.get(s);if(cur2==="yes"||cur2==="no")return cur2;let next2=await gw.request("shell.exec",{command:`hermes kanban --board ${q3(s)} block --help`}).then((r)=>supportsKind(r)?"yes":"no").catch(()=>"no");return setBlocks((m2)=>{let out=new Map(m2);return out.set(s,next2),out}),next2},[blocks,gw]),runBlock=import_react92.useCallback((t2,reason,kind2)=>{let slug2=live.current.at,arg=reason?` ${q3(reason)}`:"",suffix2=kind2?` --kind ${q3(kind2)}`:"",ok=kind2==="dependency"?`Dependency-wait ${t2.id}`:`Blocked ${t2.id}`;return gw.request("shell.exec",{command:`hermes kanban --board ${q3(slug2)} block ${q3(t2.id)}${arg}${suffix2}`}).then((r)=>{if(unsupportedKind(r)&&kind2)throw setBlocks((m2)=>{let out=new Map(m2);return out.set(slug2,"no"),out}),Error("active Hermes CLI does not support typed block kinds; choose generic block");if(r.code!==0)throw Error((r.stderr||r.stdout||`exit ${r.code}`).trim());return toast.show({variant:"success",message:ok}),resetKanban(),load4(),r.stdout}).catch((e)=>void toast.show({variant:"error",message:trunc5(e.message,120)}))},[gw,toast,load4]),writes=import_react92.useRef(Promise.resolve()),patchDirect=import_react92.useCallback((id,p,ok)=>{let board=at;writes.current=writes.current.then(async()=>{if(!await patch(board,id,p))throw Error(`no such task: ${id}`);toast.show({variant:"success",message:ok}),load4()}).catch((e)=>{toast.show({variant:"error",message:trunc5(e.message,120)})})},[at,toast,load4]),enterTop=(s)=>{setAt(s.board.slug),setTier("head"),setChip(0),setRow(0)},enterBottom=(s)=>{if(setAt(s.board.slug),setChip(Math.max(0,s.chips.length-1)),open3.has(s.board.slug)&&s.shown>0){let nc=Math.min(col,Math.max(0,s.cols.length-1));setTier("grid"),setCol(nc),setRow(Math.max(0,(s.cols[nc]?.tasks.length??1)-1));return}if(open3.has(s.board.slug)){setTier("filter");return}setTier("head")},stepBoard=(d2)=>{let n=idx+d2;return n<0||n>=sections.length?null:sections[n]},goBoard=import_react92.useCallback((d2)=>{let n=(idx+d2+sections.length)%sections.length,s=sections[n];setAt(s.board.slug),setTier("head"),setCol(0),setRow(0),setChip(0),setOpen((o)=>o.has(s.board.slug)?o:new Set(o).add(s.board.slug))},[idx,sections]),flip=import_react92.useCallback((c)=>setMasks((m2)=>{let cur2=m2.get(at)??EMPTY2,who=new Map(cur2.who),pri=new Map(cur2.pri),status2=new Map(cur2.status),g=c.kind==="who"?who:c.kind==="pri"?pri:status2,next2=cycle(g.get(c.v)??"off");next2==="off"?g.delete(c.v):g.set(c.v,next2);let out=new Map(m2);return out.set(at,{who,pri,status:status2}),setRow(0),out}),[at]),toggle=import_react92.useCallback((s)=>setOpen((o)=>{let n=new Set(o);return n.has(s)?n.delete(s):n.add(s),n}),[]),newBoard=import_react92.useCallback(()=>openTextPrompt(dialog,{title:"New board",label:"Slug (a-z, 0-9, -_)"}).then((v2)=>{if(!v2)return;return gw.request("shell.exec",{command:`hermes kanban boards create ${q3(v2)}`}).then((r)=>r.code===0?(toast.show({variant:"success",message:`Board '${v2}' created`}),resetKanban(),load4(),setAt(v2),setTier("head")):Promise.reject(Error((r.stderr||r.stdout).trim()))).catch((e)=>toast.show({variant:"error",message:trunc5(e.message,120)}))}),[dialog,gw,toast,load4]),live=import_react92.useRef({task,at,sec:sec3});live.current={task,at,sec:sec3};let create=import_react92.useCallback((parent2)=>openCreateTask(dialog,{assignees:assignees(live.current.at),parent:parent2?{id:parent2.id,title:parent2.title}:void 0}).then((d2)=>{if(!d2)return;let ws=d2.workspace.kind==="scratch"?"":d2.workspace.kind==="worktree"?"--workspace worktree":`--workspace ${q3(`dir:${d2.workspace.path}`)}`,flags=[d2.assignee?`--assignee ${q3(d2.assignee)}`:"",d2.body?`--body ${q3(d2.body)}`:"",d2.priority?`--priority ${d2.priority}`:"",d2.parent?`--parent ${q3(d2.parent)}`:"",d2.triage?"--triage":"",d2.tenant?`--tenant ${q3(d2.tenant)}`:"",d2.project?`--project ${q3(d2.project)}`:"",ws,d2.maxRuntime?`--max-runtime ${q3(d2.maxRuntime)}`:"",...d2.skills.map((s)=>`--skill ${q3(s)}`)].filter(Boolean).join(" ");return sh(`create ${q3(d2.title)} ${flags}`.trim(),`Created${d2.triage?" (triage)":""}${d2.assignee?` \u2192 ${d2.assignee}`:""}`)}),[dialog,sh]),assign=import_react92.useCallback((t2)=>{let opts=[{title:"(unassigned)",value:"none"},...assignees(live.current.at).map((n)=>({title:n,value:n}))];dialog.replace($jsx(DialogSelect,{title:`Assign ${t2.id}`,options:opts,current:t2.assignee??"none",placeholder:"Search profiles\u2026",onSelect:(o)=>{dialog.clear(),sh(`assign ${q3(t2.id)} ${q3(o.value)}`,o.value==="none"?`Unassigned ${t2.id}`:`${t2.id} \u2192 ${o.value}`)}}))},[dialog,sh]),comment=import_react92.useCallback((t2)=>openTextPrompt(dialog,{title:`Comment on ${t2.id}`,label:t2.title}).then((v2)=>v2&&sh(`comment ${q3(t2.id)} ${q3(v2)} --author user`,"Comment added")),[dialog,sh]),unblock=import_react92.useCallback((t2)=>{if(t2.status!=="blocked"&&t2.status!=="scheduled")return void toast.show({variant:"info",message:`${t2.id} is ${t2.status}, not blocked/scheduled`});if(t2.status==="scheduled")return void sh(`unblock ${q3(t2.id)}`,`Released ${t2.id}`);return openTextPrompt(dialog,{title:`Unblock ${t2.id}`,label:"Answer (posted as comment, then task \u2192 ready)"}).then((v2)=>{if(v2)return sh(`comment ${q3(t2.id)} ${q3(v2)} --author user`)}).then(()=>sh(`unblock ${q3(t2.id)}`,`Unblocked ${t2.id}`))},[dialog,sh,toast]),archive=import_react92.useCallback((t2)=>openConfirm(dialog,{title:"Archive task?",danger:!0,yes:"archive",body:`${t2.id} \xB7 ${trunc5(t2.title,60)}
4121
4121
 
4122
4122
  Moves to 'archived' and ends any open run. Children stay; their dependency on this task is treated as satisfied.`}).then((ok)=>{if(ok)sh(`archive ${q3(t2.id)}`,`Archived ${t2.id}`)}),[dialog,sh]),parseSpecify=(out)=>out.split(`
4123
- `).flatMap((l)=>l.trim()?[JSON.parse(l)]:[]),specify=import_react92.useCallback((t2)=>{if(t2.status!=="triage")return void toast.show({variant:"info",message:`${t2.id} is ${t2.status}, not triage`});return sh(`specify ${q3(t2.id)} --json`).then((out)=>{if(out==null)return;let r=parseSpecify(out)[0];if(!r)return;if(!r.ok)return void toast.show({variant:"error",message:`specify ${r.task_id}: ${trunc5(r.reason??"failed",100)}`});toast.show({variant:"success",message:r.new_title?`Specified ${r.task_id} \u2192 ${trunc5(r.new_title,60)}`:`Specified ${r.task_id} \u2192 todo`})})},[sh,toast]),specifyAll=import_react92.useCallback(()=>{let triage=live.current.sec?.cols.find((c)=>c.status==="triage")?.tasks.length??0;if(triage===0)return void toast.show({variant:"info",message:`No 'triage' tasks on ${live.current.at}`});return openConfirm(dialog,{title:`Specify all \xB7 ${live.current.at}`,body:`${triage} task${triage===1?"":"s"} in 'triage'. Auxiliary LLM expands each body and promotes to todo.`,yes:"specify"}).then((go)=>{if(!go)return;return sh("specify --all --json").then((out)=>{if(out==null)return;let rows3=parseSpecify(out),ok=rows3.filter((r)=>r.ok).length,bad=rows3.length-ok;toast.show({variant:ok===0&&bad>0?"error":"success",message:`Specified ${ok}/${rows3.length}${bad?` (${bad} failed)`:""}`})})})},[dialog,sh,toast]),dispatch=import_react92.useCallback(()=>{let ready=live.current.sec?.cols.find((c)=>c.status==="ready")?.tasks.length??0;if(ready===0)return void toast.show({variant:"info",message:`No 'ready' tasks on ${live.current.at}`});return openConfirm(dialog,{title:`Dispatch \xB7 ${live.current.at}`,body:`${ready} task${ready===1?"":"s"} in 'ready'. Spawns one worker per task (one pass).`,yes:"dispatch"}).then((ok)=>{if(!ok)return;sh("dispatch --json").then((out)=>{if(out==null)return;let r=parseDispatchResult(out),spawned2=r.spawned.length,deferred=r.skipped_per_profile_capped.length,defaults=r.auto_assigned_default.length,unassigned=r.skipped_unassigned.length,nonspawnable=r.skipped_nonspawnable.length,failed=dispatchFailures(r).length,guarded2=dispatchGuarded(r).length,parts2=[`${spawned2} spawned`];if(defaults)parts2.push(`${defaults} defaulted`);if(deferred)parts2.push(`${deferred} deferred`);if(unassigned)parts2.push(`${unassigned} unassigned`);if(nonspawnable)parts2.push(`${nonspawnable} non-spawnable`);if(failed)parts2.push(`${failed} failed`);if(guarded2)parts2.push(`${guarded2} guarded`);let more=dispatchDetails(r);toast.show({variant:dispatchVariant(r),message:`Dispatch: ${parts2.join(" \xB7 ")}`,action:more?{label:"details",run:()=>setPane({kind:"dispatch",slug:live.current.at,text:more})}:void 0})}).catch((e)=>void toast.show({variant:"error",message:trunc5(e.message,120)}))})},[dialog,sh,toast]),showLog=import_react92.useCallback((t2)=>{let s=live.current.at,text4=tailLogOf(s,t2.id);if(text4==null)return void toast.show({variant:"info",message:`No worker log for ${t2.id}`});setPane({kind:"log",slug:s,id:t2.id,text:text4})},[toast]),editTitle=import_react92.useCallback((t2)=>openTextPrompt(dialog,{title:"Edit title",label:t2.id,initial:t2.title}).then((v2)=>v2!==null&&v2!==void 0&&patchDirect(t2.id,{title:v2},`Updated ${t2.id}`)),[dialog,patchDirect]),editBody=import_react92.useCallback((t2)=>openTextPrompt(dialog,{title:"Edit body",label:t2.id,initial:t2.body??""}).then((v2)=>{if(v2===null||v2===void 0)return;patchDirect(t2.id,{body:v2},`Updated ${t2.id}`)}),[dialog,patchDirect]),editPriority=import_react92.useCallback((t2)=>{let opts=Array.from({length:10},(_2,i)=>({title:i===0?"P0 (none)":`P${i}`,value:String(i)}));dialog.replace($jsx(DialogSelect,{title:`Priority for ${t2.id}`,options:opts,current:String(t2.priority),filterable:!1,onSelect:(o)=>{dialog.clear(),patchDirect(t2.id,{priority:Number(o.value)},`${t2.id} \u2192 P${o.value}`)}}))},[dialog,patchDirect]),editResult=import_react92.useCallback((t2)=>{if(t2.status!=="done")return void toast.show({variant:"info",message:`${t2.id} is not done`});return openTextPrompt(dialog,{title:"Edit result",label:t2.id,initial:t2.result??""}).then((v2)=>{if(v2==null)return;sh(`edit ${q3(t2.id)} --result ${q3(v2)}`,`Updated ${t2.id} result`)})},[dialog,sh,toast]),block=import_react92.useCallback((t2)=>{blockSupport(live.current.at).then((support)=>{if(support==="no")return openTextPrompt(dialog,{title:`Block ${t2.id}`,label:"Reason (optional; generic block \u2014 active CLI has no --kind)"}).then((r)=>{if(r!==null)runBlock(t2,r,"")});let opts=[{title:"generic",value:"",description:"legacy block without --kind"},{title:"needs input",value:"needs_input",description:"human answer required"},{title:"dependency",value:"dependency",description:"wait in todo until parents finish"},{title:"capability",value:"capability",description:"missing tool, credential, or profile capability"},{title:"transient",value:"transient",description:"temporary/flaky condition"}];dialog.replace($jsx(DialogSelect,{title:`Block kind for ${t2.id}`,options:opts,current:t2.block_kind??"",filterable:!1,onSelect:async(o)=>{dialog.clear();let r=await openTextPrompt(dialog,{title:`Block ${t2.id}`,label:"Reason (optional, posted as comment)"});if(r!==null)runBlock(t2,r,o.value)}}))})},[dialog,blockSupport,runBlock]),editStatus=import_react92.useCallback((t2)=>{let opts=[];if(t2.status!=="done")opts.push({title:"done",value:"complete",description:"mark complete (prompts for result)"});if(t2.status!=="blocked")opts.push({title:"blocked",value:"block",description:"mark blocked (choose kind, prompts for reason)"});if(t2.status!=="scheduled")opts.push({title:"scheduled",value:"schedule",description:"park until externally unblocked (prompts for reason)"});if(t2.status==="blocked"||t2.status==="scheduled")opts.push({title:"ready",value:"unblock",description:t2.status==="scheduled"?"release back to ready":"return to ready"});opts.push({title:"archived",value:"archive",description:"archive (terminal)"}),dialog.replace($jsx(DialogSelect,{title:`Status for ${t2.id}`,options:opts,current:t2.status,filterable:!1,onSelect:async(o)=>{if(dialog.clear(),o.value==="complete"){let res=await openTextPrompt(dialog,{title:`Complete ${t2.id}`,label:"Result (optional)",initial:t2.result??""}),flag=res?` --result ${q3(res)}`:"";sh(`complete ${q3(t2.id)}${flag}`,`Completed ${t2.id}`);return}if(o.value==="block")return block(t2);if(o.value==="schedule"){let r=await openTextPrompt(dialog,{title:`Schedule ${t2.id}`,label:"Reason (optional, posted as comment)"}),arg=r?` ${q3(r)}`:"";sh(`schedule ${q3(t2.id)}${arg}`,`Scheduled ${t2.id}`);return}if(o.value==="unblock")return void sh(`unblock ${q3(t2.id)}`,`Unblocked ${t2.id}`);if(o.value==="archive")return void archive(t2)}}))},[dialog,sh,archive,block]),editParents=import_react92.useCallback((t2)=>{let cur2=(pane?.kind==="detail"&&pane.d.id===t2.id?pane.d:detailOf(at,t2.id))?.parents??[],d2=(data2.get(at)??boardStateOf(at)).columns,opts=STATUSES.flatMap((s)=>d2.get(s)??[]).filter((x2)=>x2.id!==t2.id).map((x2)=>({title:x2.id,description:trunc5(x2.title,50),value:x2.id,category:cur2.includes(x2.id)?"linked":"available"}));dialog.replace($jsx(DialogSelect,{title:`Parents for ${t2.id}`,options:opts,placeholder:"Select to toggle link\u2026",onSelect:(o)=>{if(dialog.clear(),cur2.includes(o.value))sh(`unlink ${q3(o.value)} ${q3(t2.id)}`,`Unlinked ${o.value}`);else sh(`link ${q3(o.value)} ${q3(t2.id)}`,`Linked ${o.value}`)}}))},[dialog,sh,data2,at,pane]),openField=import_react92.useCallback((f,t2)=>{if(f==="title")return void editTitle(t2);if(f==="body")return void editBody(t2);if(f==="assignee")return assign(t2);if(f==="priority")return editPriority(t2);if(f==="status")return editStatus(t2);if(f==="parents")return editParents(t2);if(f==="result")return void editResult(t2);if(f==="comment")return void comment(t2)},[editTitle,editBody,assign,editPriority,editStatus,editParents,editResult,comment]),ACTS=import_react92.useMemo(()=>[{key:"n",title:"New task",when:()=>!0,run:()=>void create()},{key:"N",title:"New child",when:(t2)=>!!t2,run:(t2)=>void create(t2)},{key:"a",title:"Assign",when:(t2)=>!!t2,run:(t2)=>void assign(t2)},{key:"c",title:"Comment",when:(t2)=>!!t2,run:(t2)=>void comment(t2)},{key:"s",title:"Specify",when:(t2)=>t2?.status==="triage",run:(t2)=>void specify(t2)},{key:"S",title:"Specify all",when:()=>!0,run:()=>void specifyAll()},{key:"u",title:"Unblock",when:(t2)=>t2?.status==="blocked"||t2?.status==="scheduled",run:(t2)=>void unblock(t2)},{key:"d",title:"Archive",when:(t2)=>!!t2,run:(t2)=>void archive(t2)},{key:"l",title:"Worker log",when:(t2)=>!!t2,run:(t2)=>showLog(t2)},{key:"b",title:"New board",when:()=>!0,run:()=>void newBoard()},{key:"D",title:"Dispatch",when:()=>!0,run:()=>void dispatch()}],[create,assign,comment,specify,specifyAll,unblock,archive,showLog,newBoard,dispatch]),isOpen=open3.has(at),paneOpen=pane?.kind==="detail",paneFields=paneOpen?fieldsFor(pane.d):[];useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.name==="escape"&&pane){if(tier==="pane"){setTier("grid");return}return setPane(null)}if(keys.match("list.refresh",key3))return load4();if(key3.name==="tab"){if(paneOpen&&tier!=="pane"){setTier("pane"),setPaneSel(0);return}if(tier==="pane"){let n=paneFields.length;if(n===0)return;let d2=key3.shift?-1:1;setPaneSel((s)=>(s+d2+n)%n);return}return goBoard(key3.shift?-1:1)}if(tier==="pane"){let t3=live.current.task;if(!t3||!paneOpen)return;let f=paneFields[Math.min(paneSel,paneFields.length-1)];if(key3.name==="up"){let n=paneFields.length;if(n===0)return;return setPaneSel((s)=>(s-1+n)%n)}if(key3.name==="down"){let n=paneFields.length;if(n===0)return;return setPaneSel((s)=>(s+1)%n)}if(key3.name==="return")return openField(f,t3);let hit2=ACTS.find((a)=>a.key===key3.raw&&a.when(t3));if(hit2)return hit2.run(t3);return}if(key3.name==="space"||key3.name===" "){if(tier==="head")return toggle(at);if(tier==="filter"&&sec3?.chips[chip2])return flip(sec3.chips[chip2]);return}if(key3.name==="down"){if(tier==="head"){if(isOpen)return setTier("filter");let n2=stepBoard(1);return n2?enterTop(n2):void 0}if(tier==="filter"){if(sec3&&sec3.shown>0){setTier("grid"),setRow(0);return}let n2=stepBoard(1);return n2?enterTop(n2):void 0}if(row3<(cur?.tasks.length??1)-1)return setRow((r)=>r+1);let n=stepBoard(1);return n?enterTop(n):void 0}if(key3.name==="up"){if(tier==="head"){let p=stepBoard(-1);return p?enterBottom(p):void 0}if(tier==="filter")return setTier("head");if(row3>0)return setRow((r)=>r-1);return setTier("filter")}if(key3.name==="left"){if(tier==="filter")return setChip((c)=>Math.max(0,c-1));if(tier==="grid")return setCol((c)=>{let n=Math.max(0,c-1);return setRow(0),n});return}if(key3.name==="right"){if(tier==="filter")return setChip((c)=>Math.min((sec3?.chips.length??1)-1,c+1));if(tier==="grid")return setCol((c)=>{let n=Math.min(cols2.length-1,c+1);return setRow(0),n});return}if(key3.name==="return"){if(tier==="head")return toggle(at);if(tier==="filter"&&sec3?.chips[chip2])return flip(sec3.chips[chip2]);if(task)return setPane((p)=>p?.kind==="detail"&&p.d.id===task.id?null:((d2)=>d2?{kind:"detail",slug:at,d:d2}:null)(detailOf(at,task.id)));return}let t2=live.current.task,hit=ACTS.find((a)=>a.key===key3.raw&&a.when(t2));if(hit)return hit.run(t2)});let hint=import_react92.useMemo(()=>{let t2=task;return[tier==="pane"?"Esc grid":"Tab board",tier==="head"?"\u2191\u2193 nav Space fold":tier==="filter"?"\u2190\u2192 chip Space toggle":tier==="pane"?"Tab/\u2191\u2193 field Enter edit Esc grid":"\u2190\u2192\u2191\u2193 nav Enter detail",...ACTS.filter((a)=>a.when(t2)).map((a)=>`${a.key} ${a.title.toLowerCase()}`),`${keys.print("list.refresh")} reload`].join(" ")},[ACTS,keys,task,tier]),onHead=import_react92.useCallback((s)=>{setAt(s),setTier("head"),toggle(s)},[toggle]),onChip=import_react92.useCallback((s,i,c)=>{setAt(s),setTier("filter"),setChip(i),flip(c)},[flip]),onPick=import_react92.useCallback((s,ci,ri,id)=>{setAt(s),setTier("grid"),setCol(ci),setRow(ri),setOpen((o)=>o.has(s)?o:new Set(o).add(s));let d2=detailOf(s,id);if(d2)setPane({kind:"detail",slug:s,d:d2})},[]);return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Kanban \xB7 ${sections.length} board${sections.length===1?"":"s"} \xB7 ${grand} task${grand===1?"":"s"}${running2?` \xB7 ${running2} running`:""}`,children:$jsx("scrollbox",{id:"kb-board-scroll",ref:outer,scrollY:!0,flexGrow:1,verticalScrollbarOptions:NOBAR,children:$jsx("box",{flexDirection:"column",width:"100%",children:sections.map((s)=>{let on=s.board.slug===at,secOpen=open3.has(s.board.slug),m2=maskOf(s.board.slug),filt=m2.who.size+m2.pri.size+m2.status.size,dg=diags.get(s.board.slug)??EMPTY_DIAG;return $jsxs("box",{id:`kb-sec-${s.board.slug}`,flexDirection:"column",flexShrink:0,marginBottom:1,children:[$jsx("box",{height:1,onMouseDown:()=>onHead(s.board.slug),backgroundColor:on&&tier==="head"?theme.backgroundElement:void 0,children:$jsxs("text",{children:[$jsx("span",{fg:on?theme.accent:theme.textMuted,children:secOpen?"\u25BE ":"\u25B8 "}),$jsx("span",{fg:on?theme.primary:theme.text,children:$jsx("strong",{children:s.board.name})}),$jsx("span",{fg:theme.textMuted,children:s.error?` \xB7 ${s.error.kind}`:s.corruptBackups.length>0?` \xB7 ${s.corruptBackups.length} corrupt backup${s.corruptBackups.length===1?"":"s"}`:s.total===0?" \xB7 empty":` \xB7 ${filt?`${s.shown}/`:""}${s.total} task${s.total===1?"":"s"}${s.running?` \xB7 ${s.running} running`:""}`})]})}),secOpen?s.error?$jsx(ErrorBanner,{error:s.error,backups:s.corruptBackups}):s.corruptBackups.length>0&&s.total===0?$jsx("box",{height:1,marginLeft:2,children:$jsx("text",{fg:theme.warning,children:`corrupt backup found: ${s.corruptBackups[0]}`})}):s.total===0?$jsx("box",{height:1,marginLeft:2,children:$jsxs("text",{fg:theme.textMuted,children:["no tasks \u2014 ",$jsx("span",{fg:theme.accent,children:"n"})," to create one here"]})}):$jsxs($Fragment,{children:[$jsx(FilterBar,{chips:s.chips,mask:m2,on:on&&tier==="filter",sel:on?Math.min(chip2,s.chips.length-1):-1,onPick:(i)=>onChip(s.board.slug,i,s.chips[i])}),s.cols.length>0?$jsx("box",{flexDirection:"row",height:s.cap,gap:1,children:s.cols.map((c,ci)=>$jsx(Column,{slug:s.board.slug,status:c.status,tasks:c.tasks,diags:dg,on:on&&(tier==="grid"||tier==="pane")&&ci===clampCol,sel:on?row3:0,onPick:(ri)=>onPick(s.board.slug,ci,ri,c.tasks[ri].id)},c.status))}):$jsx("box",{height:1,marginLeft:2,children:$jsx("text",{fg:theme.textMuted,children:"all columns hidden"})})]}):null]},s.board.slug)})})})}),pane?$jsx(SidePane,{pane,on:tier==="pane",sel:paneSel,diags:pane.kind==="detail"?diags.get(pane.slug)?.get(pane.d.id)??EMPTY_DIAGS:EMPTY_DIAGS}):null]}),$jsx(HintBar,{raw:hint})]})});var Automation=import_react94.memo((props)=>{let labels=SUB_TABS[AUTOMATION_TAB];import_react94.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint="shift+\u2190/\u2192 sub";return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane2,{visible:props.sub===0,children:$jsx(Kanban,{focused:!!props.focused&&props.sub===0})}),$jsx(Pane2,{visible:props.sub===1,children:$jsx(Agents,{focused:!!props.focused&&props.sub===1,sessionId:props.sessionId,onSwitchProfile:props.onSwitchProfile})}),$jsx(Pane2,{visible:props.sub===2,children:$jsx(Cron,{focused:!!props.focused&&props.sub===2})})]})]})}),Pane2=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react107=__toESM(require_react_production(),1);var import_react97=__toESM(require_react_production(),1);init_lane();init_lane();var int=(lo,hi,what=`${lo}\u2013${hi}`)=>(raw)=>{let n=Number(raw);if(!Number.isInteger(n))return`expected integer ${what}`;if(n<lo||n>hi)return`expected ${what}`;return null},intMin=(lo,what=`\u2265 ${lo}`)=>(raw)=>{let n=Number(raw);if(!Number.isInteger(n))return`expected integer ${what}`;if(n<lo)return`expected ${what}`;return null},integer=(raw)=>Number.isInteger(Number(raw))?null:"expected integer",float=(lo,hi)=>(raw)=>{let n=Number(raw);if(!Number.isFinite(n))return`expected number ${lo}\u2013${hi}`;if(n<lo||n>hi)return`expected ${lo}\u2013${hi}`;return null},oneOf=(...opts)=>(raw)=>opts.includes(raw)?null:`expected one of: ${opts.join(" | ")}`,nonNeg=(raw)=>{let n=Number(raw);return Number.isFinite(n)&&n>=0?null:"expected \u2265 0"},RULES={"compression.threshold":float(0.1,0.95),"compression.target_ratio":float(0.05,0.9),"prompt_caching.cache_ttl":(raw)=>/^\d+[smhd]$/.test(raw.trim())?null:"expected duration e.g. 5m, 1h","agent.max_turns":int(1,1e4),"agent.max_verify_nudges":int(0,100),"delegation.max_iterations":int(1,1e4),"delegation.max_concurrent_children":int(1,64),"delegation.max_spawn_depth":int(1,3),"delegation.max_summary_chars":intMin(0),"agent.gateway_timeout":nonNeg,"agent.gateway_timeout_warning":nonNeg,"agent.gateway_notify_interval":nonNeg,"agent.restart_drain_timeout":nonNeg,"gateway.platform_connect_timeout":integer,"delegation.child_timeout_seconds":nonNeg,"browser.command_timeout":int(1,600),"approvals.timeout":int(1,3600),"security.tirith_timeout":int(1,120),"agent.api_max_retries":int(0,20),"tool_output.max_bytes":int(1024,1e7),"tool_output.max_lines":int(10,1e5),"tools.tool_search.max_search_limit":int(1,50),"tools.tool_search.search_default_limit":int(1,50),"tools.tool_search.threshold_pct":int(0,100),"sessions.retention_days":int(1,3650),"sessions.min_interval_hours":int(1,720),"agent.service_tier":oneOf("","fast","standard"),"agent.verify_on_stop":oneOf("auto","true","false"),"display.busy_input_mode":oneOf("queue","steer","interrupt"),"display.details_mode":oneOf("hidden","collapsed","expanded"),"display.thinking_mode":oneOf("collapsed","truncated","full"),"display.tool_progress":oneOf(...TOOL_PROGRESS),"display.final_response_markdown":oneOf("render","strip","raw"),"logging.level":oneOf("DEBUG","INFO","WARNING","ERROR"),"approvals.mode":oneOf("manual","ask","yolo","deny"),"code_execution.mode":oneOf("project","strict"),"onboarding.profile_build":oneOf("ask","off"),"streaming.transport":oneOf("auto","draft","edit","off"),"tools.tool_search.enabled":oneOf("auto","on","off"),"updates.non_interactive_local_changes":oneOf("stash","discard")},check2=(key3,raw)=>RULES[key3]?.(raw)??null;init_schema();init_lane();var SELECTS={"terminal.backend":["local","docker","ssh","modal","daytona","singularity","vercel_sandbox"],"tts.provider":["edge","elevenlabs","openai","neutts","xai","mistral"],"logging.level":["DEBUG","INFO","WARNING","ERROR"],"agent.reasoning_effort":["","none","minimal","low","medium","high","xhigh"],"agent.verify_on_stop":["auto","true","false"],"display.busy_input_mode":["queue","steer","interrupt"],"display.details_mode":["hidden","collapsed","expanded"],"display.thinking_mode":["collapsed","truncated","full"],"display.tool_progress":[...TOOL_PROGRESS],"approvals.mode":["manual","ask","yolo","deny"],"onboarding.profile_build":["ask","off"],"streaming.transport":["auto","draft","edit","off"],"tools.tool_search.enabled":["auto","on","off"],"updates.non_interactive_local_changes":["stash","discard"]},get4=(obj,path4)=>{let cur=obj;for(let p of path4.split("."))if(cur&&typeof cur==="object"&&!Array.isArray(cur))cur=cur[p];else return;return cur},classify2=(key3,t2)=>{if(route(key3).via==="readonly")return"readonly";if(SELECTS[key3]||key3==="display.skin")return"select";if(t2==="bool")return"boolean";if(t2==="int"||t2==="float")return"number";return"string"},labelOf=(key3)=>{let raw=SCHEMA[key3]?.group??key3.split(".")[0];return key3.startsWith(`${raw}.`)?key3.slice(raw.length+1):key3},buildFields=(user)=>{let seen=new Set,out=[];for(let key3 of SCHEMA_KEYS){let s=SCHEMA[key3],uv=get4(user,key3),set3=uv!==void 0;out.push({key:key3,label:labelOf(key3),type:classify2(key3,s.type),value:set3?uv:s.default,set:set3,doc:s.doc,effect:s.effect,options:key3==="display.skin"?skins():SELECTS[key3]}),seen.add(key3)}let walk2=(obj,prefix="")=>{for(let[k2,v2]of Object.entries(obj)){let key3=prefix?`${prefix}.${k2}`:k2;if(v2&&typeof v2==="object"&&!Array.isArray(v2)){if(SCHEMA[key3]?.type==="dict"){seen.add(key3);continue}walk2(v2,key3);continue}if(seen.has(key3))continue;out.push({key:key3,label:labelOf(key3),type:Array.isArray(v2)?"readonly":typeof v2==="boolean"?"boolean":typeof v2==="number"?"number":"string",value:v2,set:!0,doc:"",effect:"live"})}};return walk2(user),out},MERGE={approvals:"security",privacy:"security",secrets:"security",checkpoints:"agent",context:"agent",cron:"agent",network:"agent",model_catalog:"general",onboarding:"general",human_delay:"display",dashboard:"display",gateway:"display",desktop:"display",voice:"display",tool_output:"agent",prompt_caching:"compression",code_execution:"terminal",computer_use:"agent",goals:"agent",lsp:"agent",tool_loop_guardrails:"agent",web:"agent",x_search:"agent",tools:"agent",streaming:"display",vertex:"general",slack:"platforms",telegram:"platforms",mattermost:"platforms",discord:"platforms",whatsapp:"platforms",matrix:"platforms"},rawGroupOf=(key3)=>SCHEMA[key3]?.group??(key3.includes(".")?key3.split(".")[0]:"general"),groupOf=(key3)=>{let raw=rawGroupOf(key3);return MERGE[raw]??raw},sections=(group2,fields)=>{let by=new Map;for(let f of fields){let r=rawGroupOf(f.key);if(!by.has(r))by.set(r,[]);by.get(r).push(f)}if(by.size<=1)return[{head:null,items:fields}];return[...by.keys()].sort((a,b2)=>a===group2?-1:b2===group2?1:a.localeCompare(b2)).map((r)=>({head:r,items:by.get(r)}))},GROUPS=(()=>{let g=new Set(["general"]);for(let k2 of SCHEMA_KEYS)g.add(groupOf(k2));return[...g]})(),EFFECT_GLYPH={live:"",session:"\u21BB",restart:"\u27F3"};init_lane();var AUX_TASKS=[{key:"vision",label:"Vision",hint:"Image analysis"},{key:"web_extract",label:"Web Extract",hint:"Page summarization"},{key:"compression",label:"Compression",hint:"Context compaction"},{key:"session_search",label:"Session Search",hint:"Recall queries"},{key:"skills_hub",label:"Skills Hub",hint:"Skill search"},{key:"approval",label:"Approval",hint:"Smart auto-approve"},{key:"mcp",label:"MCP",hint:"MCP tool routing"},{key:"title_generation",label:"Title Gen",hint:"Session titles"},{key:"triage_specifier",label:"Triage Specifier",hint:"Kanban spec fleshing"},{key:"kanban_decomposer",label:"Kanban Decomposer",hint:"Task decomposition"},{key:"profile_describer",label:"Profile Describer",hint:"Auto profile descriptions"},{key:"curator",label:"Curator",hint:"Skill-usage review"}],dig=(o,...path4)=>path4.reduce((c,p)=>c&&typeof c==="object"?c[p]:void 0,o),str3=(v2)=>typeof v2==="string"?v2:"",readSlots=(raw)=>{let main={kind:"main",key:"main",label:"Main model",hint:"Primary agent model",provider:str3(dig(raw,"model","provider")),model:str3(dig(raw,"model","default"))||str3(dig(raw,"model","name")),auto:!1},aux=AUX_TASKS.map((t2)=>{let p=str3(dig(raw,"auxiliary",t2.key,"provider"));return{kind:"aux",key:t2.key,label:t2.label,hint:t2.hint,provider:p,model:str3(dig(raw,"auxiliary",t2.key,"model")),auto:p===""||p==="auto"}});return[main,...aux]},staleAuxForMain=(slots,provider)=>slots.filter((s)=>s.kind==="aux"&&!s.auto&&s.provider!==""&&s.provider!=="auto"&&s.provider!==provider),assign=async(gw,slot,provider,model)=>{if(slot==="main"){let r=await gw.request("config.set",{key:"model",value:`${model} --provider ${provider} --global`,session_id:void 0});return{ok:["model.default","model.provider"],failed:[],warnings:[],warning:r.warning}}return writeConfig(gw,[{key:`auxiliary.${slot}.provider`,to:provider},{key:`auxiliary.${slot}.model`,to:model}])},resetAux=(gw,slot)=>{let keys=slot==="all"?AUX_TASKS.map((t2)=>t2.key):[slot];return writeConfig(gw,keys.flatMap((k2)=>[{key:`auxiliary.${k2}.provider`,to:"auto"},{key:`auxiliary.${k2}.model`,to:""}]))};var import_react96=__toESM(require_react_production(),1);var import_react95=__toESM(require_react_production(),1);var SecretPrompt=(props)=>{let theme=useTheme().theme,[value2,setValue]=import_react95.useState("");return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:props.title})})}),$jsx("box",{height:1}),props.label?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:props.label})}):null,$jsx(MaskInput,{value:value2,input:setValue,submit:()=>{let v2=value2.trim();if(v2)props.onSubmit(v2)}}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value2.trim()?"Enter confirm \xB7 Esc cancel":"Esc cancel"})})]})};var REFRESH="__refresh__",configured=(p)=>(p.models?.length??0)>0,setupDescription=(p)=>{if(p.warning)return p.warning;if(p.auth_type==="api_key"&&p.key_env)return`paste ${p.key_env} to activate`;if(p.auth_type==="vertex")return p.key_env?`set ${p.key_env} to your service-account JSON path`:"configure Vertex credentials with hermes model";if(p.key_env)return`set ${p.key_env} before using this provider`;if(p.auth_type)return`run hermes model to configure (${p.auth_type})`;return},providerDescription=(p)=>{if(p.authenticated===!1)return setupDescription(p);return p.total_models?`${p.total_models} models`:void 0},replaceProvider=(data2,slug2,next2)=>({...data2,providers:(data2.providers??[]).map((p)=>p.slug===slug2?next2:p)}),ModelPickerDialog=(props)=>{let dialog=useDialog(),toast=useToast(),keys=useKeys(),theme=useTheme().theme,[data2,setData]=import_react96.useState(null),[step,setStep]=import_react96.useState("provider"),[provider,setProvider]=import_react96.useState(null),[setupProvider,setSetupProvider]=import_react96.useState(null),[global2,setGlobal]=import_react96.useState(!1),seq=import_react96.useRef(0),load4=import_react96.useCallback(async(force=!1,quiet=!1)=>{let id=++seq.current;try{let next2=await props.gw.request("model.options",force?{refresh:!0,include_unconfigured:!0}:{include_unconfigured:!0});if(seq.current!==id)return null;return setData((d2)=>force||!d2?next2:d2),next2}catch(e){if(seq.current!==id)return null;if(!quiet)toast.show({variant:"error",message:e instanceof Error?e.message:String(e)});let empty={providers:[]};return setData((d2)=>d2??empty),null}},[props.gw,toast]),refresh=import_react96.useCallback(()=>{toast.show({variant:"info",message:"Refreshing model catalog; custom-provider probes may be slower\u2026"}),load4(!0)},[load4,toast]);import_react96.useEffect(()=>{return load4(Boolean(props.refresh)),()=>{seq.current++}},[load4,props.refresh]);let apply=import_react96.useCallback((model,prov)=>{if(props.onApply)return void props.onApply(prov,model).catch((e)=>toast.show({variant:"error",message:e.message}));let value2=`${model} --provider ${prov}${global2?" --global":""}`;props.gw.request("config.set",global2?{key:"model",value:value2,session_id:void 0}:{key:"model",value:value2}).then((r)=>{if(toast.show({variant:"success",message:`model \u2192 ${r.value??model}${global2?" (global)":""}`}),r.warning)toast.show({variant:"warning",message:r.warning})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[props.gw,props.onApply,global2,toast]),submitKey=import_react96.useCallback(async(p2,key3)=>{try{let r=await props.gw.request("model.save_key",{slug:p2.slug,api_key:key3});if(r.warning)toast.show({variant:"warning",message:r.warning});let direct=r.provider&&configured(r.provider)?r.provider:null,hit=(direct?null:await load4(!0,!0))?.providers?.find((pp)=>pp.slug===p2.slug),next2=direct??(hit&&configured(hit)?hit:r.provider??hit);if(!next2){toast.show({variant:"warning",message:"Provider saved; refresh model options to continue"});return}if(setData((d2)=>d2?replaceProvider(d2,p2.slug,next2):d2),configured(next2)){setSetupProvider(null),setProvider(next2.slug),setStep("model"),toast.show({variant:"success",message:`${next2.name} activated`});return}toast.show({variant:"warning",message:next2.warning??"Provider saved but no models were returned"})}catch(e){toast.show({variant:"error",message:e instanceof Error?e.message:String(e)})}},[props.gw,load4,toast]),setup=import_react96.useCallback((p2)=>{let msg=setupDescription(p2);if(p2.auth_type!=="api_key"||!p2.key_env){toast.show({variant:"warning",message:msg??"Run hermes model to configure this provider"});return}setSetupProvider(p2),setStep("setup")},[toast]),onKey=import_react96.useCallback((k2)=>{if(k2.name==="f5"||keys.match("list.refresh",k2))return refresh(),!0;if(k2.name==="tab"&&!props.onApply)return setGlobal((g)=>!g),!0;if(k2.name==="left"&&step!=="provider")return setStep("provider"),!0;return!1},[keys,props.onApply,refresh,step]),hint=`${keys.print("list.refresh")} refresh`,footer=props.onApply?$jsx("text",{fg:theme.textMuted,children:step==="model"?`${hint} \xB7 \u2190 providers`:hint}):$jsxs("text",{fg:theme.textMuted,children:[$jsx("span",{children:"Scope: "}),$jsx("span",{fg:global2?theme.warning:theme.accent,children:global2?"global (persists to config)":"this session"}),$jsx("span",{children:` \xB7 Tab toggle \xB7 ${hint}${step==="model"?" \xB7 \u2190 providers":""}`})]});if(!data2)return $jsx("box",{width:50,padding:1,children:$jsx("text",{children:"Loading models\u2026"})});if(step==="setup"&&setupProvider?.key_env)return $jsx(SecretPrompt,{title:`Paste ${setupProvider.key_env}`,label:setupDescription(setupProvider)??`API key for ${setupProvider.name}`,onSubmit:(key3)=>{submitKey(setupProvider,key3)}});if(step==="provider"){let options2=[...(data2.providers??[]).toSorted((a,b2)=>Number(Boolean(b2.is_current))-Number(Boolean(a.is_current))).map((p2)=>({title:p2.name,value:p2.slug,description:providerDescription(p2),category:p2.is_current?"Current":p2.authenticated===!1?"Setup required":"Available"})),{title:"Refresh model options",value:REFRESH,description:"force reload from gateway",hint:void 0,category:"Actions"}];return $jsx(DialogSelect,{title:props.title??"Switch Provider",options:options2,current:data2.provider,onSelect:(o)=>{if(o.value===REFRESH)return refresh();let p2=data2.providers?.find((pp)=>pp.slug===o.value);if(p2?.authenticated===!1||p2&&!configured(p2))return void setup(p2);setProvider(o.value),setStep("model")},onKey,placeholder:"Search providers...",footer})}let p=data2.providers?.find((pp)=>pp.slug===provider),options=[...(p?.models??[]).map((m2)=>{let caps3=p?.capabilities?.[m2],badges=[caps3?.fast?"fast":"",caps3?.reasoning?"reasoning":""].filter(Boolean);return{title:m2,value:m2,hint:badges.length>0?badges.join(" \xB7 "):void 0}}),{title:"Refresh model options",value:REFRESH,description:"force reload from gateway",hint:void 0,category:"Actions"}];return $jsx(DialogSelect,{title:props.title?`${props.title} \xB7 ${p?.name??provider}`:`Switch Model (${p?.name??provider})`,options,current:provider===data2.provider?data2.model:void 0,onSelect:(o)=>{if(o.value===REFRESH)return refresh();if(dialog.clear(),provider)apply(o.value,provider)},onKey,placeholder:"Search models...",footer})},openModelPicker=(dialog,gw,opts)=>{dialog.replace($jsx(ModelPickerDialog,{gw,title:opts?.title,onApply:opts?.onApply,refresh:opts?.refresh}))};var flatten=(obj,prefix="")=>Object.entries(obj).flatMap(([k2,v2])=>{let key3=prefix?`${prefix}.${k2}`:k2;if(v2&&typeof v2==="object"&&!Array.isArray(v2))return flatten(v2,key3);return[[key3,v2]]}),setNested=(obj,path4,val)=>{let parts2=path4.split("."),cur=obj;for(let i=0;i<parts2.length-1;i++){if(!cur[parts2[i]]||typeof cur[parts2[i]]!=="object")cur[parts2[i]]={};cur=cur[parts2[i]]}cur[parts2[parts2.length-1]]=val},getNested=(obj,path4)=>{let parts2=path4.split("."),cur=obj;for(let p of parts2)if(cur&&typeof cur==="object"&&!Array.isArray(cur))cur=cur[p];else return;return cur},FieldRow2=import_react97.memo((props)=>{let theme=useTheme().theme,f=props.field,bg2=props.active?theme.backgroundElement:void 0,indicator=props.active?"\u25B8 ":" ",mark2=props.changed?"\u25CF ":f.set?"\xB7":" ",markFg=props.changed?theme.warning:theme.textMuted,display2=()=>{if(props.editing)return props.buf+"\u2588";if(f.type==="readonly"){let n=Array.isArray(f.value)?f.value.length:f.value&&typeof f.value==="object"?Object.keys(f.value).length:0;return n===0?"\u2014":`${n} item${n===1?"":"s"}`}if(f.type==="boolean")return f.value?"\u2713 ON":"\u2717 OFF";return String(f.value??"")},hint=()=>{if(props.readonly||f.type==="readonly")return"\uD83D\uDD12";if(f.type==="boolean")return"[space]";if(f.type==="select")return"[h/l]";return"[enter]"},ro=props.readonly||f.type==="readonly",valFg=ro||!f.set?theme.textMuted:f.type==="boolean"?f.value?theme.success:theme.error:theme.text,labelFg=ro?theme.textMuted:props.active?theme.accent:theme.text,lead2=4+(props.badge!==void 0?12:0),glyph=props.active?EFFECT_GLYPH[f.effect]:"";return $jsxs("box",{id:props.id,flexDirection:"column",backgroundColor:bg2,children:[$jsxs("box",{flexDirection:"row",height:1,children:[$jsx(Col,{w:2,fg:markFg,children:mark2}),$jsx(Col,{w:2,fg:props.active?theme.primary:theme.text,children:indicator}),props.badge!==void 0?$jsx(Col,{w:12,fg:theme.textMuted,children:props.badge}):null,$jsx(Col,{w:40,fg:labelFg,children:f.label}),$jsx(Col,{grow:!0,min:6,fg:valFg,children:display2()}),$jsx(Col,{w:2,fg:theme.textMuted,children:glyph}),$jsx(Col,{w:9,fg:theme.textMuted,right:!0,children:props.active?hint():""})]}),props.error?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx(Col,{w:lead2+40,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,min:6,fg:theme.error,children:`\u2717 ${props.error}`})]}):props.active&&f.doc?$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:lead2,flexShrink:0}),$jsx("box",{width:40,flexShrink:0,minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:f.doc})})]}):null]})}),SlotRow=import_react97.memo((p)=>{let theme=useTheme().theme,main=p.s.kind==="main",val=main?`${p.s.provider||"(unset)"} \xB7 ${p.s.model||"(unset)"}`:p.s.auto?"auto (use main model)":`${p.s.provider} \xB7 ${p.s.model||"(provider default)"}`;return $jsxs("box",{id:p.id,flexDirection:"row",height:1,backgroundColor:p.on?theme.backgroundElement:void 0,children:[$jsx(Col,{w:2,fg:p.on?theme.primary:theme.text,children:p.on?"\u25B8 ":" "}),$jsx(Col,{w:2,fg:main?theme.primary:theme.textMuted,children:main?"\u2605":" "}),$jsx(Col,{w:16,fg:p.on?theme.accent:theme.text,children:p.s.label}),$jsx(Col,{w:22,fg:theme.textMuted,children:p.s.hint}),$jsx(Col,{grow:!0,min:10,fg:p.s.auto?theme.textMuted:theme.text,children:val}),$jsx(Col,{w:14,fg:theme.textMuted,right:!0,children:p.on?main?"[enter]":"[enter] [x]":""})]})}),Config2=import_react97.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),restartGateway=useGatewayRestart(),toast=useToast(),dialog=useDialog(),[raw,setRaw]=import_react97.useState({}),rawRef=import_react97.useRef(raw);rawRef.current=raw;let[original,setOriginal]=import_react97.useState({}),[yaml,setYaml]=import_react97.useState(""),[mode2,setMode]=import_react97.useState("form"),[cat,setCat]=import_react97.useState(0),[cursor,setCursor]=import_react97.useState(0),[editing,setEditing]=import_react97.useState(!1),[buf,setBuf]=import_react97.useState(""),[err,setErr]=import_react97.useState({}),[searching,setSearching]=import_react97.useState(!1),[query2,setQuery]=import_react97.useState(""),[focus,setFocus]=import_react97.useState("categories"),[managed,setManaged]=import_react97.useState(null),[loadErr,setLoadErr]=import_react97.useState(null),loads=import_react97.useRef(0);import_react97.useEffect(()=>{managedSystem().then(setManaged)},[]);let load4=import_react97.useCallback(()=>{let gen=++loads.current;gw.request("config.get",{key:"full"}).then((res)=>{if(loads.current!==gen)return;let parsed=res.config??{};rawRef.current=structuredClone(parsed),setRaw(rawRef.current),setOriginal(structuredClone(parsed)),setYaml($stringify(parsed)),setErr({}),setLoadErr(null)}).catch((e)=>{if(loads.current===gen)setLoadErr(e instanceof Error?e.message:String(e))})},[gw]);import_react97.useEffect(()=>{return load4(),()=>{loads.current++}},[load4]);let all=buildFields(raw),grouped=all.reduce((map,f)=>{let g=groupOf(f.key);if(!map.has(g))map.set(g,[]);return map.get(g).push(f),map},new Map(GROUPS.map((g)=>[g,[]]))),groups=[...grouped.keys()];groups.splice(1,0,"models");let active=groups[cat]??groups[0],onSlots=active==="models"&&!searching,slots=readSlots(raw),secs=searching&&query2.trim()?[{head:null,items:all.filter((f)=>f.key.toLowerCase().includes(query2.toLowerCase()))}]:sections(active,grouped.get(active)??[]),fields=secs.flatMap((s)=>s.items),count3=onSlots?slots.length:fields.length,follow=useFollow("cfg"),catFollow=useFollow("cfg-cat"),changed=(key3)=>JSON.stringify(getNested(raw,key3))!==JSON.stringify(getNested(original,key3)),nChanged=all.reduce((n,f)=>n+(changed(f.key)?1:0),0),update=(key3,val)=>{loads.current++;let next2=structuredClone(rawRef.current);setNested(next2,key3,val),rawRef.current=next2,setRaw(next2),setYaml($stringify(next2))},fmt3=(v2)=>v2===void 0?"\u2014":Array.isArray(v2)?v2.join(", "):String(v2),save2=async()=>{if(managed){toast.show({variant:"error",message:`Managed by ${managed} \u2014 edit configuration.nix`});return}let nErr=Object.keys(err).length;if(nErr>0){toast.show({variant:"error",message:`${nErr} invalid field${nErr===1?"":"s"}`});return}let target=mode2==="yaml"?$parse(yaml)??{}:rawRef.current,diffs=flatten(target).filter(([key3])=>JSON.stringify(getNested(target,key3))!==JSON.stringify(getNested(original,key3))).map(([key3,val])=>({key:key3,from:getNested(original,key3),to:val}));if(diffs.length===0){toast.show({variant:"info",message:"No changes"});return}let body=diffs.map((d2)=>`${d2.key}: ${fmt3(d2.from)} \u2192 ${fmt3(d2.to)}`).join(`
4123
+ `).flatMap((l)=>l.trim()?[JSON.parse(l)]:[]),specify=import_react92.useCallback((t2)=>{if(t2.status!=="triage")return void toast.show({variant:"info",message:`${t2.id} is ${t2.status}, not triage`});return sh(`specify ${q3(t2.id)} --json`).then((out)=>{if(out==null)return;let r=parseSpecify(out)[0];if(!r)return;if(!r.ok)return void toast.show({variant:"error",message:`specify ${r.task_id}: ${trunc5(r.reason??"failed",100)}`});toast.show({variant:"success",message:r.new_title?`Specified ${r.task_id} \u2192 ${trunc5(r.new_title,60)}`:`Specified ${r.task_id} \u2192 todo`})})},[sh,toast]),specifyAll=import_react92.useCallback(()=>{let triage=live.current.sec?.cols.find((c)=>c.status==="triage")?.tasks.length??0;if(triage===0)return void toast.show({variant:"info",message:`No 'triage' tasks on ${live.current.at}`});return openConfirm(dialog,{title:`Specify all \xB7 ${live.current.at}`,body:`${triage} task${triage===1?"":"s"} in 'triage'. Auxiliary LLM expands each body and promotes to todo.`,yes:"specify"}).then((go)=>{if(!go)return;return sh("specify --all --json").then((out)=>{if(out==null)return;let rows3=parseSpecify(out),ok=rows3.filter((r)=>r.ok).length,bad=rows3.length-ok;toast.show({variant:ok===0&&bad>0?"error":"success",message:`Specified ${ok}/${rows3.length}${bad?` (${bad} failed)`:""}`})})})},[dialog,sh,toast]),dispatch=import_react92.useCallback(()=>{let ready=live.current.sec?.cols.find((c)=>c.status==="ready")?.tasks.length??0;if(ready===0)return void toast.show({variant:"info",message:`No 'ready' tasks on ${live.current.at}`});return openConfirm(dialog,{title:`Dispatch \xB7 ${live.current.at}`,body:`${ready} task${ready===1?"":"s"} in 'ready'. Spawns one worker per task (one pass).`,yes:"dispatch"}).then((ok)=>{if(!ok)return;sh("dispatch --json").then((out)=>{if(out==null)return;let r=parseDispatchResult(out),spawned2=r.spawned.length,deferred=r.skipped_per_profile_capped.length,defaults=r.auto_assigned_default.length,unassigned=r.skipped_unassigned.length,nonspawnable=r.skipped_nonspawnable.length,failed=dispatchFailures(r).length,guarded2=dispatchGuarded(r).length,parts2=[`${spawned2} spawned`];if(defaults)parts2.push(`${defaults} defaulted`);if(deferred)parts2.push(`${deferred} deferred`);if(unassigned)parts2.push(`${unassigned} unassigned`);if(nonspawnable)parts2.push(`${nonspawnable} non-spawnable`);if(failed)parts2.push(`${failed} failed`);if(guarded2)parts2.push(`${guarded2} guarded`);let more=dispatchDetails(r);toast.show({variant:dispatchVariant(r),message:`Dispatch: ${parts2.join(" \xB7 ")}`,action:more?{label:"details",run:()=>setPane({kind:"dispatch",slug:live.current.at,text:more})}:void 0})}).catch((e)=>void toast.show({variant:"error",message:trunc5(e.message,120)}))})},[dialog,sh,toast]),showLog=import_react92.useCallback((t2)=>{let s=live.current.at,text4=tailLogOf(s,t2.id);if(text4==null)return void toast.show({variant:"info",message:`No worker log for ${t2.id}`});setPane({kind:"log",slug:s,id:t2.id,text:text4})},[toast]),editTitle=import_react92.useCallback((t2)=>openTextPrompt(dialog,{title:"Edit title",label:t2.id,initial:t2.title}).then((v2)=>v2!==null&&v2!==void 0&&patchDirect(t2.id,{title:v2},`Updated ${t2.id}`)),[dialog,patchDirect]),editBody=import_react92.useCallback((t2)=>openTextPrompt(dialog,{title:"Edit body",label:t2.id,initial:t2.body??""}).then((v2)=>{if(v2===null||v2===void 0)return;patchDirect(t2.id,{body:v2},`Updated ${t2.id}`)}),[dialog,patchDirect]),editPriority=import_react92.useCallback((t2)=>{let opts=Array.from({length:10},(_2,i)=>({title:i===0?"P0 (none)":`P${i}`,value:String(i)}));dialog.replace($jsx(DialogSelect,{title:`Priority for ${t2.id}`,options:opts,current:String(t2.priority),filterable:!1,onSelect:(o)=>{dialog.clear(),patchDirect(t2.id,{priority:Number(o.value)},`${t2.id} \u2192 P${o.value}`)}}))},[dialog,patchDirect]),editResult=import_react92.useCallback((t2)=>{if(t2.status!=="done")return void toast.show({variant:"info",message:`${t2.id} is not done`});return openTextPrompt(dialog,{title:"Edit result",label:t2.id,initial:t2.result??""}).then((v2)=>{if(v2==null)return;sh(`edit ${q3(t2.id)} --result ${q3(v2)}`,`Updated ${t2.id} result`)})},[dialog,sh,toast]),block=import_react92.useCallback((t2)=>{blockSupport(live.current.at).then((support)=>{if(support==="no")return openTextPrompt(dialog,{title:`Block ${t2.id}`,label:"Reason (optional; generic block \u2014 active CLI has no --kind)"}).then((r)=>{if(r!==null)runBlock(t2,r,"")});let opts=[{title:"generic",value:"",description:"legacy block without --kind"},{title:"needs input",value:"needs_input",description:"human answer required"},{title:"dependency",value:"dependency",description:"wait in todo until parents finish"},{title:"capability",value:"capability",description:"missing tool, credential, or profile capability"},{title:"transient",value:"transient",description:"temporary/flaky condition"}];dialog.replace($jsx(DialogSelect,{title:`Block kind for ${t2.id}`,options:opts,current:t2.block_kind??"",filterable:!1,onSelect:async(o)=>{dialog.clear();let r=await openTextPrompt(dialog,{title:`Block ${t2.id}`,label:"Reason (optional, posted as comment)"});if(r!==null)runBlock(t2,r,o.value)}}))})},[dialog,blockSupport,runBlock]),editStatus=import_react92.useCallback((t2)=>{let opts=[];if(t2.status!=="done")opts.push({title:"done",value:"complete",description:"mark complete (prompts for result)"});if(t2.status!=="blocked")opts.push({title:"blocked",value:"block",description:"mark blocked (choose kind, prompts for reason)"});if(t2.status!=="scheduled")opts.push({title:"scheduled",value:"schedule",description:"park until externally unblocked (prompts for reason)"});if(t2.status==="blocked"||t2.status==="scheduled")opts.push({title:"ready",value:"unblock",description:t2.status==="scheduled"?"release back to ready":"return to ready"});opts.push({title:"archived",value:"archive",description:"archive (terminal)"}),dialog.replace($jsx(DialogSelect,{title:`Status for ${t2.id}`,options:opts,current:t2.status,filterable:!1,onSelect:async(o)=>{if(dialog.clear(),o.value==="complete"){let res=await openTextPrompt(dialog,{title:`Complete ${t2.id}`,label:"Result (optional)",initial:t2.result??""}),flag=res?` --result ${q3(res)}`:"";sh(`complete ${q3(t2.id)}${flag}`,`Completed ${t2.id}`);return}if(o.value==="block")return block(t2);if(o.value==="schedule"){let r=await openTextPrompt(dialog,{title:`Schedule ${t2.id}`,label:"Reason (optional, posted as comment)"}),arg=r?` ${q3(r)}`:"";sh(`schedule ${q3(t2.id)}${arg}`,`Scheduled ${t2.id}`);return}if(o.value==="unblock")return void sh(`unblock ${q3(t2.id)}`,`Unblocked ${t2.id}`);if(o.value==="archive")return void archive(t2)}}))},[dialog,sh,archive,block]),editParents=import_react92.useCallback((t2)=>{let cur2=(pane?.kind==="detail"&&pane.d.id===t2.id?pane.d:detailOf(at,t2.id))?.parents??[],d2=(data2.get(at)??boardStateOf(at)).columns,opts=STATUSES.flatMap((s)=>d2.get(s)??[]).filter((x2)=>x2.id!==t2.id).map((x2)=>({title:x2.id,description:trunc5(x2.title,50),value:x2.id,category:cur2.includes(x2.id)?"linked":"available"}));dialog.replace($jsx(DialogSelect,{title:`Parents for ${t2.id}`,options:opts,placeholder:"Select to toggle link\u2026",onSelect:(o)=>{if(dialog.clear(),cur2.includes(o.value))sh(`unlink ${q3(o.value)} ${q3(t2.id)}`,`Unlinked ${o.value}`);else sh(`link ${q3(o.value)} ${q3(t2.id)}`,`Linked ${o.value}`)}}))},[dialog,sh,data2,at,pane]),openField=import_react92.useCallback((f,t2)=>{if(f==="title")return void editTitle(t2);if(f==="body")return void editBody(t2);if(f==="assignee")return assign(t2);if(f==="priority")return editPriority(t2);if(f==="status")return editStatus(t2);if(f==="parents")return editParents(t2);if(f==="result")return void editResult(t2);if(f==="comment")return void comment(t2)},[editTitle,editBody,assign,editPriority,editStatus,editParents,editResult,comment]),ACTS=import_react92.useMemo(()=>[{key:"n",title:"New task",when:()=>!0,run:()=>void create()},{key:"N",title:"New child",when:(t2)=>!!t2,run:(t2)=>void create(t2)},{key:"a",title:"Assign",when:(t2)=>!!t2,run:(t2)=>void assign(t2)},{key:"c",title:"Comment",when:(t2)=>!!t2,run:(t2)=>void comment(t2)},{key:"s",title:"Specify",when:(t2)=>t2?.status==="triage",run:(t2)=>void specify(t2)},{key:"S",title:"Specify all",when:()=>!0,run:()=>void specifyAll()},{key:"u",title:"Unblock",when:(t2)=>t2?.status==="blocked"||t2?.status==="scheduled",run:(t2)=>void unblock(t2)},{key:"d",title:"Archive",when:(t2)=>!!t2,run:(t2)=>void archive(t2)},{key:"l",title:"Worker log",when:(t2)=>!!t2,run:(t2)=>showLog(t2)},{key:"b",title:"New board",when:()=>!0,run:()=>void newBoard()},{key:"D",title:"Dispatch",when:()=>!0,run:()=>void dispatch()}],[create,assign,comment,specify,specifyAll,unblock,archive,showLog,newBoard,dispatch]),isOpen=open3.has(at),paneOpen=pane?.kind==="detail",paneFields=paneOpen?fieldsFor(pane.d):[];useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(key3.name==="escape"&&pane){if(tier==="pane"){setTier("grid");return}return setPane(null)}if(keys.match("list.refresh",key3))return load4();if(key3.name==="tab"){if(paneOpen&&tier!=="pane"){setTier("pane"),setPaneSel(0);return}if(tier==="pane"){let n=paneFields.length;if(n===0)return;let d2=key3.shift?-1:1;setPaneSel((s)=>(s+d2+n)%n);return}return goBoard(key3.shift?-1:1)}if(tier==="pane"){let t3=live.current.task;if(!t3||!paneOpen)return;let f=paneFields[Math.min(paneSel,paneFields.length-1)];if(key3.name==="up"){let n=paneFields.length;if(n===0)return;return setPaneSel((s)=>(s-1+n)%n)}if(key3.name==="down"){let n=paneFields.length;if(n===0)return;return setPaneSel((s)=>(s+1)%n)}if(key3.name==="return")return openField(f,t3);let hit2=ACTS.find((a)=>a.key===key3.raw&&a.when(t3));if(hit2)return hit2.run(t3);return}if(key3.name==="space"||key3.name===" "){if(tier==="head")return toggle(at);if(tier==="filter"&&sec3?.chips[chip2])return flip(sec3.chips[chip2]);return}if(key3.name==="down"){if(tier==="head"){if(isOpen)return setTier("filter");let n2=stepBoard(1);return n2?enterTop(n2):void 0}if(tier==="filter"){if(sec3&&sec3.shown>0){setTier("grid"),setRow(0);return}let n2=stepBoard(1);return n2?enterTop(n2):void 0}if(row3<(cur?.tasks.length??1)-1)return setRow((r)=>r+1);let n=stepBoard(1);return n?enterTop(n):void 0}if(key3.name==="up"){if(tier==="head"){let p=stepBoard(-1);return p?enterBottom(p):void 0}if(tier==="filter")return setTier("head");if(row3>0)return setRow((r)=>r-1);return setTier("filter")}if(key3.name==="left"){if(tier==="filter")return setChip((c)=>Math.max(0,c-1));if(tier==="grid")return setCol((c)=>{let n=Math.max(0,c-1);return setRow(0),n});return}if(key3.name==="right"){if(tier==="filter")return setChip((c)=>Math.min((sec3?.chips.length??1)-1,c+1));if(tier==="grid")return setCol((c)=>{let n=Math.min(cols2.length-1,c+1);return setRow(0),n});return}if(key3.name==="return"){if(tier==="head")return toggle(at);if(tier==="filter"&&sec3?.chips[chip2])return flip(sec3.chips[chip2]);if(task)return setPane((p)=>p?.kind==="detail"&&p.d.id===task.id?null:((d2)=>d2?{kind:"detail",slug:at,d:d2}:null)(detailOf(at,task.id)));return}let t2=live.current.task,hit=ACTS.find((a)=>a.key===key3.raw&&a.when(t2));if(hit)return hit.run(t2)});let hint=import_react92.useMemo(()=>{let t2=task;return[tier==="pane"?"Esc grid":"Tab board",tier==="head"?"\u2191\u2193 nav Space fold":tier==="filter"?"\u2190\u2192 chip Space toggle":tier==="pane"?"Tab/\u2191\u2193 field Enter edit Esc grid":"\u2190\u2192\u2191\u2193 nav Enter detail",...ACTS.filter((a)=>a.when(t2)).map((a)=>`${a.key} ${a.title.toLowerCase()}`),`${keys.print("list.refresh")} reload`].join(" ")},[ACTS,keys,task,tier]),onHead=import_react92.useCallback((s)=>{setAt(s),setTier("head"),toggle(s)},[toggle]),onChip=import_react92.useCallback((s,i,c)=>{setAt(s),setTier("filter"),setChip(i),flip(c)},[flip]),onPick=import_react92.useCallback((s,ci,ri,id)=>{setAt(s),setTier("grid"),setCol(ci),setRow(ri),setOpen((o)=>o.has(s)?o:new Set(o).add(s));let d2=detailOf(s,id);if(d2)setPane({kind:"detail",slug:s,d:d2})},[]);return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx(TabShell,{title:`Kanban \xB7 ${sections.length} board${sections.length===1?"":"s"} \xB7 ${grand} task${grand===1?"":"s"}${running2?` \xB7 ${running2} running`:""}`,children:$jsx("scrollbox",{id:"kb-board-scroll",ref:outer,scrollY:!0,flexGrow:1,verticalScrollbarOptions:NOBAR,children:$jsx("box",{flexDirection:"column",width:"100%",children:sections.map((s)=>{let on=s.board.slug===at,secOpen=open3.has(s.board.slug),m2=maskOf(s.board.slug),filt=m2.who.size+m2.pri.size+m2.status.size,dg=diags.get(s.board.slug)??EMPTY_DIAG;return $jsxs("box",{id:`kb-sec-${s.board.slug}`,flexDirection:"column",flexShrink:0,marginBottom:1,children:[$jsx("box",{height:1,onMouseDown:()=>onHead(s.board.slug),backgroundColor:on&&tier==="head"?theme.backgroundElement:void 0,children:$jsxs("text",{children:[$jsx("span",{fg:on?theme.accent:theme.textMuted,children:secOpen?"\u25BE ":"\u25B8 "}),$jsx("span",{fg:on?theme.primary:theme.text,children:$jsx("strong",{children:s.board.name})}),$jsx("span",{fg:theme.textMuted,children:s.error?` \xB7 ${s.error.kind}`:s.corruptBackups.length>0?` \xB7 ${s.corruptBackups.length} corrupt backup${s.corruptBackups.length===1?"":"s"}`:s.total===0?" \xB7 empty":` \xB7 ${filt?`${s.shown}/`:""}${s.total} task${s.total===1?"":"s"}${s.running?` \xB7 ${s.running} running`:""}`})]})}),secOpen?s.error?$jsx(ErrorBanner,{error:s.error,backups:s.corruptBackups}):s.corruptBackups.length>0&&s.total===0?$jsx("box",{height:1,marginLeft:2,children:$jsx("text",{fg:theme.warning,children:`corrupt backup found: ${s.corruptBackups[0]}`})}):s.total===0?$jsx("box",{height:1,marginLeft:2,children:$jsxs("text",{fg:theme.textMuted,children:["no tasks \u2014 ",$jsx("span",{fg:theme.accent,children:"n"})," to create one here"]})}):$jsxs($Fragment,{children:[$jsx(FilterBar,{chips:s.chips,mask:m2,on:on&&tier==="filter",sel:on?Math.min(chip2,s.chips.length-1):-1,onPick:(i)=>onChip(s.board.slug,i,s.chips[i])}),s.cols.length>0?$jsx("box",{flexDirection:"row",height:s.cap,gap:1,children:s.cols.map((c,ci)=>$jsx(Column,{slug:s.board.slug,status:c.status,tasks:c.tasks,diags:dg,on:on&&(tier==="grid"||tier==="pane")&&ci===clampCol,sel:on?row3:0,onPick:(ri)=>onPick(s.board.slug,ci,ri,c.tasks[ri].id)},c.status))}):$jsx("box",{height:1,marginLeft:2,children:$jsx("text",{fg:theme.textMuted,children:"all columns hidden"})})]}):null]},s.board.slug)})})})}),pane?$jsx(SidePane,{pane,on:tier==="pane",sel:paneSel,diags:pane.kind==="detail"?diags.get(pane.slug)?.get(pane.d.id)??EMPTY_DIAGS:EMPTY_DIAGS}):null]}),$jsx(HintBar,{raw:hint})]})});var Automation=import_react94.memo((props)=>{let labels=SUB_TABS[AUTOMATION_TAB];import_react94.useEffect(()=>{if(props.sub>=labels.length)props.setSub(0)},[props.sub,labels.length]);let hint="shift+\u2190/\u2192 sub";return $jsxs("box",{flexDirection:"column",flexGrow:1,minWidth:0,children:[$jsx(SubTabBar,{tabs:labels,active:props.sub,onChange:props.setSub,hint}),$jsxs("box",{flexGrow:1,minWidth:0,flexDirection:"column",children:[$jsx(Pane2,{visible:props.sub===0,children:$jsx(Kanban,{focused:!!props.focused&&props.sub===0})}),$jsx(Pane2,{visible:props.sub===1,children:$jsx(Agents,{focused:!!props.focused&&props.sub===1,sessionId:props.sessionId,onSwitchProfile:props.onSwitchProfile})}),$jsx(Pane2,{visible:props.sub===2,children:$jsx(Cron,{focused:!!props.focused&&props.sub===2})})]})]})}),Pane2=({visible:visible2,children:children2})=>visible2?$jsx("box",{flexGrow:1,minWidth:0,minHeight:0,flexDirection:"column",children:children2}):null;var import_react107=__toESM(require_react_production(),1);var import_react97=__toESM(require_react_production(),1);init_lane();init_lane();init_schema();var int=(lo,hi,what=`${lo}\u2013${hi}`)=>(raw)=>{let n=Number(raw);if(!Number.isInteger(n))return`expected integer ${what}`;if(n<lo||n>hi)return`expected ${what}`;return null},intMin=(lo,what=`\u2265 ${lo}`)=>(raw)=>{let n=Number(raw);if(!Number.isInteger(n))return`expected integer ${what}`;if(n<lo)return`expected ${what}`;return null},integer=(raw)=>Number.isInteger(Number(raw))?null:"expected integer",float=(lo,hi)=>(raw)=>{let n=Number(raw);if(!Number.isFinite(n))return`expected number ${lo}\u2013${hi}`;if(n<lo||n>hi)return`expected ${lo}\u2013${hi}`;return null},oneOf=(...opts)=>(raw)=>opts.includes(raw)?null:`expected one of: ${opts.join(" | ")}`,nonNeg=(raw)=>{let n=Number(raw);return Number.isFinite(n)&&n>=0?null:"expected \u2265 0"},RULES={"compression.threshold":float(0.1,0.95),"compression.target_ratio":float(0.05,0.9),"prompt_caching.cache_ttl":(raw)=>/^\d+[smhd]$/.test(raw.trim())?null:"expected duration e.g. 5m, 1h","agent.max_turns":int(1,1e4),"agent.max_verify_nudges":int(0,100),"delegation.max_iterations":int(1,1e4),"delegation.max_concurrent_children":int(1,64),"delegation.max_spawn_depth":int(1,3),"delegation.max_summary_chars":intMin(0),"agent.gateway_timeout":nonNeg,"agent.gateway_timeout_warning":nonNeg,"agent.gateway_notify_interval":nonNeg,"agent.restart_drain_timeout":nonNeg,"gateway.platform_connect_timeout":integer,"delegation.child_timeout_seconds":nonNeg,"browser.command_timeout":int(1,600),"approvals.timeout":int(1,3600),"security.tirith_timeout":int(1,120),"agent.api_max_retries":int(0,20),"tool_output.max_bytes":int(1024,1e7),"tool_output.max_lines":int(10,1e5),"tools.tool_search.max_search_limit":int(1,50),"tools.tool_search.search_default_limit":int(1,50),"tools.tool_search.threshold_pct":int(0,100),"sessions.retention_days":int(1,3650),"sessions.min_interval_hours":int(1,720),"agent.service_tier":oneOf("","fast","standard"),"agent.verify_on_stop":oneOf("auto","true","false"),"display.busy_input_mode":oneOf("queue","steer","interrupt"),"display.details_mode":oneOf("hidden","collapsed","expanded"),"display.thinking_mode":oneOf("collapsed","truncated","full"),"display.tool_progress":oneOf(...TOOL_PROGRESS),"display.final_response_markdown":oneOf("render","strip","raw"),"logging.level":oneOf("DEBUG","INFO","WARNING","ERROR"),"approvals.mode":oneOf(...APPROVAL_MODES),"code_execution.mode":oneOf("project","strict"),"onboarding.profile_build":oneOf("ask","off"),"streaming.transport":oneOf("auto","draft","edit","off"),"tools.tool_search.enabled":oneOf("auto","on","off"),"updates.non_interactive_local_changes":oneOf("stash","discard")},check2=(key3,raw)=>RULES[key3]?.(raw)??null;init_schema();init_lane();var SELECTS={"terminal.backend":["local","docker","ssh","modal","daytona","singularity","vercel_sandbox"],"tts.provider":["edge","elevenlabs","openai","neutts","xai","mistral"],"logging.level":["DEBUG","INFO","WARNING","ERROR"],"agent.reasoning_effort":["","none","minimal","low","medium","high","xhigh"],"agent.verify_on_stop":["auto","true","false"],"display.busy_input_mode":["queue","steer","interrupt"],"display.details_mode":["hidden","collapsed","expanded"],"display.thinking_mode":["collapsed","truncated","full"],"display.tool_progress":[...TOOL_PROGRESS],"approvals.mode":[...APPROVAL_MODES],"onboarding.profile_build":["ask","off"],"streaming.transport":["auto","draft","edit","off"],"tools.tool_search.enabled":["auto","on","off"],"updates.non_interactive_local_changes":["stash","discard"]},get4=(obj,path4)=>{let cur=obj;for(let p of path4.split("."))if(cur&&typeof cur==="object"&&!Array.isArray(cur))cur=cur[p];else return;return cur},classify2=(key3,t2)=>{if(route(key3).via==="readonly")return"readonly";if(SELECTS[key3]||key3==="display.skin")return"select";if(t2==="bool")return"boolean";if(t2==="int"||t2==="float")return"number";return"string"},labelOf=(key3)=>{let raw=SCHEMA[key3]?.group??key3.split(".")[0];return key3.startsWith(`${raw}.`)?key3.slice(raw.length+1):key3},buildFields=(user)=>{let seen=new Set,out=[];for(let key3 of SCHEMA_KEYS){let s=SCHEMA[key3],uv=get4(user,key3),set3=uv!==void 0;out.push({key:key3,label:labelOf(key3),type:classify2(key3,s.type),value:set3?uv:s.default,set:set3,doc:s.doc,effect:s.effect,options:key3==="display.skin"?skins():SELECTS[key3]}),seen.add(key3)}let walk2=(obj,prefix="")=>{for(let[k2,v2]of Object.entries(obj)){let key3=prefix?`${prefix}.${k2}`:k2;if(v2&&typeof v2==="object"&&!Array.isArray(v2)){if(SCHEMA[key3]?.type==="dict"){seen.add(key3);continue}walk2(v2,key3);continue}if(seen.has(key3))continue;out.push({key:key3,label:labelOf(key3),type:Array.isArray(v2)?"readonly":typeof v2==="boolean"?"boolean":typeof v2==="number"?"number":"string",value:v2,set:!0,doc:"",effect:"live"})}};return walk2(user),out},MERGE={approvals:"security",privacy:"security",secrets:"security",checkpoints:"agent",context:"agent",cron:"agent",network:"agent",model_catalog:"general",onboarding:"general",human_delay:"display",dashboard:"display",gateway:"display",desktop:"display",voice:"display",tool_output:"agent",prompt_caching:"compression",code_execution:"terminal",computer_use:"agent",goals:"agent",lsp:"agent",tool_loop_guardrails:"agent",web:"agent",x_search:"agent",tools:"agent",streaming:"display",vertex:"general",slack:"platforms",telegram:"platforms",mattermost:"platforms",discord:"platforms",whatsapp:"platforms",matrix:"platforms"},rawGroupOf=(key3)=>SCHEMA[key3]?.group??(key3.includes(".")?key3.split(".")[0]:"general"),groupOf=(key3)=>{let raw=rawGroupOf(key3);return MERGE[raw]??raw},sections=(group2,fields)=>{let by=new Map;for(let f of fields){let r=rawGroupOf(f.key);if(!by.has(r))by.set(r,[]);by.get(r).push(f)}if(by.size<=1)return[{head:null,items:fields}];return[...by.keys()].sort((a,b2)=>a===group2?-1:b2===group2?1:a.localeCompare(b2)).map((r)=>({head:r,items:by.get(r)}))},GROUPS=(()=>{let g=new Set(["general"]);for(let k2 of SCHEMA_KEYS)g.add(groupOf(k2));return[...g]})(),EFFECT_GLYPH={live:"",session:"\u21BB",restart:"\u27F3"};init_lane();var AUX_TASKS=[{key:"vision",label:"Vision",hint:"Image analysis"},{key:"web_extract",label:"Web Extract",hint:"Page summarization"},{key:"compression",label:"Compression",hint:"Context compaction"},{key:"session_search",label:"Session Search",hint:"Recall queries"},{key:"skills_hub",label:"Skills Hub",hint:"Skill search"},{key:"approval",label:"Approval",hint:"Smart auto-approve"},{key:"mcp",label:"MCP",hint:"MCP tool routing"},{key:"title_generation",label:"Title Gen",hint:"Session titles"},{key:"triage_specifier",label:"Triage Specifier",hint:"Kanban spec fleshing"},{key:"kanban_decomposer",label:"Kanban Decomposer",hint:"Task decomposition"},{key:"profile_describer",label:"Profile Describer",hint:"Auto profile descriptions"},{key:"curator",label:"Curator",hint:"Skill-usage review"}],dig=(o,...path4)=>path4.reduce((c,p)=>c&&typeof c==="object"?c[p]:void 0,o),str3=(v2)=>typeof v2==="string"?v2:"",readSlots=(raw)=>{let main={kind:"main",key:"main",label:"Main model",hint:"Primary agent model",provider:str3(dig(raw,"model","provider")),model:str3(dig(raw,"model","default"))||str3(dig(raw,"model","name")),auto:!1},aux=AUX_TASKS.map((t2)=>{let p=str3(dig(raw,"auxiliary",t2.key,"provider"));return{kind:"aux",key:t2.key,label:t2.label,hint:t2.hint,provider:p,model:str3(dig(raw,"auxiliary",t2.key,"model")),auto:p===""||p==="auto"}});return[main,...aux]},staleAuxForMain=(slots,provider)=>slots.filter((s)=>s.kind==="aux"&&!s.auto&&s.provider!==""&&s.provider!=="auto"&&s.provider!==provider),assign=async(gw,slot,provider,model)=>{if(slot==="main"){let r=await gw.request("config.set",{key:"model",value:`${model} --provider ${provider} --global`,session_id:void 0});return{ok:["model.default","model.provider"],failed:[],warnings:[],warning:r.warning}}return writeConfig(gw,[{key:`auxiliary.${slot}.provider`,to:provider},{key:`auxiliary.${slot}.model`,to:model}])},resetAux=(gw,slot)=>{let keys=slot==="all"?AUX_TASKS.map((t2)=>t2.key):[slot];return writeConfig(gw,keys.flatMap((k2)=>[{key:`auxiliary.${k2}.provider`,to:"auto"},{key:`auxiliary.${k2}.model`,to:""}]))};var import_react96=__toESM(require_react_production(),1);var import_react95=__toESM(require_react_production(),1);var SecretPrompt=(props)=>{let theme=useTheme().theme,[value2,setValue]=import_react95.useState("");return $jsxs("box",{flexDirection:"column",width:60,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:props.title})})}),$jsx("box",{height:1}),props.label?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:props.label})}):null,$jsx(MaskInput,{value:value2,input:setValue,submit:()=>{let v2=value2.trim();if(v2)props.onSubmit(v2)}}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:value2.trim()?"Enter confirm \xB7 Esc cancel":"Esc cancel"})})]})};var REFRESH="__refresh__",configured=(p)=>(p.models?.length??0)>0,setupDescription=(p)=>{if(p.warning)return p.warning;if(p.auth_type==="api_key"&&p.key_env)return`paste ${p.key_env} to activate`;if(p.auth_type==="vertex")return p.key_env?`set ${p.key_env} to your service-account JSON path`:"configure Vertex credentials with hermes model";if(p.key_env)return`set ${p.key_env} before using this provider`;if(p.auth_type)return`run hermes model to configure (${p.auth_type})`;return},providerDescription=(p)=>{if(p.authenticated===!1)return setupDescription(p);return p.total_models?`${p.total_models} models`:void 0},replaceProvider=(data2,slug2,next2)=>({...data2,providers:(data2.providers??[]).map((p)=>p.slug===slug2?next2:p)}),ModelPickerDialog=(props)=>{let dialog=useDialog(),toast=useToast(),keys=useKeys(),theme=useTheme().theme,[data2,setData]=import_react96.useState(null),[step,setStep]=import_react96.useState("provider"),[provider,setProvider]=import_react96.useState(null),[setupProvider,setSetupProvider]=import_react96.useState(null),[global2,setGlobal]=import_react96.useState(!1),seq=import_react96.useRef(0),load4=import_react96.useCallback(async(force=!1,quiet=!1)=>{let id=++seq.current;try{let next2=await props.gw.request("model.options",force?{refresh:!0,include_unconfigured:!0}:{include_unconfigured:!0});if(seq.current!==id)return null;return setData((d2)=>force||!d2?next2:d2),next2}catch(e){if(seq.current!==id)return null;if(!quiet)toast.show({variant:"error",message:e instanceof Error?e.message:String(e)});let empty={providers:[]};return setData((d2)=>d2??empty),null}},[props.gw,toast]),refresh=import_react96.useCallback(()=>{toast.show({variant:"info",message:"Refreshing model catalog; custom-provider probes may be slower\u2026"}),load4(!0)},[load4,toast]);import_react96.useEffect(()=>{return load4(Boolean(props.refresh)),()=>{seq.current++}},[load4,props.refresh]);let apply=import_react96.useCallback((model,prov)=>{if(props.onApply)return void props.onApply(prov,model).catch((e)=>toast.show({variant:"error",message:e.message}));let value2=`${model} --provider ${prov}${global2?" --global":""}`;props.gw.request("config.set",global2?{key:"model",value:value2,session_id:void 0}:{key:"model",value:value2}).then((r)=>{if(toast.show({variant:"success",message:`model \u2192 ${r.value??model}${global2?" (global)":""}`}),r.warning)toast.show({variant:"warning",message:r.warning})}).catch((e)=>toast.show({variant:"error",message:e.message}))},[props.gw,props.onApply,global2,toast]),submitKey=import_react96.useCallback(async(p2,key3)=>{try{let r=await props.gw.request("model.save_key",{slug:p2.slug,api_key:key3});if(r.warning)toast.show({variant:"warning",message:r.warning});let direct=r.provider&&configured(r.provider)?r.provider:null,hit=(direct?null:await load4(!0,!0))?.providers?.find((pp)=>pp.slug===p2.slug),next2=direct??(hit&&configured(hit)?hit:r.provider??hit);if(!next2){toast.show({variant:"warning",message:"Provider saved; refresh model options to continue"});return}if(setData((d2)=>d2?replaceProvider(d2,p2.slug,next2):d2),configured(next2)){setSetupProvider(null),setProvider(next2.slug),setStep("model"),toast.show({variant:"success",message:`${next2.name} activated`});return}toast.show({variant:"warning",message:next2.warning??"Provider saved but no models were returned"})}catch(e){toast.show({variant:"error",message:e instanceof Error?e.message:String(e)})}},[props.gw,load4,toast]),setup=import_react96.useCallback((p2)=>{let msg=setupDescription(p2);if(p2.auth_type!=="api_key"||!p2.key_env){toast.show({variant:"warning",message:msg??"Run hermes model to configure this provider"});return}setSetupProvider(p2),setStep("setup")},[toast]),onKey=import_react96.useCallback((k2)=>{if(k2.name==="f5"||keys.match("list.refresh",k2))return refresh(),!0;if(k2.name==="tab"&&!props.onApply)return setGlobal((g)=>!g),!0;if(k2.name==="left"&&step!=="provider")return setStep("provider"),!0;return!1},[keys,props.onApply,refresh,step]),hint=`${keys.print("list.refresh")} refresh`,footer=props.onApply?$jsx("text",{fg:theme.textMuted,children:step==="model"?`${hint} \xB7 \u2190 providers`:hint}):$jsxs("text",{fg:theme.textMuted,children:[$jsx("span",{children:"Scope: "}),$jsx("span",{fg:global2?theme.warning:theme.accent,children:global2?"global (persists to config)":"this session"}),$jsx("span",{children:` \xB7 Tab toggle \xB7 ${hint}${step==="model"?" \xB7 \u2190 providers":""}`})]});if(!data2)return $jsx("box",{width:50,padding:1,children:$jsx("text",{children:"Loading models\u2026"})});if(step==="setup"&&setupProvider?.key_env)return $jsx(SecretPrompt,{title:`Paste ${setupProvider.key_env}`,label:setupDescription(setupProvider)??`API key for ${setupProvider.name}`,onSubmit:(key3)=>{submitKey(setupProvider,key3)}});if(step==="provider"){let options2=[...(data2.providers??[]).toSorted((a,b2)=>Number(Boolean(b2.is_current))-Number(Boolean(a.is_current))).map((p2)=>({title:p2.name,value:p2.slug,description:providerDescription(p2),category:p2.is_current?"Current":p2.authenticated===!1?"Setup required":"Available"})),{title:"Refresh model options",value:REFRESH,description:"force reload from gateway",hint:void 0,category:"Actions"}];return $jsx(DialogSelect,{title:props.title??"Switch Provider",options:options2,current:data2.provider,onSelect:(o)=>{if(o.value===REFRESH)return refresh();let p2=data2.providers?.find((pp)=>pp.slug===o.value);if(p2?.authenticated===!1||p2&&!configured(p2))return void setup(p2);setProvider(o.value),setStep("model")},onKey,placeholder:"Search providers...",footer})}let p=data2.providers?.find((pp)=>pp.slug===provider),options=[...(p?.models??[]).map((m2)=>{let caps3=p?.capabilities?.[m2],badges=[caps3?.fast?"fast":"",caps3?.reasoning?"reasoning":""].filter(Boolean);return{title:m2,value:m2,hint:badges.length>0?badges.join(" \xB7 "):void 0}}),{title:"Refresh model options",value:REFRESH,description:"force reload from gateway",hint:void 0,category:"Actions"}];return $jsx(DialogSelect,{title:props.title?`${props.title} \xB7 ${p?.name??provider}`:`Switch Model (${p?.name??provider})`,options,current:provider===data2.provider?data2.model:void 0,onSelect:(o)=>{if(o.value===REFRESH)return refresh();if(dialog.clear(),provider)apply(o.value,provider)},onKey,placeholder:"Search models...",footer})},openModelPicker=(dialog,gw,opts)=>{dialog.replace($jsx(ModelPickerDialog,{gw,title:opts?.title,onApply:opts?.onApply,refresh:opts?.refresh}))};var flatten=(obj,prefix="")=>Object.entries(obj).flatMap(([k2,v2])=>{let key3=prefix?`${prefix}.${k2}`:k2;if(v2&&typeof v2==="object"&&!Array.isArray(v2))return flatten(v2,key3);return[[key3,v2]]}),setNested=(obj,path4,val)=>{let parts2=path4.split("."),cur=obj;for(let i=0;i<parts2.length-1;i++){if(!cur[parts2[i]]||typeof cur[parts2[i]]!=="object")cur[parts2[i]]={};cur=cur[parts2[i]]}cur[parts2[parts2.length-1]]=val},getNested=(obj,path4)=>{let parts2=path4.split("."),cur=obj;for(let p of parts2)if(cur&&typeof cur==="object"&&!Array.isArray(cur))cur=cur[p];else return;return cur},FieldRow2=import_react97.memo((props)=>{let theme=useTheme().theme,f=props.field,bg2=props.active?theme.backgroundElement:void 0,indicator=props.active?"\u25B8 ":" ",mark2=props.changed?"\u25CF ":f.set?"\xB7":" ",markFg=props.changed?theme.warning:theme.textMuted,display2=()=>{if(props.editing)return props.buf+"\u2588";if(f.type==="readonly"){let n=Array.isArray(f.value)?f.value.length:f.value&&typeof f.value==="object"?Object.keys(f.value).length:0;return n===0?"\u2014":`${n} item${n===1?"":"s"}`}if(f.type==="boolean")return f.value?"\u2713 ON":"\u2717 OFF";return String(f.value??"")},hint=()=>{if(props.readonly||f.type==="readonly")return"\uD83D\uDD12";if(f.type==="boolean")return"[space]";if(f.type==="select")return"[h/l]";return"[enter]"},ro=props.readonly||f.type==="readonly",valFg=ro||!f.set?theme.textMuted:f.type==="boolean"?f.value?theme.success:theme.error:theme.text,labelFg=ro?theme.textMuted:props.active?theme.accent:theme.text,lead2=4+(props.badge!==void 0?12:0),glyph=props.active?EFFECT_GLYPH[f.effect]:"";return $jsxs("box",{id:props.id,flexDirection:"column",backgroundColor:bg2,children:[$jsxs("box",{flexDirection:"row",height:1,children:[$jsx(Col,{w:2,fg:markFg,children:mark2}),$jsx(Col,{w:2,fg:props.active?theme.primary:theme.text,children:indicator}),props.badge!==void 0?$jsx(Col,{w:12,fg:theme.textMuted,children:props.badge}):null,$jsx(Col,{w:40,fg:labelFg,children:f.label}),$jsx(Col,{grow:!0,min:6,fg:valFg,children:display2()}),$jsx(Col,{w:2,fg:theme.textMuted,children:glyph}),$jsx(Col,{w:9,fg:theme.textMuted,right:!0,children:props.active?hint():""})]}),props.error?$jsxs("box",{flexDirection:"row",height:1,children:[$jsx(Col,{w:lead2+40,fg:theme.textMuted,children:""}),$jsx(Col,{grow:!0,min:6,fg:theme.error,children:`\u2717 ${props.error}`})]}):props.active&&f.doc?$jsxs("box",{flexDirection:"row",minHeight:1,children:[$jsx("box",{width:lead2,flexShrink:0}),$jsx("box",{width:40,flexShrink:0,minHeight:1,children:$jsx("text",{wrapMode:"word",fg:theme.textMuted,children:f.doc})})]}):null]})}),SlotRow=import_react97.memo((p)=>{let theme=useTheme().theme,main=p.s.kind==="main",val=main?`${p.s.provider||"(unset)"} \xB7 ${p.s.model||"(unset)"}`:p.s.auto?"auto (use main model)":`${p.s.provider} \xB7 ${p.s.model||"(provider default)"}`;return $jsxs("box",{id:p.id,flexDirection:"row",height:1,backgroundColor:p.on?theme.backgroundElement:void 0,children:[$jsx(Col,{w:2,fg:p.on?theme.primary:theme.text,children:p.on?"\u25B8 ":" "}),$jsx(Col,{w:2,fg:main?theme.primary:theme.textMuted,children:main?"\u2605":" "}),$jsx(Col,{w:16,fg:p.on?theme.accent:theme.text,children:p.s.label}),$jsx(Col,{w:22,fg:theme.textMuted,children:p.s.hint}),$jsx(Col,{grow:!0,min:10,fg:p.s.auto?theme.textMuted:theme.text,children:val}),$jsx(Col,{w:14,fg:theme.textMuted,right:!0,children:p.on?main?"[enter]":"[enter] [x]":""})]})}),Config2=import_react97.memo((props)=>{let theme=useTheme().theme,gw=useGateway(),restartGateway=useGatewayRestart(),toast=useToast(),dialog=useDialog(),[raw,setRaw]=import_react97.useState({}),rawRef=import_react97.useRef(raw);rawRef.current=raw;let[original,setOriginal]=import_react97.useState({}),[yaml,setYaml]=import_react97.useState(""),[mode2,setMode]=import_react97.useState("form"),[cat,setCat]=import_react97.useState(0),[cursor,setCursor]=import_react97.useState(0),[editing,setEditing]=import_react97.useState(!1),[buf,setBuf]=import_react97.useState(""),[err,setErr]=import_react97.useState({}),[searching,setSearching]=import_react97.useState(!1),[query2,setQuery]=import_react97.useState(""),[focus,setFocus]=import_react97.useState("categories"),[managed,setManaged]=import_react97.useState(null),[loadErr,setLoadErr]=import_react97.useState(null),loads=import_react97.useRef(0);import_react97.useEffect(()=>{managedSystem().then(setManaged)},[]);let load4=import_react97.useCallback(()=>{let gen=++loads.current;gw.request("config.get",{key:"full"}).then((res)=>{if(loads.current!==gen)return;let parsed=res.config??{};rawRef.current=structuredClone(parsed),setRaw(rawRef.current),setOriginal(structuredClone(parsed)),setYaml($stringify(parsed)),setErr({}),setLoadErr(null)}).catch((e)=>{if(loads.current===gen)setLoadErr(e instanceof Error?e.message:String(e))})},[gw]);import_react97.useEffect(()=>{return load4(),()=>{loads.current++}},[load4]);let all=buildFields(raw),grouped=all.reduce((map,f)=>{let g=groupOf(f.key);if(!map.has(g))map.set(g,[]);return map.get(g).push(f),map},new Map(GROUPS.map((g)=>[g,[]]))),groups=[...grouped.keys()];groups.splice(1,0,"models");let active=groups[cat]??groups[0],onSlots=active==="models"&&!searching,slots=readSlots(raw),secs=searching&&query2.trim()?[{head:null,items:all.filter((f)=>f.key.toLowerCase().includes(query2.toLowerCase()))}]:sections(active,grouped.get(active)??[]),fields=secs.flatMap((s)=>s.items),count3=onSlots?slots.length:fields.length,follow=useFollow("cfg"),catFollow=useFollow("cfg-cat"),changed=(key3)=>JSON.stringify(getNested(raw,key3))!==JSON.stringify(getNested(original,key3)),nChanged=all.reduce((n,f)=>n+(changed(f.key)?1:0),0),update=(key3,val)=>{loads.current++;let next2=structuredClone(rawRef.current);setNested(next2,key3,val),rawRef.current=next2,setRaw(next2),setYaml($stringify(next2))},fmt3=(v2)=>v2===void 0?"\u2014":Array.isArray(v2)?v2.join(", "):String(v2),save2=async()=>{if(managed){toast.show({variant:"error",message:`Managed by ${managed} \u2014 edit configuration.nix`});return}let nErr=Object.keys(err).length;if(nErr>0){toast.show({variant:"error",message:`${nErr} invalid field${nErr===1?"":"s"}`});return}let target=mode2==="yaml"?$parse(yaml)??{}:rawRef.current,diffs=flatten(target).filter(([key3])=>JSON.stringify(getNested(target,key3))!==JSON.stringify(getNested(original,key3))).map(([key3,val])=>({key:key3,from:getNested(original,key3),to:val}));if(diffs.length===0){toast.show({variant:"info",message:"No changes"});return}let body=diffs.map((d2)=>`${d2.key}: ${fmt3(d2.from)} \u2192 ${fmt3(d2.to)}`).join(`
4124
4124
  `);if(!await openConfirm(dialog,{title:`Write ${diffs.length} change${diffs.length===1?"":"s"} to config.yaml?`,body,yes:"save"}))return;let res=await writeConfig(gw,diffs.map((d2)=>({key:d2.key,to:d2.to})));for(let w2 of res.warnings)toast.show({variant:"info",message:`${w2.key}: ${w2.msg}`});if(res.failed.length>0){load4(),toast.show({variant:"error",message:`${res.failed.length} failed: ${res.failed.map((f)=>f.key).join(", ")}`});return}let landed=diffs.filter((d2)=>res.ok.includes(d2.key)),miss=await verifyWrite(gw,landed.map((d2)=>({key:d2.key,to:d2.to}))).catch((e)=>{return toast.show({variant:"error",message:e instanceof Error?e.message:String(e)}),null});if(!miss)return;if(miss.length>0){toast.show({variant:"error",message:`Write didn't land: ${miss.join(", ")}`});return}load4();let tier=maxEffect(res.ok);if(tier==="restart"){if(await openConfirm(dialog,{title:`Saved \u2014 ${res.ok.length} setting${res.ok.length===1?"":"s"} need a gateway restart`,body:"Restart now? This interrupts any running turn.",yes:"restart now",no:"later",danger:!0}))restartGateway("resume"),toast.show({variant:"info",message:"Gateway restarting\u2026"});return}toast.show({variant:"success",message:tier==="live"?"Saved":"Saved \u2014 new sessions pick this up"})},pick=import_react97.useCallback((s)=>{if(managed)return toast.show({variant:"error",message:`Managed by ${managed}`});let warnStaleAux=async(prov)=>{let stale=staleAuxForMain(readSlots(raw),prov);if(stale.length===0)return;let names=stale.map((x2)=>x2.label).join(", ");if(!await openConfirm(dialog,{title:"Auxiliary models still pinned to another provider",body:`${names}
4125
4125
 
4126
4126
  Reset these slots to auto so they follow the main model?`,yes:"reset stale",no:"keep"})){toast.show({variant:"warning",message:`Aux still pinned to another provider: ${names}. Press X to reset all to auto.`});return}for(let slot of stale){let r=await resetAux(gw,slot.key);if(r.failed.length){toast.show({variant:"error",message:`${slot.label}: ${r.failed.map((f)=>f.err).join("; ")}`});return}}toast.show({variant:"success",message:`Reset ${stale.length} aux slot${stale.length===1?"":"s"} \u2192 auto`}),load4()};openModelPicker(dialog,gw,{title:s.kind==="main"?"Set main model":`Set auxiliary \xB7 ${s.label}`,onApply:async(prov,model)=>{let token=dialog.version(),r=await assign(gw,s.key,prov,model);if(r.failed.length)return toast.show({variant:"error",message:r.failed.map((f)=>f.err).join("; ")});if(toast.show({variant:"success",message:s.kind==="main"?`main \u2192 ${prov} \xB7 ${model}`:`${s.key} \u2192 ${prov} \xB7 ${model}`}),r.warning)toast.show({variant:"warning",message:r.warning});if(load4(),s.kind==="main"&&dialog.version()===token)await warnStaleAux(prov)}})},[gw,dialog,toast,load4,managed,raw]),unset=import_react97.useCallback((s)=>{if(managed||s.kind!=="aux"||s.auto)return;resetAux(gw,s.key).then((r)=>{if(r.failed.length)return toast.show({variant:"error",message:r.failed.map((f)=>f.err).join("; ")});toast.show({variant:"success",message:`${s.key} \u2192 auto`}),load4()})},[gw,toast,load4,managed]),unsetAll=import_react97.useCallback(()=>openConfirm(dialog,{title:"Reset all auxiliary slots to auto?",body:`${AUX_TASKS.length} slots. Each falls back to the main model.`,yes:"reset",danger:!0}).then((ok)=>{if(!ok)return;resetAux(gw,"all").then((r)=>{if(r.failed.length)return toast.show({variant:"error",message:`${r.failed.length} failed`});toast.show({variant:"success",message:"All auxiliary slots \u2192 auto"}),load4()})}),[gw,dialog,toast,load4]),keys=useKeys();if(useKeyboard((key3)=>{if(!props.focused||dialog.open())return;if(keys.match("config.mode",key3)&&!editing&&!searching){setMode((m2)=>m2==="form"?"yaml":"form");return}if(keys.match("config.save",key3))return void save2();if(mode2==="yaml"){if(key3.name==="backspace"){loads.current++,setYaml((prev)=>prev.slice(0,-1));return}if(key3.name==="return"){loads.current++,setYaml((prev)=>prev+`
@@ -4156,13 +4156,13 @@ Usage:
4156
4156
  herm --no-splash skip the launch splash
4157
4157
  herm -v, --version print version
4158
4158
  herm -h, --help show this help
4159
- `;var TIERS=["block","slick","tiny"],pickFont=(innerW)=>TIERS.find((f)=>measureText({text:"HERM",font:f}).width<=innerW)??"tiny",clip=(s,w2)=>[...s].length<=w2?s:[...s].slice(0,Math.max(1,w2-1)).join("")+"\u2026";function Splash(p){let theme=useTheme().theme,ref=import_react124.useRef(null),[box2,setBox]=import_react124.useState({w:0,h:0}),renderer=useRenderer();import_react124.useEffect(()=>{let cb=async()=>{let r=ref.current;if(!r)return;setBox((b2)=>b2.w===r.width&&b2.h===r.height?b2:{w:r.width,h:r.height})};return renderer.setFrameCallback(cb),()=>renderer.removeFrameCallback(cb)},[renderer]);let{lines:lines3,inner}=import_react124.useMemo(()=>frame(box2.w,box2.h),[box2.w,box2.h]),font=import_react124.useMemo(()=>pickFont(inner.w),[inner.w]),[tip2,setTip]=import_react124.useState(()=>exports_tips.randomTip()),behind=p.info?.behind,count3=behind==null||behind<0?null:behind===0?"up to date":`${behind} behind`,sub2=[`v${VERSION}`,p.info?`hermes ${p.info.agentVersion??"?"}`:"\u2026",count3,p.info?.model].filter(Boolean).join(" \xB7 "),prompt=p.last&&!p.composing,title=p.last?.title?.trim()||p.last?.id;return $jsxs("box",{ref,position:"absolute",left:0,top:0,right:0,bottom:0,zIndex:50,backgroundColor:theme.background,children:[lines3.map((l,i)=>$jsx("box",{position:"absolute",top:i,left:0,height:1,children:$jsx("text",{fg:theme.accent,children:l})},i)),lines3.length>0&&$jsxs("box",{position:"absolute",left:inner.x,top:inner.y,width:inner.w,height:inner.h,flexDirection:"column",alignItems:"center",justifyContent:"center",children:[$jsx("box",{children:$jsx("ascii-font",{text:"HERM",font,color:[theme.accent,theme.textMuted],selectable:!1})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:clip(sub2,inner.w)})}),p.news?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:clip(`\u203A ${p.news}`,inner.w)})}):null,$jsx("box",{height:2}),p.loading?$jsx("text",{fg:theme.textMuted,children:$jsx("span",{fg:theme.accent,children:"Loading\u2026"})}):prompt?$jsxs($Fragment,{children:[$jsxs("text",{fg:theme.textMuted,children:["continue ",$jsxs("span",{fg:theme.text,children:['"',clip(title??"",Math.max(8,inner.w-14)),'"']})," ?"]}),$jsxs("text",{fg:theme.textMuted,children:[$jsx("span",{fg:theme.accent,children:"[enter]"})," yes \xB7 type to start fresh"]})]}):$jsxs("text",{fg:theme.textMuted,children:[$jsx("span",{fg:theme.accent,children:"[enter]"})," to send"]}),inner.h>=14?$jsx("box",{position:"absolute",bottom:0,left:0,right:0,flexDirection:"column",alignItems:"center",onMouseDown:()=>setTip((t2)=>exports_tips.randomTip(t2)),children:$jsx("text",{wrapMode:"word",children:exports_tips.splitTip(clip(tip2,inner.w*2)).map((s,i)=>$jsx("span",{fg:s.hl?theme.accent:theme.textMuted,children:s.t},i))})}):null]})]})}init_sessions_db();var LOCAL_COMMANDS=[{name:"clear",description:"Clear chat messages",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"new",description:"Start a new session",category:"Client",aliases:["reset"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"theme",description:"Switch color theme or mode",category:"Client",aliases:[],argsHint:"[name|light|dark]",subcommands:[],source:"local",target:"local"},{name:"help",description:"Show keyboard shortcuts",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"keys",description:"Rebind keyboard shortcuts",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"logs",description:"Show gateway stderr log",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"title",description:"Set session title",category:"Client",aliases:[],argsHint:"[text]",subcommands:[],source:"local",target:"local"},{name:"rollback",description:"Browse & restore checkpoints",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"history",description:"Server-side transcript viewer",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"status",description:"Version, model, paths",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"usage",description:"Credits, account status, tokens, context fill, cost",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"profile",description:"Active profile details",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"journey",description:"Open the learning journey graph",category:"Info",aliases:["learning","memory-graph"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"steer",description:"Inject a note mid-turn (no interrupt)",category:"Session",aliases:[],argsHint:"[text]",subcommands:[],source:"local",target:"local"},{name:"reload-mcp",description:"Restart MCP servers & rediscover tools",category:"Session",aliases:[],argsHint:"[now|always]",subcommands:["now","always"],source:"local",target:"local"},{name:"reload",description:"Hot-reload ~/.hermes/.env (API keys)",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"reload-skills",description:"Re-scan ~/.hermes/skills/ for added/removed skills",category:"Session",aliases:["reload_skills"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"chafa",description:"Render image via chafa (demo)",category:"Client",aliases:[],argsHint:"<path>",subcommands:[],source:"local",target:"local"},{name:"splash",description:"Show the launch splash",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"goal",description:"Set/control the session goal",category:"Session",aliases:[],argsHint:"[text|done|pause|resume|clear|status]",subcommands:["done","pause","resume","clear","status"],source:"command",target:"gateway"},{name:"skin",description:"Switch Hermes skin (+ theme + eikon)",category:"Client",aliases:[],argsHint:"[name]",subcommands:[...SKINS],source:"local",target:"local"},{name:"voice",description:"Toggle voice recording",category:"Client",aliases:[],argsHint:"[on|off|status|tts]",subcommands:["on","off","status","tts"],source:"local",target:"local"},{name:"queue",description:"Queue a prompt for the next idle turn",category:"Session",aliases:["q"],argsHint:"[text]",subcommands:[],source:"local",target:"local"},{name:"yolo",description:"Toggle approval bypass",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"quit",description:"Exit herm",category:"Exit",aliases:["exit"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"stash",description:"Park the prompt (pop/list to restore)",category:"Client",aliases:[],argsHint:"[pop|list]",subcommands:["pop","list"],source:"local",target:"local"},{name:"undo",description:"Remove the last conversation turn",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"redo",description:"Re-send the last undone message",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"retry",description:"Rewind and re-send the last user turn",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"setup",description:"Show setup guidance",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"branch",description:"Fork current conversation",category:"Session",aliases:["fork"],argsHint:"[name]",subcommands:[],source:"local",target:"local"},{name:"compress",description:"Compress conversation context",category:"Session",aliases:["compact"],argsHint:"[here [N] | focus topic | --preview|--dry-run]",subcommands:[],source:"local",target:"local"},{name:"browser",description:"Connect/disconnect a CDP browser",category:"Session",aliases:[],argsHint:"[connect|disconnect|status] [url]",subcommands:["connect","disconnect","status"],source:"local",target:"local"}];function fallbacks(){return LOCAL_COMMANDS.map((c)=>c.name==="skin"?{...c,subcommands:skins()}:c)}var INTERCEPT=["save","resume","model","copy","paste","image","background","mouse","redraw"],LOCAL_NAMES=new Set([...LOCAL_COMMANDS.filter((command)=>command.target==="local").map((command)=>command.name),...INTERCEPT]);function resolve9(list3,name){let q5=name.toLowerCase();for(let c of list3)if(c.name.toLowerCase()===q5||c.aliases.some((a)=>a.toLowerCase()===q5))return{hit:c};let hits=new Set;for(let c of list3)for(let n of[c.name,...c.aliases])if(n.toLowerCase().startsWith(q5)){hits.add(c);break}if(hits.size===1)return{hit:[...hits][0]};if(hits.size===0)return{miss:!0};return{ambiguous:[...hits].map((c)=>`/${c.name}`).sort()}}function matchSub(list3,input){let m2=input.match(/^\/(\w+)\s+(\S*)$/);if(!m2)return null;let name=m2[1],sub2=m2[2],cmd=list3.find((c)=>c.name===name||c.aliases.includes(name));if(!cmd||cmd.subcommands.length===0)return null;let q5=sub2.toLowerCase(),matches=cmd.subcommands.filter((s)=>s.toLowerCase().startsWith(q5));if(matches.length===0)return null;return matches.map((s)=>({...cmd,name:`${cmd.name} ${s}`,description:`${cmd.name} \u2192 ${s}`,argsHint:"",subcommands:[]}))}var CATEGORY_ORDER=["Client","Session","Configuration","Config","Tools & Skills","Skills","Plugins","MCP","Info","Exit"];function sort(list3){let idx=(c)=>{let i=CATEGORY_ORDER.indexOf(c);return i<0?999:i};return[...list3].sort((a,b2)=>{let ca=idx(a.category)-idx(b2.category);return ca!==0?ca:a.name.localeCompare(b2.name)})}var import_react126=__toESM(require_react_production(),1);var bare=(s)=>s[0]==="/"?s.slice(1):s;function useSlashCommands(){let gw=useGateway(),ready=useGatewayReady(),[cmds,setCmds]=import_react126.useState(fallbacks),fetch2=import_react126.useCallback(async()=>{let res=await gw.request("commands.catalog").catch(()=>null),fallback=fallbacks();if(!res){setCmds(fallback);return}let cat=new Map;for(let g of res.categories??[])for(let[n]of g.pairs??[])cat.set(bare(n),g.name);let alias=new Map,addAlias=(name,value2)=>{let k2=bare(name),v2=bare(value2);if(k2===v2)return;let list3=alias.get(k2)??[];if(!list3.includes(v2))alias.set(k2,[...list3,v2])};for(let l of fallback)for(let a of l.aliases)addAlias(l.name,a);for(let[a,c]of Object.entries(res.canon??{}))addAlias(c,a);let sub2=new Map(Object.entries(res.sub??{}).map(([k2,v2])=>[bare(k2),v2])),local=new Map(fallback.map((c)=>[c.name,c])),remote2=(res.pairs??[]).map(([raw2,desc])=>{let name=bare(raw2),l=local.get(name),description=name==="quit"?desc.replace(/\s*\(usage:[^)]*\)\s*$/,""):desc;return{name,description,category:cat.get(name)??(name.includes(":")?"Skills":"Command"),aliases:alias.get(name)??[],argsHint:l?.argsHint??"",subcommands:sub2.get(name)??l?.subcommands??[],source:"command",target:LOCAL_NAMES.has(name)?"local":"gateway"}}),seen=new Set(remote2.map((c)=>c.name)),locals=fallback.filter((c)=>!seen.has(c.name));setCmds(sort([...locals,...remote2]))},[gw]);return import_react126.useEffect(()=>{if(ready)fetch2()},[ready,fetch2]),{cmds,refresh:fetch2}}var import_react140=__toESM(require_react_production(),1);var import_react127=__toESM(require_react_production(),1);var GROUPS2=[{title:"Global",scope:"global"},{title:"Composer",scope:"composer"},{title:"Lists",scope:"list"},{title:"Dialogs",scope:"dialog"},{title:"Sessions",scope:"sessions"},{title:"Agents",scope:"agents"},{title:"Config",scope:"config"},{title:"Eikon",scope:"eikon"}],COLS3=2,HelpDialog=()=>{let theme=useTheme().theme,keys=useKeys(),sections2=import_react127.useMemo(()=>GROUPS2.map((g)=>({title:g.title,rows:keys.all(g.scope).filter((e)=>e.id!=="leader"&&e.chord.length>0).map((e)=>[keys.print(e.id),e.desc])})).filter((s)=>s.rows.length>0),[keys]),total=sections2.reduce((n,s)=>n+s.rows.length+2,0),split2=Math.ceil(total/COLS3),cols2=[[],[]],acc2=0;for(let s of sections2){let h2=s.rows.length+2,i=acc2+h2<=split2||cols2[0].length===0?0:1;if(cols2[i].push(s),i===0)acc2+=h2}return $jsxs("box",{flexDirection:"column",width:104,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.text,children:$jsx("strong",{children:"Keyboard Shortcuts"})})}),$jsx("text",{fg:theme.textMuted,children:`leader = ${keys.print("leader")}`})]}),$jsx("box",{height:1}),$jsx("box",{flexDirection:"row",gap:3,children:cols2.map((col,ci)=>$jsx("box",{flexDirection:"column",flexGrow:1,flexBasis:0,children:col.map((s)=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:s.title})}),s.rows.map(([chord,desc])=>$jsxs("box",{flexDirection:"row",height:1,paddingLeft:1,children:[$jsx("box",{width:14,children:$jsx("text",{fg:theme.accent,children:chord})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:desc})})]},chord+desc))]},s.title))},ci))}),$jsx("text",{fg:theme.textMuted,children:"esc to close"})]})};var import_react128=__toESM(require_react_production(),1);import{existsSync as existsSync29,readFileSync as readFileSync21}from"fs";import{homedir as homedir8}from"os";import{join as join24}from"path";var OC_TO_HERM=[["leader","leader"],["app_exit","app.exit"],["terminal_suspend","app.suspend"],["sidebar_toggle","app.sidebar"],["command_list","palette.open"],["editor_open","editor.open"],["theme_list","theme.pick"],["model_list","model.pick"],["status_view","status.open"],["session_new","session.new"],["session_compact","session.compress"],["session_timeline","session.timeline"],["session_interrupt","session.interrupt"],["session_rename","sessions.rename"],["messages_copy","reply.copy"],["messages_redo","session.redo"],["input_clear","input.clear"],["input_submit","input.submit"],["input_newline","input.newline"],["input_paste","clipboard.attach"]],TABLE2=new Map(OC_TO_HERM),ocPaths=(cwd=process.cwd(),home5=homedir8())=>[join24(home5,".config","opencode","tui.json"),join24(cwd,"tui.json"),join24(cwd,".opencode","tui.json"),join24(cwd,"opencode.json")],read3=(p)=>{if(!existsSync29(p))return{};return JSON.parse(readFileSync21(p,"utf8")).keybinds??{}},loadOcKeybinds=(cwd,home5)=>{let merged={},sources=[];for(let p of ocPaths(cwd,home5)){let kb=read3(p);if(Object.keys(kb).length===0)continue;Object.assign(merged,kb),sources.push(p)}let overrides={},skipped=[];for(let[oc,chord]of Object.entries(merged)){let herm=TABLE2.get(oc);if(herm)overrides[herm]=chord;else skipped.push(oc)}return{overrides,skipped,sources}};var GROUPS3=[{title:"Global",scope:"global"},{title:"Composer",scope:"composer"},{title:"Lists",scope:"list"},{title:"Dialogs",scope:"dialog"},{title:"Sessions",scope:"sessions"},{title:"Agents",scope:"agents"},{title:"Config",scope:"config"}],KeysDialog=(props)=>{let theme=useTheme().theme,keys=useKeys(),toast=useToast(),overrides=exports_preferences.get("keys")??{},rows3=import_react128.useMemo(()=>GROUPS3.flatMap((g)=>{let entries2=keys.all(g.scope).filter((e)=>e.id!=="leader");if(entries2.length===0)return[];return[{type:"header",title:g.title},...entries2.map((e)=>({type:"action",id:e.id,desc:e.desc,chord:e.chord,override:overrides[e.id]!==void 0}))]}),[keys,overrides]),actionRows=rows3.map((r,i)=>({r,i})).filter((x2)=>x2.r.type==="action"),[sel,setSel]=import_react128.useState(0),cur=actionRows[sel]?.r,curConflicts=cur?conflictsWith(keys.table,cur.id):[],write=(id,value2)=>{let next2={...exports_preferences.get("keys")??{}};if(value2===void 0)delete next2[id];else next2[id]=value2;exports_preferences.set("keys",next2)},rebind=(id)=>{let now=overrides[id]??DEFAULTS2[id].chord;openTextPrompt(props.dialog,{title:`Rebind ${id}`,label:"Chord (e.g. ctrl+k, <leader>m, shift+return; empty = unbind)",initial:now}).then((v2)=>{if(openKeys(props.dialog),v2===null)return;let parsed=parse2(v2);write(id,parsed.length===0?"none":v2)})},importOc=()=>{let r=loadOcKeybinds();if(r.sources.length===0)return toast.show({variant:"info",message:"No opencode tui.json found"});let n=Object.keys(r.overrides).length;openConfirm(props.dialog,{title:`Import ${n} keybind${n===1?"":"s"} from opencode?`,body:`${r.sources.map((s)=>`\xB7 ${s}`).join(`
4159
+ `;var TIERS=["block","slick","tiny"],pickFont=(innerW)=>TIERS.find((f)=>measureText({text:"HERM",font:f}).width<=innerW)??"tiny",clip=(s,w2)=>[...s].length<=w2?s:[...s].slice(0,Math.max(1,w2-1)).join("")+"\u2026";function Splash(p){let theme=useTheme().theme,ref=import_react124.useRef(null),[box2,setBox]=import_react124.useState({w:0,h:0}),renderer=useRenderer();import_react124.useEffect(()=>{let cb=async()=>{let r=ref.current;if(!r)return;setBox((b2)=>b2.w===r.width&&b2.h===r.height?b2:{w:r.width,h:r.height})};return renderer.setFrameCallback(cb),()=>renderer.removeFrameCallback(cb)},[renderer]);let{lines:lines3,inner}=import_react124.useMemo(()=>frame(box2.w,box2.h),[box2.w,box2.h]),font=import_react124.useMemo(()=>pickFont(inner.w),[inner.w]),[tip2,setTip]=import_react124.useState(()=>exports_tips.randomTip()),behind=p.info?.behind,count3=behind==null||behind<0?null:behind===0?"up to date":`${behind} behind`,sub2=[`v${VERSION}`,p.info?`hermes ${p.info.agentVersion??"?"}`:"\u2026",count3,p.info?.model].filter(Boolean).join(" \xB7 "),prompt=p.last&&!p.composing,title=p.last?.title?.trim()||p.last?.id;return $jsxs("box",{ref,position:"absolute",left:0,top:0,right:0,bottom:0,zIndex:50,backgroundColor:theme.background,children:[lines3.map((l,i)=>$jsx("box",{position:"absolute",top:i,left:0,height:1,children:$jsx("text",{fg:theme.accent,children:l})},i)),lines3.length>0&&$jsxs("box",{position:"absolute",left:inner.x,top:inner.y,width:inner.w,height:inner.h,flexDirection:"column",alignItems:"center",justifyContent:"center",children:[$jsx("box",{children:$jsx("ascii-font",{text:"HERM",font,color:[theme.accent,theme.textMuted],selectable:!1})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:clip(sub2,inner.w)})}),p.news?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:clip(`\u203A ${p.news}`,inner.w)})}):null,$jsx("box",{height:2}),p.loading?$jsx("text",{fg:theme.textMuted,children:$jsx("span",{fg:theme.accent,children:"Loading\u2026"})}):prompt?$jsxs($Fragment,{children:[$jsxs("text",{fg:theme.textMuted,children:["continue ",$jsxs("span",{fg:theme.text,children:['"',clip(title??"",Math.max(8,inner.w-14)),'"']})," ?"]}),$jsxs("text",{fg:theme.textMuted,children:[$jsx("span",{fg:theme.accent,children:"[enter]"})," yes \xB7 type to start fresh"]})]}):$jsxs("text",{fg:theme.textMuted,children:[$jsx("span",{fg:theme.accent,children:"[enter]"})," to send"]}),inner.h>=14?$jsx("box",{position:"absolute",bottom:0,left:0,right:0,flexDirection:"column",alignItems:"center",onMouseDown:()=>setTip((t2)=>exports_tips.randomTip(t2)),children:$jsx("text",{wrapMode:"word",children:exports_tips.splitTip(clip(tip2,inner.w*2)).map((s,i)=>$jsx("span",{fg:s.hl?theme.accent:theme.textMuted,children:s.t},i))})}):null]})]})}init_sessions_db();var LOCAL_COMMANDS=[{name:"clear",description:"Clear chat messages",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"new",description:"Start a new session",category:"Client",aliases:["reset"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"theme",description:"Switch color theme or mode",category:"Client",aliases:[],argsHint:"[name|light|dark]",subcommands:[],source:"local",target:"local"},{name:"help",description:"Show keyboard shortcuts",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"keys",description:"Rebind keyboard shortcuts",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"logs",description:"Show gateway stderr log",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"title",description:"Set session title",category:"Client",aliases:[],argsHint:"[text]",subcommands:[],source:"local",target:"local"},{name:"rollback",description:"Browse & restore checkpoints",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"history",description:"Server-side transcript viewer",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"status",description:"Version, model, paths",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"usage",description:"Credits, account status, tokens, context fill, cost",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"profile",description:"Active profile details",category:"Info",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"journey",description:"Open the learning journey graph",category:"Info",aliases:["learning","memory-graph"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"steer",description:"Inject a note mid-turn (no interrupt)",category:"Session",aliases:[],argsHint:"[text]",subcommands:[],source:"local",target:"local"},{name:"reload-mcp",description:"Restart MCP servers & rediscover tools",category:"Session",aliases:[],argsHint:"[now|always]",subcommands:["now","always"],source:"local",target:"local"},{name:"reload",description:"Hot-reload ~/.hermes/.env (API keys)",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"reload-skills",description:"Re-scan ~/.hermes/skills/ for added/removed skills",category:"Session",aliases:["reload_skills"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"chafa",description:"Render image via chafa (demo)",category:"Client",aliases:[],argsHint:"<path>",subcommands:[],source:"local",target:"local"},{name:"splash",description:"Show the launch splash",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"goal",description:"Set/control the session goal",category:"Session",aliases:[],argsHint:"[text|done|pause|resume|clear|status]",subcommands:["done","pause","resume","clear","status"],source:"command",target:"gateway"},{name:"skin",description:"Switch Hermes skin (+ theme + eikon)",category:"Client",aliases:[],argsHint:"[name]",subcommands:[...SKINS],source:"local",target:"local"},{name:"voice",description:"Toggle voice recording",category:"Client",aliases:[],argsHint:"[on|off|status|tts]",subcommands:["on","off","status","tts"],source:"local",target:"local"},{name:"queue",description:"Queue a prompt for the next idle turn",category:"Session",aliases:["q"],argsHint:"[text]",subcommands:[],source:"local",target:"local"},{name:"yolo",description:"Toggle approval bypass",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"quit",description:"Exit herm",category:"Exit",aliases:["exit"],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"stash",description:"Park the prompt (pop/list to restore)",category:"Client",aliases:[],argsHint:"[pop|list]",subcommands:["pop","list"],source:"local",target:"local"},{name:"undo",description:"Remove the last conversation turn",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"redo",description:"Re-send the last undone message",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"retry",description:"Rewind and re-send the last user turn",category:"Session",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"setup",description:"Show setup guidance",category:"Client",aliases:[],argsHint:"",subcommands:[],source:"local",target:"local"},{name:"branch",description:"Fork current conversation",category:"Session",aliases:["fork"],argsHint:"[name]",subcommands:[],source:"local",target:"local"},{name:"compress",description:"Compress conversation context",category:"Session",aliases:["compact"],argsHint:"[here [N] | focus topic | --preview|--dry-run]",subcommands:[],source:"local",target:"local"},{name:"browser",description:"Connect/disconnect a CDP browser",category:"Session",aliases:[],argsHint:"[connect|disconnect|status] [url]",subcommands:["connect","disconnect","status"],source:"local",target:"local"}];function fallbacks(){return LOCAL_COMMANDS.map((c)=>c.name==="skin"?{...c,subcommands:skins()}:c)}var INTERCEPT=["save","resume","model","copy","paste","image","background","mouse","redraw"],LOCAL_NAMES=new Set([...LOCAL_COMMANDS.filter((command)=>command.target==="local").map((command)=>command.name),...INTERCEPT]);function resolve9(list3,name){let q5=name.toLowerCase();for(let c of list3)if(c.name.toLowerCase()===q5||c.aliases.some((a)=>a.toLowerCase()===q5))return{hit:c};let hits=new Set;for(let c of list3)for(let n of[c.name,...c.aliases])if(n.toLowerCase().startsWith(q5)){hits.add(c);break}if(hits.size===1)return{hit:[...hits][0]};if(hits.size===0)return{miss:!0};return{ambiguous:[...hits].map((c)=>`/${c.name}`).sort()}}function matchSub(list3,input){let m2=input.match(/^\/(\w+)\s+(\S*)$/);if(!m2)return null;let name=m2[1],sub2=m2[2],cmd=list3.find((c)=>c.name===name||c.aliases.includes(name));if(!cmd||cmd.subcommands.length===0)return null;let q5=sub2.toLowerCase(),matches=cmd.subcommands.filter((s)=>s.toLowerCase().startsWith(q5));if(matches.length===0)return null;return matches.map((s)=>({...cmd,name:`${cmd.name} ${s}`,description:`${cmd.name} \u2192 ${s}`,argsHint:"",subcommands:[]}))}var CATEGORY_ORDER=["Client","Session","Configuration","Config","Tools & Skills","Skills","Plugins","MCP","Info","Exit"];function sort(list3){let idx=(c)=>{let i=CATEGORY_ORDER.indexOf(c);return i<0?999:i};return[...list3].sort((a,b2)=>{let ca=idx(a.category)-idx(b2.category);return ca!==0?ca:a.name.localeCompare(b2.name)})}var import_react126=__toESM(require_react_production(),1);var bare=(s)=>s[0]==="/"?s.slice(1):s;function useSlashCommands(){let gw=useGateway(),ready=useGatewayReady(),[cmds,setCmds]=import_react126.useState(fallbacks),fetch2=import_react126.useCallback(async()=>{let res=await gw.request("commands.catalog").catch(()=>null),fallback2=fallbacks();if(!res){setCmds(fallback2);return}let cat=new Map;for(let g of res.categories??[])for(let[n]of g.pairs??[])cat.set(bare(n),g.name);let alias=new Map,addAlias=(name,value2)=>{let k2=bare(name),v2=bare(value2);if(k2===v2)return;let list3=alias.get(k2)??[];if(!list3.includes(v2))alias.set(k2,[...list3,v2])};for(let l of fallback2)for(let a of l.aliases)addAlias(l.name,a);for(let[a,c]of Object.entries(res.canon??{}))addAlias(c,a);let sub2=new Map(Object.entries(res.sub??{}).map(([k2,v2])=>[bare(k2),v2])),local=new Map(fallback2.map((c)=>[c.name,c])),remote2=(res.pairs??[]).map(([raw2,desc])=>{let name=bare(raw2),l=local.get(name),description=name==="quit"?desc.replace(/\s*\(usage:[^)]*\)\s*$/,""):desc;return{name,description,category:cat.get(name)??(name.includes(":")?"Skills":"Command"),aliases:alias.get(name)??[],argsHint:l?.argsHint??"",subcommands:sub2.get(name)??l?.subcommands??[],source:"command",target:LOCAL_NAMES.has(name)?"local":"gateway"}}),seen=new Set(remote2.map((c)=>c.name)),locals=fallback2.filter((c)=>!seen.has(c.name));setCmds(sort([...locals,...remote2]))},[gw]);return import_react126.useEffect(()=>{if(ready)fetch2()},[ready,fetch2]),{cmds,refresh:fetch2}}var import_react140=__toESM(require_react_production(),1);var import_react127=__toESM(require_react_production(),1);var GROUPS2=[{title:"Global",scope:"global"},{title:"Composer",scope:"composer"},{title:"Lists",scope:"list"},{title:"Dialogs",scope:"dialog"},{title:"Sessions",scope:"sessions"},{title:"Agents",scope:"agents"},{title:"Config",scope:"config"},{title:"Eikon",scope:"eikon"}],COLS3=2,HelpDialog=()=>{let theme=useTheme().theme,keys=useKeys(),sections2=import_react127.useMemo(()=>GROUPS2.map((g)=>({title:g.title,rows:keys.all(g.scope).filter((e)=>e.id!=="leader"&&e.chord.length>0).map((e)=>[keys.print(e.id),e.desc])})).filter((s)=>s.rows.length>0),[keys]),total=sections2.reduce((n,s)=>n+s.rows.length+2,0),split2=Math.ceil(total/COLS3),cols2=[[],[]],acc2=0;for(let s of sections2){let h2=s.rows.length+2,i=acc2+h2<=split2||cols2[0].length===0?0:1;if(cols2[i].push(s),i===0)acc2+=h2}return $jsxs("box",{flexDirection:"column",width:104,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.text,children:$jsx("strong",{children:"Keyboard Shortcuts"})})}),$jsx("text",{fg:theme.textMuted,children:`leader = ${keys.print("leader")}`})]}),$jsx("box",{height:1}),$jsx("box",{flexDirection:"row",gap:3,children:cols2.map((col,ci)=>$jsx("box",{flexDirection:"column",flexGrow:1,flexBasis:0,children:col.map((s)=>$jsxs("box",{flexDirection:"column",marginBottom:1,children:[$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:s.title})}),s.rows.map(([chord,desc])=>$jsxs("box",{flexDirection:"row",height:1,paddingLeft:1,children:[$jsx("box",{width:14,children:$jsx("text",{fg:theme.accent,children:chord})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:desc})})]},chord+desc))]},s.title))},ci))}),$jsx("text",{fg:theme.textMuted,children:"esc to close"})]})};var import_react128=__toESM(require_react_production(),1);import{existsSync as existsSync29,readFileSync as readFileSync21}from"fs";import{homedir as homedir8}from"os";import{join as join24}from"path";var OC_TO_HERM=[["leader","leader"],["app_exit","app.exit"],["terminal_suspend","app.suspend"],["sidebar_toggle","app.sidebar"],["command_list","palette.open"],["editor_open","editor.open"],["theme_list","theme.pick"],["model_list","model.pick"],["status_view","status.open"],["session_new","session.new"],["session_compact","session.compress"],["session_timeline","session.timeline"],["session_interrupt","session.interrupt"],["session_rename","sessions.rename"],["messages_copy","reply.copy"],["messages_redo","session.redo"],["input_clear","input.clear"],["input_submit","input.submit"],["input_newline","input.newline"],["input_paste","clipboard.attach"]],TABLE2=new Map(OC_TO_HERM),ocPaths=(cwd=process.cwd(),home5=homedir8())=>[join24(home5,".config","opencode","tui.json"),join24(cwd,"tui.json"),join24(cwd,".opencode","tui.json"),join24(cwd,"opencode.json")],read3=(p)=>{if(!existsSync29(p))return{};return JSON.parse(readFileSync21(p,"utf8")).keybinds??{}},loadOcKeybinds=(cwd,home5)=>{let merged={},sources=[];for(let p of ocPaths(cwd,home5)){let kb=read3(p);if(Object.keys(kb).length===0)continue;Object.assign(merged,kb),sources.push(p)}let overrides={},skipped=[];for(let[oc,chord]of Object.entries(merged)){let herm=TABLE2.get(oc);if(herm)overrides[herm]=chord;else skipped.push(oc)}return{overrides,skipped,sources}};var GROUPS3=[{title:"Global",scope:"global"},{title:"Composer",scope:"composer"},{title:"Lists",scope:"list"},{title:"Dialogs",scope:"dialog"},{title:"Sessions",scope:"sessions"},{title:"Agents",scope:"agents"},{title:"Config",scope:"config"}],KeysDialog=(props)=>{let theme=useTheme().theme,keys=useKeys(),toast=useToast(),overrides=exports_preferences.get("keys")??{},rows3=import_react128.useMemo(()=>GROUPS3.flatMap((g)=>{let entries2=keys.all(g.scope).filter((e)=>e.id!=="leader");if(entries2.length===0)return[];return[{type:"header",title:g.title},...entries2.map((e)=>({type:"action",id:e.id,desc:e.desc,chord:e.chord,override:overrides[e.id]!==void 0}))]}),[keys,overrides]),actionRows=rows3.map((r,i)=>({r,i})).filter((x2)=>x2.r.type==="action"),[sel,setSel]=import_react128.useState(0),cur=actionRows[sel]?.r,curConflicts=cur?conflictsWith(keys.table,cur.id):[],write=(id,value2)=>{let next2={...exports_preferences.get("keys")??{}};if(value2===void 0)delete next2[id];else next2[id]=value2;exports_preferences.set("keys",next2)},rebind=(id)=>{let now=overrides[id]??DEFAULTS2[id].chord;openTextPrompt(props.dialog,{title:`Rebind ${id}`,label:"Chord (e.g. ctrl+k, <leader>m, shift+return; empty = unbind)",initial:now}).then((v2)=>{if(openKeys(props.dialog),v2===null)return;let parsed=parse2(v2);write(id,parsed.length===0?"none":v2)})},importOc=()=>{let r=loadOcKeybinds();if(r.sources.length===0)return toast.show({variant:"info",message:"No opencode tui.json found"});let n=Object.keys(r.overrides).length;openConfirm(props.dialog,{title:`Import ${n} keybind${n===1?"":"s"} from opencode?`,body:`${r.sources.map((s)=>`\xB7 ${s}`).join(`
4160
4160
  `)}
4161
4161
 
4162
4162
  ${n} mapped \xB7 ${r.skipped.length} skipped (no herm equivalent)${r.skipped.length?`:
4163
4163
  ${r.skipped.slice(0,8).join(", ")}${r.skipped.length>8?", \u2026":""}`:""}`,yes:"import"}).then((ok)=>{if(openKeys(props.dialog),!ok)return;exports_preferences.set("keys",{...exports_preferences.get("keys")??{},...r.overrides}),toast.show({variant:"success",message:`Imported ${n} \xB7 skipped ${r.skipped.length}`})})};return useKeyboard((key4)=>{if(key4.name==="up")return setSel((s)=>Math.max(0,s-1));if(key4.name==="down")return setSel((s)=>Math.min(actionRows.length-1,s+1));if(key4.name==="return"&&cur)return rebind(cur.id);if(key4.name==="r"&&!key4.ctrl&&cur?.override){write(cur.id,void 0);return}if(key4.name==="o"&&!key4.ctrl)return importOc()}),$jsxs("box",{flexDirection:"column",width:78,children:[$jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{flexGrow:1,children:$jsx("text",{fg:theme.text,children:$jsx("strong",{children:"Keybindings"})})}),$jsx("text",{fg:theme.textMuted,children:`leader = ${keys.print("leader")}`})]}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,maxHeight:22,verticalScrollbarOptions:VBAR,children:$jsx("box",{flexDirection:"column",width:"100%",children:rows3.map((r,i)=>{if(r.type==="header")return $jsx("box",{height:1,marginTop:i>0?1:0,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:r.title})})},`h-${r.title}`);let ai=actionRows.findIndex((x2)=>x2.i===i),on=ai===sel,conf=conflictsWith(keys.table,r.id);return $jsxs("box",{height:1,flexDirection:"row",backgroundColor:on?theme.backgroundElement:void 0,onMouseOver:()=>setSel(ai),onMouseDown:()=>{setSel(ai),rebind(r.id)},children:[$jsx("box",{width:2,flexShrink:0,children:$jsx("text",{fg:on?theme.primary:theme.text,children:on?"\u25B8 ":" "})}),$jsx("box",{width:16,flexShrink:0,height:1,overflow:"hidden",children:$jsx("text",{fg:on?theme.accent:theme.text,children:print(r.chord,keys.print("leader"))||"\u2014"})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:theme.textMuted,children:r.desc})}),$jsx("box",{width:5,flexShrink:0,flexDirection:"row",justifyContent:"flex-end",children:$jsxs("text",{children:[r.override?$jsx("span",{fg:theme.info,children:"\xB7 "}):null,conf.length>0?$jsx("span",{fg:theme.warning,children:"\u26A0"}):null]})})]},r.id)})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:curConflicts.length>0?$jsx("text",{fg:theme.warning,children:`\u26A0 shares ${keys.print(cur.id)} with: ${curConflicts.join(", ")}`}):$jsx("text",{fg:theme.textMuted,children:`\u2191\u2193 select Enter rebind${cur?.override?" \xB7 r reset":""} \xB7 o import opencode \xB7 esc close \xB7 \xB7 = overridden`})})]})};function openKeys(dialog){dialog.replace($jsx(KeysDialog,{dialog}))}var ERRLIKE=/error|fail|traceback|exception|\b[45]\d\d\b|refused|denied|unauthori/i,LogsDialog=()=>{let theme=useTheme().theme,lines3=useGateway().tail(200).split(`
4164
4164
  `).filter(Boolean);return $jsxs("box",{flexDirection:"column",width:110,height:Math.min(34,Math.max(8,lines3.length+5)),children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Gateway Logs"})})}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.textMuted,children:[lines3.length," lines \xB7 stderr + protocol \xB7 Esc to close"]})}),$jsx("box",{height:1}),lines3.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No log output captured."})}):$jsx("scrollbox",{scrollY:!0,stickyScroll:!0,stickyStart:"bottom",flexGrow:1,children:$jsx("box",{flexDirection:"column",children:lines3.map((l,i)=>$jsx("box",{height:1,children:$jsx("text",{fg:ERRLIKE.test(l)?theme.error:theme.textMuted,children:l.length>106?l.slice(0,105)+"\u2026":l})},i))})})]})},openLogs=(dialog)=>dialog.replace($jsx(LogsDialog,{}));var import_react130=__toESM(require_react_production(),1);var ThemePickerDialog=({onConfirm})=>{let ctx=useTheme(),dialog=useDialog(),options=ctx.names.map((n)=>({title:n,value:n})),onMove=import_react130.useCallback((opt)=>{ctx.set(opt.value)},[ctx]),onSelect=import_react130.useCallback((opt)=>{ctx.set(opt.value),onConfirm(),dialog.clear()},[ctx,dialog,onConfirm]),flip=import_react130.useCallback(()=>{ctx.setMode(ctx.mode==="dark"?"light":"dark")},[ctx]),onKey=import_react130.useCallback((key4)=>{if(key4.name!=="tab")return!1;return flip(),!0},[flip]),footer=$jsx("box",{height:1,onMouseDown:flip,children:$jsxs("text",{fg:ctx.theme.textMuted,children:[$jsx("span",{children:"Mode: "}),$jsx("span",{fg:ctx.mode==="light"?ctx.theme.warning:ctx.theme.accent,children:ctx.mode}),$jsx("span",{children:" \xB7 Tab/click: toggle"})]})});return $jsx(DialogSelect,{title:"Switch Theme",options,current:ctx.name,onSelect,onMove,onKey,placeholder:"Search themes...",footer})},openThemePicker=(dialog,ctx)=>{let{name:saved,mode:mode2}=ctx,confirmed=!1;dialog.replace($jsx(ThemePickerDialog,{onConfirm:()=>{confirmed=!0}}),()=>{if(confirmed)return;ctx.set(saved),ctx.setMode(mode2)})};var import_react131=__toESM(require_react_production(),1);import{homedir as homedir9}from"os";import{join as join25}from"path";var trunc6=(s,n)=>s.length<=n?s:s.slice(0,n-1)+"\u2026",defaultDirs=()=>{let hermesHome2=process.env.HERMES_HOME||join25(homedir9(),".hermes");return[BUNDLED_EIKON_DIR,join25(hermesHome2,"eikons")]},EikonPickerDialog=(props)=>{let theme=useTheme().theme,dialog=useDialog(),dirs2=props.dirs??defaultDirs(),found2=import_react131.useMemo(()=>listEikons(dirs2),[dirs2]),[cursor,setCursor]=import_react131.useState(0),cur=found2[cursor],parsed=import_react131.useMemo(()=>{if(!cur)return;try{return parseEikonFile(cur.path)}catch{return}},[cur]);useListKeys({active:!0,count:found2.length,setSel:setCursor,onActivate:()=>{if(cur)props.onSelect(cur.meta.name.toLowerCase()),dialog.clear()}});let w2=(parsed?.meta.width??48)+2,h2=Math.max(parsed?.meta.height??24,12);return $jsxs("box",{flexDirection:"column",width:40+w2,height:h2+4,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Pick Avatar"})})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${found2.length} found \xB7 \u2191\u2193 nav \xB7 Enter select \xB7 Esc close`})}),$jsx("box",{height:1}),$jsxs("box",{flexDirection:"row",flexGrow:1,children:[$jsx("box",{width:38,marginRight:2,children:$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:found2.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No .eikon files found."})},"empty"):found2.map((e,i)=>{let on=i===cursor;return $jsxs("box",{flexDirection:"column",paddingLeft:1,paddingRight:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseDown:()=>setCursor(i),children:[$jsx("box",{height:1,children:$jsx("text",{fg:on?theme.text:theme.textMuted,children:$jsx("strong",{children:trunc6(e.meta.name,34)})})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${e.meta.author??"\u2014"} \xB7 ${e.meta.states.length} states`})})]},e.path)})})})}),$jsx("box",{flexGrow:1,flexDirection:"column",overflow:"hidden",children:parsed?$jsx(AnimatedAvatar,{state:"idle",eikon:parsed},cur?.path??"none"):$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No preview."})},"blank")})]})]})},openEikonPicker=(dialog,onSelect)=>dialog.replace($jsx(EikonPickerDialog,{onSelect}));var import_react132=__toESM(require_react_production(),1);var RollbackDialog=(props)=>{let theme=useTheme().theme,[data2,setData]=import_react132.useState(props.initial??null),[sel,setSel]=import_react132.useState(props.sel??0),[diff,setDiff]=import_react132.useState(null),[opened,setOpened]=import_react132.useState(null),[confirm,setConfirm]=import_react132.useState(!1),seq=import_react132.useRef(0),restoring=import_react132.useRef(!1);import_react132.useEffect(()=>{if(props.initial)return;props.gw.request("rollback.list").then(setData).catch((e)=>setData({enabled:!1,checkpoints:[],err:e.message}))},[props.gw,props.initial]),import_react132.useEffect(()=>()=>{seq.current++},[]);let points=data2?.checkpoints??[],cur=points[sel],target2=opened??cur,open3=(cp)=>{let id=++seq.current;props.gw.request("rollback.diff",{hash:cp.hash}).then((next2)=>{if(seq.current!==id)return;setOpened(cp),setDiff(next2)}).catch((e)=>{if(seq.current===id)props.toast.error(e)})},back=()=>{seq.current++,setDiff(null),setOpened(null),setConfirm(!1),props.dialog.replace($jsx(RollbackDialog,{gw:props.gw,toast:props.toast,dialog:props.dialog,initial:data2??void 0,sel}))},restore=(cp)=>{if(restoring.current)return;restoring.current=!0,props.gw.request("rollback.restore",{hash:cp.hash}).then((r)=>{if(!r.success)throw Error("restore rejected");let n=r.history_removed;props.toast.show({variant:"success",message:`Restored ${cp.hash.slice(0,7)}${n?` \xB7 ${n} turns removed`:""}`}),props.dialog.clear()}).catch((e)=>{props.toast.show({variant:"error",message:`Restore failed: ${e.message}`}),props.dialog.clear()}).finally(()=>{restoring.current=!1})},keys=useKeys();if(useKeyboard((key4)=>{if(diff){if(confirm){if(target2&&keys.match("dialog.confirm",key4))return restore(target2);if(keys.match("dialog.deny",key4)||keys.match("dialog.cancel",key4))return setConfirm(!1),back();return}if(keys.match("dialog.cancel",key4))return back();if(key4.name==="r")return setConfirm(!0);return}if(!data2?.enabled)return;handleListKey(keys,key4,{count:points.length,setSel,onActivate:()=>{if(cur)open3(cur)}})}),!data2)return $jsx("box",{width:60,height:3,children:$jsx("text",{fg:theme.textMuted,children:"Loading checkpoints\u2026"})});if(!data2.enabled)return $jsxs("box",{flexDirection:"column",width:60,height:5,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:data2.err?"Rollback unavailable":"Checkpoints disabled"})})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:data2.err??"Enable checkpoints in config to use /rollback."})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Esc to close"})})]});if(diff){let body=diff.rendered||diff.diff||diff.stat||"(empty diff)";return $jsxs("box",{flexDirection:"column",width:110,height:30,children:[$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.primary,children:$jsx("strong",{children:"Rollback \xB7 "})}),$jsx("span",{fg:theme.accent,children:target2?.hash.slice(0,7)??""}),$jsx("span",{fg:theme.textMuted,children:` ${trunc5(target2?.message??"",70)}`})]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:diff.stat||" "})}),$jsx("box",{height:1}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:$jsx(DiffBlock,{text:body})})}),$jsx("box",{height:1}),confirm?$jsx("box",{height:1,children:$jsxs("text",{children:[$jsx("span",{fg:theme.warning,children:$jsx("strong",{children:"Restore this checkpoint? "})}),$jsx("span",{fg:theme.textMuted,children:"[y] restore [n] cancel"})]})}):$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"[r] restore \xB7 Esc back"})})]})}return $jsxs("box",{flexDirection:"column",width:90,height:Math.min(28,Math.max(8,points.length+6)),children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Rollback"})})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:`${points.length} checkpoints \xB7 \u2191\u2193 navigate Enter diff Esc close`})}),$jsx("box",{height:1}),points.length===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"No checkpoints yet."})}):$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",width:"100%",children:points.map((cp,i)=>{let on=i===sel;return $jsx("box",{height:1,backgroundColor:on?theme.backgroundElement:void 0,onMouseDown:()=>{setSel(i),open3(cp)},onMouseOver:()=>setSel(i),children:$jsxs("text",{children:[$jsx("span",{fg:on?theme.primary:theme.textMuted,children:on?"\u25B8 ":" "}),$jsx("span",{fg:theme.accent,children:cp.hash.slice(0,7).padEnd(9)}),$jsx("span",{fg:theme.textMuted,children:ago(cp.timestamp).padEnd(12)}),$jsx("span",{fg:on?theme.text:theme.textMuted,children:trunc5(cp.message,56)})]})},cp.hash)})})})]})},openRollback=(dialog,gw,toast)=>dialog.replace($jsx(RollbackDialog,{gw,toast,dialog}));var import_react134=__toESM(require_react_production(),1);var tag=(m2,theme)=>m2.role==="user"?{label:"\u25B8 You",fg:theme.info}:m2.role==="assistant"?{label:"\u25C2 Agent",fg:theme.success}:m2.role==="tool"?{label:`\u2699 ${m2.name??"tool"}`,fg:theme.warning}:{label:"\xB7 system",fg:theme.textMuted},flatten2=(t2)=>{if(typeof t2==="string")return t2;if(!Array.isArray(t2))return"";for(let p of t2)if(p&&typeof p==="object"&&"type"in p&&p.type==="text"&&"text"in p&&typeof p.text==="string")return p.text;return""},body=(m2)=>m2.role==="tool"?m2.context??"":flatten2(m2.text),HistoryDialog=(props)=>{let theme=useTheme().theme,[rows3,setRows]=import_react134.useState(null),[err,setErr]=import_react134.useState("");import_react134.useEffect(()=>{props.gw.request("session.history").then((r)=>setRows(r.messages??[])).catch((e)=>{setErr(e.message),setRows([])})},[props.gw]);let n=rows3?.length??0,h2=Math.min(34,Math.max(8,n+5));return $jsxs("box",{flexDirection:"column",width:110,height:h2,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:"Session History"})})}),$jsx("box",{height:1,children:$jsx("text",{fg:err?theme.error:theme.textMuted,children:err?`\u26A0 ${err}`:`${n} messages \xB7 server-authoritative \xB7 Esc to close`})}),$jsx("box",{height:1}),rows3===null?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"loading\u2026"})}):n===0?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"Empty \u2014 no turns yet."})}):$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("box",{flexDirection:"column",children:rows3.map((m2,i)=>{let t2=tag(m2,theme);return $jsxs("box",{height:1,flexDirection:"row",children:[$jsx("box",{width:14,flexShrink:0,children:$jsx("text",{fg:t2.fg,children:trunc5(t2.label,13)})}),$jsx("box",{flexGrow:1,minWidth:0,height:1,overflow:"hidden",children:$jsx("text",{fg:m2.role==="tool"||m2.role==="system"?theme.textMuted:theme.text,children:body(m2).replace(/\n/g," ")})})]},i)})})})]})},openHistory=(dialog,gw)=>dialog.replace($jsx(HistoryDialog,{gw}));var import_react135=__toESM(require_react_production(),1);var InfoDialog=(props)=>{let theme=useTheme().theme,body2=props.rows.filter((r)=>r[1]!==void 0);return $jsxs("box",{flexDirection:"column",minWidth:52,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsx("strong",{children:props.title})})}),props.warning?$jsx("text",{wrapMode:"word",fg:theme.warning,children:props.warning}):null,props.lines?.length?$jsx("box",{flexDirection:"column",children:props.lines.map((line4,i)=>$jsx("box",{height:1,children:$jsx("text",{fg:theme.text,children:line4})},i))}):null,$jsx("box",{flexDirection:"column",children:$jsx(KVBlock,{rows:body2})}),props.note?$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:props.note})}):null,$jsx("box",{height:1,children:$jsx("text",{fg:theme.borderSubtle,children:"Esc to close"})})]})};function openStatus(dialog,info3,sid2){let toolsets=Object.keys(info3?.tools??{}),nTools=Object.values(info3?.tools??{}).reduce((n,v2)=>n+v2.length,0),mcp=info3?.mcp_servers??[],up=mcp.filter((s)=>s.connected).length;dialog.replace($jsx(InfoDialog,{title:"Status",rows:[["Version",info3?.version||"\u2014"],["Model",info3?.model||"\u2014"],["Profile",activeProfileName()],["Home",hermesPath("")],["CWD",info3?.cwd||process.cwd()],["Session",sid2||"\u2014"],["Tools",`${nTools} in ${toolsets.length} toolset${toolsets.length===1?"":"s"}`],["Skills",String(Object.values(info3?.skills??{}).reduce((n,v2)=>n+v2.length,0))],["MCP",mcp.length?`${up}/${mcp.length} connected`:void 0]],warning:info3?.install_warning}))}var UsageDialog=({gw})=>{let theme=useTheme().theme,[u3,setU]=import_react135.useState(null),[err,setErr]=import_react135.useState("");if(import_react135.useEffect(()=>{gw.request("session.usage").then(setU).catch((e)=>setErr(e instanceof Error?e.message:String(e)))},[gw]),err)return $jsx(InfoDialog,{title:"Usage",rows:[["Error",err,theme.error]]});if(!u3)return $jsx(InfoDialog,{title:"Usage",rows:[["","\u2026"]]});let ctx=u3.context_max?`${fmt(u3.context_used??0)} / ${fmt(u3.context_max)} (${Math.round(u3.context_percent??0)}%)`:void 0;return $jsx(InfoDialog,{title:"Usage",lines:u3.credits_lines,note:u3.cost_status==="estimated"?"cost is estimated":void 0,rows:[["Model",u3.model||"\u2014"],["API calls",String(u3.calls??0)],["Input",fmt(u3.input??0)],["Output",fmt(u3.output??0)],["Cache r/w",u3.cache_read||u3.cache_write?`${fmt(u3.cache_read??0)} / ${fmt(u3.cache_write??0)}`:void 0],["Reasoning",u3.reasoning?fmt(u3.reasoning):void 0],["Total",fmt(u3.total??0)],["Context",ctx],["Cost",u3.cost_usd!=null?cost2(u3.cost_usd):void 0,theme.accent]]})},openUsage=(dialog,gw)=>dialog.replace($jsx(UsageDialog,{gw})),ProfileDialog=()=>{let[p,setP]=import_react135.useState(void 0),active=activeProfileName();if(import_react135.useEffect(()=>{listProfiles().then((ps)=>setP(ps.find((x2)=>x2.name===active)??null)).catch(()=>setP(null))},[]),p===void 0)return $jsx(InfoDialog,{title:"Profile",rows:[["","\u2026"]]});return $jsx(InfoDialog,{title:"Profile",note:p?void 0:"profile directory not found",rows:[["Active",active],["Home",p?.path??hermesPath("")],["Model",p?.model??"\u2014"],["Provider",p?.provider??"\u2014"],["Skills",p?String(p.skill_count):void 0],["Gateway",p?.gateway_running?"running":"stopped"],["Sticky",p?.is_sticky?"yes":void 0],["Alias",p?.is_default?void 0:p?.has_alias?`~/.local/bin/${active}`:"\u2014"],[".env",p?.has_env?"present":"\u2014"]]})},openProfile=(dialog)=>dialog.replace($jsx(ProfileDialog,{}));var import_react136=__toESM(require_react_production(),1);import{spawnSync as spawnSync2}from"child_process";import{existsSync as existsSync30}from"fs";var CHAFA=["/usr/sbin/chafa","/usr/bin/chafa","/usr/local/bin/chafa","/opt/homebrew/bin/chafa"];function whichChafa(){for(let p of CHAFA)if(existsSync30(p))return p;return null}function render(path4,w2,h2){let bin=whichChafa();if(!bin)return{err:"chafa not installed (brew/apt install chafa)"};let full=path4.startsWith("~")?path4.replace(/^~/,process.env.HOME??""):path4;if(!existsSync30(full))return{err:`file not found: ${full}`};let r=spawnSync2(bin,[`--size=${w2}x${h2}`,"--format=symbols","--symbols=block","--colors=full",full],{encoding:"utf8"});if(r.status!==0)return{err:r.stderr||`chafa exit ${r.status}`};return{rows:parseChafa(r.stdout)}}var ChafaDialog=({path:path4})=>{let theme=useTheme().theme,[w2]=import_react136.useState(80),[h2]=import_react136.useState(28),result=import_react136.useMemo(()=>render(path4,w2,h2),[path4,w2,h2]);return $jsxs("box",{flexDirection:"column",minWidth:w2+4,gap:1,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.primary,children:$jsxs("strong",{children:["chafa demo \xB7 ",path4]})})}),result.err?$jsx("box",{height:1,children:$jsx("text",{fg:theme.error,children:result.err})}):$jsx("box",{flexDirection:"column",children:result.rows.map((row4,i)=>$jsx("text",{children:row4.map((c,j2)=>$jsx("span",{fg:hex(c.fg),bg:hex(c.bg),children:c.ch},j2))},i))}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.borderSubtle,children:[result.rows?`${result.rows.length} rows \xB7 ${result.rows.reduce((a,r)=>a+r.length,0)} cells \xB7 `:"","Esc to close"]})})]})};function openChafa(dialog,path4){dialog.replace($jsx(ChafaDialog,{path:path4}))}var import_react138=__toESM(require_react_production(),1);var exports_selection={};__export(exports_selection,{key:()=>key4,Selection:()=>exports_selection});function yank(renderer,toast){let text5=renderer.getSelection()?.getSelectedText();if(!text5)return!1;return copyText(text5,toast).catch(()=>toast?.show({variant:"error",message:"Clipboard write failed"})),renderer.clearSelection(),!0}function key4(renderer,evt,toast){let sel=renderer.getSelection();if(!sel?.getSelectedText())return!1;if(evt.ctrl&&evt.name==="c")return yank(renderer,toast),!0;if(evt.name==="escape")return renderer.clearSelection(),!0;let focus=renderer.currentFocusedRenderable;if(focus&&sel.selectedRenderables.includes(focus))return!1;return renderer.clearSelection(),!1}var SGR_MOUSE_BLOB_RE=/^(?:\x1b\[|\^\[\[)?<?\d+(?:;\d+){1,2}[Mm]$/,SGR_MOUSE_RESIDUE_RE=/^\d+(?:;\d+){1,2}[Mm]$/;function isDegradedMouseInput(key5){return[key5.raw,key5.sequence,key5.name].some((v2)=>typeof v2==="string"&&isDegradedMouseBlob(v2))}function isDegradedMouseBlob(text5){if(!text5||/\s/.test(text5))return!1;return SGR_MOUSE_BLOB_RE.test(text5)||SGR_MOUSE_RESIDUE_RE.test(text5)}var DEFAULT_VOICE_KEY={mod:"ctrl",ch:"b",raw:"ctrl+b"},MOD_ALIASES={alt:"alt",ctrl:"ctrl",control:"ctrl",option:"alt",opt:"alt"};function parseVoiceRecordKey(raw2){if(typeof raw2!=="string"||!raw2.trim())return DEFAULT_VOICE_KEY;let lower=raw2.trim().toLowerCase(),parts2=lower.split("+").map((p)=>p.trim()).filter(Boolean);if(parts2.length<2)return DEFAULT_VOICE_KEY;if(parts2.length>2)return DEFAULT_VOICE_KEY;let[modRaw,chRaw]=parts2,mod=MOD_ALIASES[modRaw];if(!mod)return DEFAULT_VOICE_KEY;if(chRaw.length!==1)return DEFAULT_VOICE_KEY;if(mod==="ctrl"&&(chRaw==="c"||chRaw==="d"||chRaw==="l"))return DEFAULT_VOICE_KEY;return{mod,ch:chRaw,raw:lower}}function formatVoiceRecordKey(v2){return`${v2.mod[0].toUpperCase()+v2.mod.slice(1)}+${v2.ch.toUpperCase()}`}function isVoiceToggleKey(key5,configured2=DEFAULT_VOICE_KEY){if(key5.name.toLowerCase()!==configured2.ch)return!1;if(key5.shift)return!1;switch(configured2.mod){case"ctrl":return key5.ctrl&&!key5.meta&&!key5.super;case"alt":return key5.meta&&!key5.ctrl&&!key5.super}}function redraw(renderer){resolveRenderLib().clearTerminal(renderer.rendererPtr),renderer.currentRenderBuffer.clear(RGBA.fromValues(0,0,0,0)),renderer.requestRender()}var INTERRUPT_MS=5000,DOUBLE_TAB_MS=400,QUIT_MS=2000;function useAppKeys(o){let renderer=useRenderer(),keys=useKeys(),lastEsc=import_react138.useRef(0),lastTab=import_react138.useRef(0),lastQuit=import_react138.useRef(0),regionFor=(t2)=>t2===o.chatTab?"input":"content";import_react138.useEffect(()=>{let found2=conflicts(keys.table).filter((c)=>!(c.a==="session.interrupt"&&c.b==="dialog.cancel")).filter((c)=>!(c.a==="app.exit"&&c.b==="input.clear"));if(found2.length===0)return;let first=found2[0];o.onNotice(`Keybinding conflict: ${print([first.chord])} \u2192 ${first.a} and ${first.b}`+(found2.length>1?` (+${found2.length-1} more)`:""))},[keys.table]),useKeyboard((key5)=>{let c=o.composer.current;if(isDegradedMouseInput(key5)){key5.stopPropagation();return}if(exports_selection.key(renderer,key5,{show:o.onCopyToast,clear:()=>{},error:()=>{}})){key5.stopPropagation();return}if(keys.match("input.clear",key5)&&c&&!c.isEmpty()){let v2=c.value().trim();if(v2.length>=20)c.remember(v2);c.set(""),lastQuit.current=0,key5.stopPropagation();return}if(keys.match("input.stash",key5)){o.onStash(),key5.stopPropagation();return}if(keys.match("app.exit",key5)){let now=Date.now();if(now-lastQuit.current<QUIT_MS)return o.onQuit();lastQuit.current=now,o.onQuitArm(keys.print("app.exit")),key5.stopPropagation();return}if(keys.match("app.suspend",key5)){renderer.suspend(),process.kill(process.pid,"SIGTSTP"),process.once("SIGCONT",()=>renderer.resume());return}if(keys.match("app.redraw",key5)){redraw(renderer),key5.stopPropagation();return}if(keys.match("app.sidebar",key5)){o.onToggleSidebar();return}if(o.dialogOpen())return;if(o.voiceRecordKey&&o.onVoiceRecord&&isVoiceToggleKey(key5,o.voiceRecordKey)){o.onVoiceRecord(),key5.stopPropagation();return}if(c?.mode()==="shell"){if(key5.name==="escape"){c.setMode("normal"),key5.stopPropagation();return}if(key5.name==="backspace"&&!key5.ctrl&&!key5.meta&&c.caret()===0){c.setMode("normal"),key5.stopPropagation();return}}if(keys.match("session.steer",key5)){o.onSteer(),key5.stopPropagation();return}if(keys.match("queue.flush",key5)&&(o.streaming||o.starting)&&o.queued>0){o.onFlushQueue(),key5.stopPropagation();return}if(o.onPromptKey&&!keys.leader&&!key5.ctrl&&!key5.meta&&key5.eventType!=="release"){if(o.onPromptKey(key5)){key5.stopPropagation();return}}if(keys.match("editor.open",key5)&&!o.streaming){let seed=c?.value()??"";editInEditor(renderer,seed).then((out)=>{if(out===void 0){if(!process.env.VISUAL&&!process.env.EDITOR)o.onNotice("Set $EDITOR or $VISUAL to use the external editor");return}c?.set(out),o.setFocusRegion("input")}).catch((e)=>o.onNotice(e.message));return}if(keys.match("tab.prev",key5)){o.setTab((t2)=>{let n=Math.max(0,t2-1);return o.setFocusRegion(regionFor(n)),n});return}if(keys.match("tab.next",key5)){o.setTab((t2)=>{let n=Math.min(o.tabMax,t2+1);return o.setFocusRegion(regionFor(n)),n});return}if(o.subCount>0&&key5.shift&&!key5.ctrl&&!key5.meta&&key5.eventType!=="release"){if(key5.name==="left"){o.cycleSub(-1),key5.stopPropagation();return}if(key5.name==="right"){o.cycleSub(1),key5.stopPropagation();return}}if(keys.leader&&!key5.ctrl&&!key5.meta&&!key5.shift&&key5.eventType!=="release"){let n={"1":0,"2":1,"3":2,"4":3,"5":4,"6":5,"7":6,"8":7,"9":8,"0":9,"-":10}[key5.name];if(n!==void 0&&n<=o.tabMax){o.setTab(()=>{return o.setFocusRegion(regionFor(n)),n}),key5.stopPropagation();return}}if(key5.meta&&!key5.ctrl&&!key5.shift&&key5.eventType!=="release"){let n={"1":0,"2":1,"3":2,"4":3,"5":4,"6":5,"7":6,"8":7,"9":8,"0":9,"-":10}[key5.name];if(n!==void 0&&n<=o.tabMax){o.setTab(()=>{return o.setFocusRegion(regionFor(n)),n}),key5.stopPropagation();return}}if(c?.popOpen()){if(key5.name==="escape"){c.popCancel(),key5.stopPropagation();return}if(key5.name==="up"){c.popNav(-1),key5.stopPropagation();return}if(key5.name==="down"){c.popNav(1),key5.stopPropagation();return}if(key5.name==="tab"||key5.name==="return"){c.popAccept(),key5.stopPropagation();return}return}if(keys.match("focus.cycle",key5)&&!o.streaming){if(o.tab===o.chatTab){o.setFocusRegion((r)=>r==="input"?"content":"input");return}if(o.focusRegion==="input"){o.setFocusRegion("content");return}let now=Date.now();if(now-lastTab.current<DOUBLE_TAB_MS)o.setFocusRegion("input"),lastTab.current=0,key5.stopPropagation();else lastTab.current=now;return}if(keys.match("session.interrupt",key5)){if(!o.streaming&&!o.starting&&o.onEscape?.())return;if(o.streaming||o.starting){let now=Date.now();if(now-lastEsc.current<INTERRUPT_MS){o.onInterrupt(),lastEsc.current=0;return}lastEsc.current=now,o.onInterruptNotice();return}if(o.tab===o.chatTab&&o.focusRegion==="content")o.setFocusRegion("input");return}if(keys.match("reply.copy",key5))return o.onCopyLast();if(keys.match("clipboard.attach",key5)){o.onAttachClipboard(),key5.stopPropagation();return}if(o.focusRegion==="input"&&!o.streaming){if((key5.name==="!"||key5.name==="1"&&key5.shift)&&!key5.ctrl&&!key5.meta&&key5.eventType!=="release"&&c&&c.mode()==="normal"&&!c.popOpen()&&c.caret()===0){c.setMode("shell"),key5.stopPropagation();return}if(key5.name==="up"){let before=c?.value();return void(c?.historyUp()&&c?.value()!==before&&key5.stopPropagation())}if(key5.name==="down"){let before=c?.value();return void(c?.historyDown()&&c?.value()!==before&&key5.stopPropagation())}if(key5.name==="backspace"&&!key5.ctrl&&!key5.meta&&c&&(c.isEmpty()||c.caret()===0||c.value()[c.caret()-1]===`
4165
- `)&&o.onDetachLast()){key5.stopPropagation();return}}if(o.tab===o.chatTab&&o.focusRegion==="content"&&!o.streaming&&!key5.ctrl&&!key5.meta&&key5.eventType!=="release"){if(key5.name.length===1&&key5.name!==" "){let ch=key5.shift&&/[a-z]/.test(key5.name)?key5.name.toUpperCase():key5.name;o.setFocusRegion("input"),c?.insert(ch),key5.stopPropagation()}}})}import{writeSync}from"fs";var done=!1;function quit(renderer,sid2,title,gw){if(done)process.exit(0);done=!0;try{gw?.kill()}catch{}if(renderer.destroy(),process.stdout.isTTY){let banner=sid2?`
4165
+ `)&&o.onDetachLast()){key5.stopPropagation();return}}if(o.tab===o.chatTab&&o.focusRegion==="content"&&!o.streaming&&!key5.ctrl&&!key5.meta&&key5.eventType!=="release"){if(key5.name.length===1&&key5.name!==" "){let ch=key5.shift&&/[a-z]/.test(key5.name)?key5.name.toUpperCase():key5.name;o.setFocusRegion("input"),c?.insert(ch),key5.stopPropagation()}}})}import{writeSync}from"fs";var done=!1;function quit(renderer,sid2,title,gw){if(done)process.exit(0);done=!0;try{gw?.kill()}catch{}try{renderer.setTerminalTitle("")}catch{}if(renderer.destroy(),process.stdout.isTTY){let banner=sid2?`
4166
4166
  continue herm --resume ${sid2}${title?` \u2014 ${title.slice(0,60)}`:""}
4167
4167
 
4168
4168
  `:`
@@ -4181,13 +4181,13 @@ ${r.skipped.slice(0,8).join(", ")}${r.skipped.length>8?", \u2026":""}`:""}`,yes:
4181
4181
  ${list3.join(" ")}`});return}if(!list3.includes(name)){toast.show({variant:"error",message:`unknown skin: ${name}`});return}gw.request("config.set",{key:"skin",value:name}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});if(themeCtx.has(name)){themeCtx.set(name);let m2=mode(name);if(m2)themeCtx.setMode(m2)}set("eikon",void 0),set("eikonPath",void 0),x2.dispatch({kind:"system",text:`skin \u2192 ${name}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return}case"resume":if(arg){x2.switchSession(arg);return}x2.goTo(TAB_SLASH.sessions.tab,TAB_SLASH.sessions.sub);return;case"branch":branch2(arg);return;case"compress":runCompress(arg);return;case"undo":destructive(arg,{title:"Undo last turn?",body:"Pops the last user + assistant pair from the transcript. /redo in this session to restore.",yes:"undo"},()=>{let msgs=x2.turnRef.current.messages,at=msgs.map((m2)=>m2.role).lastIndexOf("user"),tail=at>=0?msgs.slice(at):[];x2.session.undo().then(()=>{if(tail.length)x2.undone.current.push(tail);return gw.request("session.history")}).then((r)=>x2.dispatch({kind:"load",messages:transcriptToMessages(r.messages??[])})).catch((err)=>toast.show({variant:"error",message:err.message}))});return;case"redo":{let head=x2.undone.current.pop()?.find((m2)=>m2.role==="user");if(!head){toast.show({variant:"info",message:"nothing to redo"});return}x2.sendRef.current(text2(head));return}case"retry":{let last4=[...x2.turnRef.current.messages].reverse().find((m2)=>m2.role==="user");if(!last4){toast.show({variant:"info",message:"nothing to retry"});return}x2.rewind(last4).then((ok)=>{if(ok)x2.sendRef.current(text2(last4))});return}case"model":if(!arg){openModelPicker(dialog,gw);return}if(arg.trim()==="--refresh"){openModelPicker(dialog,gw,{refresh:!0});return}gw.request("config.set",{key:"model",value:arg}).then((r)=>{if(r.warning)toast.show({variant:"warning",message:r.warning});x2.dispatch({kind:"system",text:`model \u2192 ${r.value??arg}`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"yolo":gw.request("config.set",{key:"yolo"}).then((r)=>{if(r.info)x2.setInfo(r.info),x2.setUsage(r.info.usage);else x2.setInfo({...x2.info??{},yolo:!x2.info?.yolo});if(toast.show({variant:"success",message:`yolo ${r.value??"toggled"}`}),r.warning)toast.show({variant:"warning",message:r.warning})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"quit":quit(renderer,x2.sid,x2.title,gw);return;case"queue":if(!arg){x2.dispatch({kind:"system",text:`${x2.queueRef.current.length} queued`});return}x2.setQueue((q5)=>[...q5,arg]);return;case"stash":{let comp=x2.composer.current;if(arg==="pop"){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});comp?.set(e.text),x2.setFocusRegion("input");return}if(arg==="list"){let list3=exports_stash.all();if(list3.length===0)return toast.show({variant:"info",message:"stash empty"});dialog.replace($jsx(DialogSelect,{title:"Stashed prompts",filterable:list3.length>6,options:list3.map((e)=>({title:trunc5(e.text.replace(/\n/g," \u23CE "),50),value:String(e.at),hint:ago(e.at)})),onSelect:(o)=>{let e=list3.find((s)=>String(s.at)===o.value);if(e)exports_stash.drop(e.at),comp?.set(e.text),x2.setFocusRegion("input");dialog.clear()}}));return}let text5=arg||comp?.value().trim()||"";if(!text5)return toast.show({variant:"info",message:"nothing to stash \u2014 /stash list"});let n=exports_stash.push(text5);if(!arg)comp?.set("");toast.show({variant:"info",message:`stashed (${n}) \u2014 /stash pop to restore`});return}case"copy":{let all2=x2.turnRef.current.messages.filter((m3)=>m3.role==="assistant"),n=arg?Math.min(Math.max(1,parseInt(arg,10)||0),all2.length):all2.length,m2=all2[n-1];if(!m2){toast.show({variant:"info",message:"nothing to copy"});return}let body2=text2(m2);copyText(body2,toast,`copied ${body2.length} chars`);return}case"paste":x2.attachClipboard();return;case"image":if(!arg){toast.show({variant:"info",message:"usage: /image <path>"});return}gw.request("image.attach",{path:arg}).then((r)=>r.attached?x2.setAttachments((a)=>[...a,r]):toast.show({variant:"warning",message:r.message??"attach failed"})).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"background":if(!arg){x2.dispatch({kind:"system",text:"/background <prompt>"});return}gw.request("prompt.background",x2.sid?{session_id:x2.sid,text:arg}:{text:arg}).then((r)=>{if(!r.task_id){toast.show({variant:"error",message:"background start failed"});return}bg2.register(r.task_id,arg),x2.dispatch({kind:"system",text:`bg ${r.task_id} started`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"voice":x2.voiceToggle((arg||"status").toLowerCase(),x2.sid).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"mouse":{let want=arg==="on"?!0:arg==="off"?!1:!renderer.useMouse;renderer.useMouse=want,set("mouse",want),toast.show({variant:"info",message:`mouse ${want?"on":"off"}`});return}case"redraw":redraw(renderer);return;case"browser":{let parts2=arg.trim().split(/\s+/),sub2=parts2[0]?.toLowerCase()||"connect",url2=parts2[1];if(!["connect","disconnect","status"].includes(sub2)){toast.show({variant:"error",message:"usage: /browser [connect|disconnect|status] [url]"});return}let payload2={action:sub2};if(sub2==="connect"&&url2)payload2.url=url2;gw.request("browser.manage",payload2).then((r)=>{for(let m2 of r.messages??[])x2.dispatch({kind:"system",text:m2});if(r.connected)x2.dispatch({kind:"system",text:`Browser connected${r.url?` \u2192 ${r.url}`:""}`});else if(sub2==="disconnect")x2.dispatch({kind:"system",text:"Browser disconnected"});else if(sub2==="status")x2.dispatch({kind:"system",text:r.url??"No browser connected"})}).catch((e)=>toast.show({variant:"error",message:`browser: ${e.message}`}));return}case"setup":x2.dispatch({kind:"system",text:`/${c2.name} is an Ink-TUI command and has no effect in herm`});return;case"steer":{let fire=(text5)=>gw.request("session.steer",{text:text5}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(arg){fire(arg);return}openTextPrompt(dialog,{title:"Steer",label:"Note to inject on next tool result"}).then((text5)=>{if(text5)fire(text5)});return}case"reload-mcp":{let a=arg.trim().toLowerCase(),skip=a==="now"||a==="once"||a==="approve"||a==="yes"||a==="always",fire=(always)=>gw.request("reload.mcp",{confirm:!0,always}).then((r)=>r.status==="confirm_required"?toast.show({variant:"warning",message:r.message??"reload requires confirmation"}):toast.show({variant:"success",message:always?"MCP servers reloaded \xB7 future /reload-mcp runs silently":"MCP servers reloaded"})).catch((e)=>toast.show({variant:"error",message:e.message}));if(skip){fire(a==="always");return}openConfirm(dialog,{title:"Reload MCP servers?",body:"Rebuilds the MCP tool set. Invalidates the prompt cache, so the next message re-sends full input tokens.",yes:"reload",danger:!0}).then((ok)=>{if(ok)fire(!1)});return}case"reload":gw.request("reload.env",{}).then((r)=>{let n=Number(r.updated??0);toast.show({variant:"success",message:`Reloaded .env (${n} var${n===1?"":"s"} updated) \xB7 /new to apply`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"reload-skills":gw.request("skills.reload",{}).then((r)=>{x2.dispatch({kind:"system",text:r.output});let n=Number(r.result?.total??0);toast.show({variant:"success",message:`Skills reloaded (${n} available)`})}).catch((e)=>toast.show({variant:"error",message:e.message}));return;case"save":gw.request("session.save").then((r)=>toast.show({variant:"success",message:`Saved \u2192 ${r.file}`})).catch((e)=>toast.show({variant:"error",message:e.message}));return}if(c2.target!=="gateway"||!x2.capabilities.canDispatchGatewayCommand)return;let jump=TAB_SLASH[c2.name];if(jump!==void 0&&!arg){x2.goTo(jump.tab,jump.sub);return}let full=`/${c2.name}${arg?" "+arg:""}`;if(x2.turnRef.current.streaming){x2.setQueue((q5)=>[...q5,full]);return}x2.dispatch({kind:"user",text:full}),gw.request("slash.exec",{command:full}).then((res)=>{if(res?.warning)x2.dispatch({kind:"system",text:`\u26A0 ${res.warning}`});if(res?.output)x2.dispatch({kind:"system",text:res.output})}).catch(()=>{gw.request("command.dispatch",{name:c2.name,arg}).then((d2)=>{if(d2.notice)x2.dispatch({kind:"system",text:d2.notice});if(d2.type==="exec"||d2.type==="plugin")return x2.dispatch({kind:"system",text:d2.output||"(no output)"});if(d2.type==="alias"&&d2.target)return void x2.sendRef.current(`/${d2.target}${arg?" "+arg:""}`);if((d2.type==="skill"||d2.type==="send")&&d2.message){if(d2.type==="skill")x2.dispatch({kind:"system",text:`\u26A1 loading skill: ${d2.name??c2.name}`});return void x2.sendRef.current(d2.message)}x2.dispatch({kind:"system",text:`/${c2.name}: unknown`})}).catch((e)=>x2.dispatch({kind:"system",text:`error: ${e.message}`}))})},[gw,dialog,toast,themeCtx,renderer,destructive,applyTitle,runCompress,branch2]);return import_react140.useEffect(()=>cmd.register([{title:"Help",value:"help",action:"help.open",category:"General",onSelect:()=>dialog.replace($jsx(HelpDialog,{}))},{title:"Keybindings",value:"keys",description:"View & rebind shortcuts",category:"General",onSelect:()=>openKeys(dialog)},{title:"Gateway Logs",value:"logs",description:"Show gateway stderr",category:"General",onSelect:()=>openLogs(dialog)},{title:"Switch Theme",value:"theme",action:"theme.pick",category:"General",onSelect:()=>openThemePicker(dialog,themeCtx)},{title:"Switch Model",value:"model",action:"model.pick",category:"General",onSelect:()=>openModelPicker(dialog,gw)},{title:"Pick Avatar",value:"eikon",description:"Choose sidebar .eikon avatar",category:"General",onSelect:()=>pickEikon()},{title:"Rollback",value:"rollback",description:"Browse & restore checkpoints",category:"Session",onSelect:()=>openRollback(dialog,gw,toast)},{title:"History",value:"history",action:"session.timeline",category:"Session",onSelect:()=>openHistory(dialog,gw)},{title:"Status",value:"status",action:"status.open",category:"Info",onSelect:()=>openStatus(dialog,ctx2.current.info,ctx2.current.sid)},{title:"Usage",value:"usage",description:"Tokens \xB7 context \xB7 cost",category:"Info",onSelect:()=>openUsage(dialog,gw)},{title:"Profile",value:"profile",description:"Active profile details",category:"Info",onSelect:()=>openProfile(dialog)},{title:"New Session",value:"new-session",action:"session.new",category:"Session",onSelect:()=>destructive("",{title:"Start a new session?",body:"Ends the current session and starts a fresh one. The existing session remains saved and resumable.",yes:"new session"},()=>{ctx2.current.newSession()})},{title:"Compress Session",value:"compress",action:"session.compress",category:"Session",onSelect:()=>runCompress()},{title:"Undo Last Turn",value:"undo",description:"Pop last user+assistant pair",category:"Session",onSelect:()=>run({name:"undo",target:"local"})},{title:"Redo",value:"redo",action:"session.redo",category:"Session",onSelect:()=>run({name:"redo",target:"local"})},{title:"Branch Session",value:"branch",description:"Fork the current conversation",category:"Session",onSelect:()=>branch2()}]),[cmd,dialog,themeCtx,gw,toast,destructive,pickEikon,runCompress,branch2,run]),run}var import_react142=__toESM(require_react_production(),1);init_perf();function variant(level2){switch(level2){case"error":return"error";case"warning":case"warn":return"warning";case"success":return"success";default:return"info"}}function duration2(p){if(p.kind==="sticky")return null;if(typeof p.ttl_ms==="number")return p.ttl_ms;if(typeof p.duration_ms==="number")return p.duration_ms;return}function showNotification(toast,p){let text5=String(p?.text??"").trim();if(!text5)return;toast.show({key:p?.key,variant:variant(p?.level),message:text5,duration:duration2(p??{text:text5})})}function clearNotification(toast,p){let key5=String(p?.key??"").trim();if(!key5)return;toast.clear(key5)}function count3(o){return o?Object.values(o).reduce((n,v2)=>n+v2.length,0):0}function reference(label3,text5,index4,count4){let head=index4&&count4?`\u25C7 Reference ${index4}/${count4} \u2014 ${label3}`:`\u25C7 Reference \u2014 ${label3}`,body2=text5.trim();return body2?`${head}
4182
4182
  ${body2}`:head}function formatProcessNotification(text5){let body2=text5.replace(/^\[IMPORTANT: /,"").replace(/\]$/,""),done2=body2.match(/^Background process (\S+) completed \(exit code (\S+)\)\.\nCommand: (.+?)(?:\n|$)/);if(done2)return`${done2[1]} exited ${done2[2]} \xB7 ${done2[3]}`;let hit2=body2.match(/^Background process (\S+) matched watch pattern "([^"]+)"\.\nCommand: (.+?)(?:\n|$)/);if(hit2)return`${hit2[1]} matched "${hit2[2]}" \xB7 ${hit2[3]}`;return body2.slice(0,100)}function mapEvent(ev,side){switch(ev.type){case"gateway.ready":if(side.onReady?.(),ev.payload?.skin)side.onSkin?.(ev.payload.skin);return null;case"session.info":{let si=ev.payload;side.onSessionInfo?.(si);let label3=si.model?`Connected \u2014 ${si.model} \xB7 ${count3(si.tools)} tools \xB7 ${count3(si.skills)} skills`:"Connected to Hermes";if(si.credential_warning)side.onStatus?.(si.credential_warning);return{kind:"system",text:label3}}case"session.title":return side.onSessionTitle?.(ev.payload.session_id,ev.payload.title),null;case"message.start":return count("stream:start"),mem("stream-start"),{kind:"message.start"};case"message.delta":{let chunk=ev.payload?.text??"";if(!chunk)return null;return count("stream:chunk"),{kind:"message.delta",chunk}}case"message.complete":{count("stream:done"),mem("stream-done");let p=ev.payload;if(p?.usage)side.onUsage?.(p.usage);if(side.onTurnComplete?.(),p?.status==="error")return{kind:"error",text:p.text||"request failed \u2014 see messages above"};if(p?.status==="interrupted")return{kind:"message.complete",text:(p.text||"")+`
4183
4183
 
4184
- *[interrupted]*`,usage:p?.usage};return{kind:"message.complete",text:p?.text??void 0,usage:p?.usage}}case"tool.start":return{kind:"tool.start",id:ev.payload.tool_id,name:ev.payload.name??"unknown",preview:ev.payload.context,args:ev.payload.args_text};case"tool.progress":return{kind:"tool.progress",name:ev.payload.name,preview:ev.payload.preview};case"tool.generating":return{kind:"tool.generating",name:ev.payload.name};case"tool.complete":return{kind:"tool.complete",id:ev.payload.tool_id,summary:ev.payload.summary,error:ev.payload.error,inline_diff:ev.payload.inline_diff,duration:typeof ev.payload.duration_s==="number"?ev.payload.duration_s*1000:void 0,result:ev.payload.result_text};case"thinking.delta":return side.onStatus?.(ev.payload?.text??""),null;case"reasoning.delta":case"reasoning.available":{let text5=ev.payload?.text;if(!text5)return null;return{kind:"thinking",text:text5,final:ev.type==="reasoning.available",verbose:ev.payload?.verbose}}case"moa.reference":return{kind:"reference",text:reference(ev.payload?.label??"reference",ev.payload?.text??"",ev.payload?.index,ev.payload?.count)};case"moa.aggregating":{let agg=ev.payload?.aggregator;return side.onStatus?.(agg?`aggregating with ${agg}\u2026`:"aggregating\u2026"),null}case"subagent.start":case"subagent.thinking":case"subagent.tool":case"subagent.progress":case"subagent.complete":{let sub2=ev.type.slice(9);return record(sub2,ev.payload),{kind:"subagent",event:sub2,payload:ev.payload}}case"error":return{kind:"error",text:ev.payload?.message??"Unknown error"};case"clarify.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"clarify",...ev.payload}};case"approval.request":{let req={variant:"approval",...ev.payload},fallback={kind:"prompt",id:`approval-${pid()}`,req};if(shouldRemember(req))return side.onApprovalRemembered?.(fallback),null;return fallback}case"sudo.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"sudo",...ev.payload}};case"secret.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"secret",...ev.payload}};case"background.complete":return side.onBackground?.(ev.payload.task_id,ev.payload.text),null;case"review.summary":{let text5=String(ev.payload?.text??"").trim();if(!text5)return null;return{kind:"system",text:text5}}case"btw.complete":return side.onBtw?.(ev.payload.text),null;case"gateway.stderr":{let line4=ev.payload.line;if(/error|fail|traceback|exception|\b[45]\d\d\b|refused|denied|unauthori/i.test(line4))return{kind:"error",text:line4,fatal:!1};return null}case"skin.changed":return side.onSkin?.(ev.payload),null;case"gateway.start_timeout":return{kind:"error",text:`gateway startup timed out (${ev.payload?.python??"python"} @ ${ev.payload?.cwd??"?"})`};case"gateway.protocol_error":return{kind:"system",text:`protocol error: ${ev.payload?.preview??"?"}`};case"browser.progress":{let text5=ev.payload?.message??"";if(!text5)return null;return ev.payload?.level==="error"?{kind:"error",text:text5}:{kind:"system",text:`\xB7 ${text5}`}}case"status.update":{let kind2=ev.payload?.kind,text5=ev.payload?.text??"";if(kind2==="process")return side.onStatus?.(formatProcessNotification(text5)),null;if(side.onStatus?.(text5),!kind2||kind2==="status")return null;return{kind:"system",text:text5}}case"notification.show":if(side.notices)showNotification(side.notices,ev.payload);return null;case"notification.clear":if(side.notices)clearNotification(side.notices,ev.payload);return null;case"voice.status":{let state3=String(ev.payload?.state??"");return side.onVoiceStatus?.(state3),null}case"voice.transcript":{if(ev.payload?.no_speech_limit===!0)return side.onVoiceTranscript?.("",!0),null;let text5=String(ev.payload?.text??"").trim();if(!text5)return null;return side.onVoiceTranscript?.(text5,!1),null}}return null}var STREAM_EVENTS=new Set(["message.start","message.delta","reasoning.delta","reasoning.available","thinking.delta","moa.reference","moa.aggregating","tool.start","tool.progress","tool.generating"]),TITLE_DELAYS=[1200,5000,15000,30000];function useStream(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),bg2=useBackground(),ctx2=import_react142.useRef(c);ctx2.current=c;let timers=import_react142.useRef([]);import_react142.useEffect(()=>()=>{timers.current.forEach(clearTimeout),timers.current=[]},[]);let interrupted=import_react142.useRef(!1),info3=import_react142.useRef(!1),deltas=import_react142.useRef({text:"",think:"",timer:null}),flush2=import_react142.useCallback(()=>{let d2=deltas.current;if(d2.timer)clearTimeout(d2.timer),d2.timer=null;if(d2.think)ctx2.current.dispatch({kind:"thinking",text:d2.think,final:!1}),d2.think="";if(d2.text)ctx2.current.dispatch({kind:"message.delta",chunk:d2.text}),d2.text=""},[]),sync=import_react142.useCallback((ms2=0)=>{let sid2=ctx2.current.sidRef.current;if(!sid2)return;let run=()=>gw.request("session.title",{session_id:sid2}).then((r)=>{if(ctx2.current.sidRef.current!==sid2)return;if(ctx2.current.setTitle(r.title??""),r.session_key)set("lastSessionId",r.session_key)}).catch(()=>{});if(ms2<=0)return run();let id=setTimeout(()=>{timers.current=timers.current.filter((t2)=>t2!==id),run()},ms2);timers.current.push(id)},[gw]),retitle=import_react142.useCallback((sid2,title)=>{if(!sid2||title===void 0)return;if(sid2===ctx2.current.sidRef.current)ctx2.current.setTitle(title);home3.update("recentSessions",(rows3)=>rows3.map((r)=>r.id===sid2?{...r,title}:r))},[]),handle=import_react142.useCallback((ev)=>{let x2=ctx2.current;if(ev.type==="gateway.ready")info3.current=!1;if(ev.type==="message.start")x2.start();if(ev.type==="background.complete"&&ev.session_id&&x2.sidRef.current&&ev.session_id!==x2.sidRef.current){bg2.unregister(ev.payload.task_id);return}let shared=ev.type==="background.complete"&&!ev.session_id;if(ev.session_id&&x2.sidRef.current&&ev.session_id!==x2.sidRef.current&&!ev.type.startsWith("gateway.")&&!shared)return;if(interrupted.current){if(STREAM_EVENTS.has(ev.type))return;if(ev.type==="status.update"&&ev.payload?.kind==="lifecycle")return}let action=mapEvent(ev,{onReady:()=>{x2.session.boot(x2.launchRef.current).then((r)=>{if(x2.setSid(r.id),r.info)x2.setInfo(r.info),x2.setUsage(r.info.usage);if(x2.sessionStart.current=Date.now(),r.messages.length)x2.dispatch({kind:"load",messages:r.messages});if(r.note)toast.show({variant:"info",message:r.note})}).catch((err)=>{let msg=err instanceof Error?err.message:String(err);x2.setReady(!1),x2.setStarting(!1),x2.setStatus(`session boot failed: ${msg}`),x2.setErrorPulse(!0),x2.dispatch({kind:"system",text:`Failed to start session: ${msg}`})})},onSessionInfo:(si)=>{if(x2.setInfo(si),si.usage)x2.setUsage(si.usage);if(x2.setReady(!0),si.running===!1)x2.start(),x2.setStarting(!1),x2.setStatus("");if(si.session_id)x2.setSid(si.session_id);if(x2.settle(),si.title!==void 0)x2.setTitle(si.title);let bad=(si.mcp_servers??[]).filter((s)=>!s.connected);if(bad.length)x2.dispatch({kind:"system",text:`MCP: ${bad.length} server(s) failed to connect \u2014 ${bad.map((s)=>s.name+(s.error?` (${s.error})`:"")).join(", ")}`});gw.request("config.get",{key:"busy"}).then((r)=>{let m2=r.value;if(m2==="queue"||m2==="steer"||m2==="interrupt")x2.setBusy(m2)}).catch(()=>{})},onUsage:(u3)=>x2.setUsage(u3),onTurnComplete:()=>{x2.setStarting(!1),x2.setStatus(""),flush(gw,x2.sidRef.current),x2.goalHook.check(x2.sidRef.current),TITLE_DELAYS.forEach(sync)},onBackground:(tid,text5)=>{let title=bg2.label(tid);bg2.unregister(tid),x2.dispatch({kind:"background",id:tid,title,text:text5})},onBtw:(text5)=>{let head=text5.split(`
4185
- `)[0].slice(0,80);x2.dispatch({kind:"system",text:`\u25C8 btw \u2014 ${head}`}),toast.show({variant:"info",title:"btw",message:head,duration:8000,action:{label:"view",run:()=>openAlert(dialog,"btw",text5)}})},onStatus:(text5)=>x2.setStatus(text5),onSessionTitle:retitle,onApprovalRemembered:(fallback)=>{let sid2=x2.sidRef.current;gw.request("approval.respond",{choice:"always"}).catch((err)=>{if(ctx2.current.sidRef.current!==sid2)return;x2.dispatch(fallback),toast.show({variant:"error",message:err.message})})},onSkin:(s)=>x2.setSkin(deriveSkin(s)),onVoiceStatus:x2.onVoiceStatus,onVoiceTranscript:x2.onVoiceTranscript,notices:toast});if(!action)return;if(ev.type==="session.info"){if(info3.current)return;info3.current=!0}let d2=deltas.current;if(action.kind==="message.delta"){if(d2.think)flush2();d2.text+=action.chunk,d2.timer??=setTimeout(flush2,16);return}if(action.kind==="thinking"&&!action.final){if(d2.text)flush2();d2.think+=action.text,d2.timer??=setTimeout(flush2,16);return}if(flush2(),action.kind==="message.start")x2.setStarting(!1),x2.setStatus("");if(action.kind==="error")x2.setStarting(!1);if(action.kind==="error")x2.setErrorPulse(!0);x2.dispatch(action)},[gw,dialog,toast,flush2,bg2,retitle]);useGatewayEvent(handle);let doInterrupt=import_react142.useCallback(()=>{interrupted.current=!0;let d2=deltas.current;if(d2.timer)clearTimeout(d2.timer),d2.timer=null;d2.text="",d2.think="",ctx2.current.session.interrupt().catch((err)=>{interrupted.current=!1,toast.show({variant:"error",message:err.message})})},[toast]);return{interrupted,doInterrupt}}var import_react148=__toESM(require_react_production(),1);init_perf();var PORT=Number(process.env.CONTROL_PORT)||7777,BIND=process.env.CONTROL_BIND||"127.0.0.1",enabled2=process.env.CONTROL==="1",LOOPBACK=new Set(["127.0.0.1","::1","localhost"]);function isLoopback(host){return LOOPBACK.has(host)}function warningFor(on,bind,port2){if(!on)return null;if(isLoopback(bind))return null;return{host:bind,port:port2,message:`CONTROL server bound to ${bind}:${port2} \u2014 reachable from the network. Set CONTROL_BIND=127.0.0.1 to restrict to loopback.`}}function warning(){return warningFor(enabled2,BIND,PORT)}var TAB_NAMES=TABS.map((t2)=>t2.name),bridge=null,pendingTab=null,pendingSend=!1;function setBridge(b2){bridge=b2}function currentTab(){if(pendingTab!==null)return pendingTab;return bridge?.tab()??0}var json2=(data2,status2=200)=>new Response(JSON.stringify(data2),{status:status2,headers:{"Content-Type":"application/json"}}),idx=(name)=>{let n=TAB_NAMES.indexOf(name);if(n<0)throw Error(`control.ts DANGEROUS: tab '${name}' missing from TAB_NAMES`);return n},DANGEROUS={[idx("Chat")]:new Set(["return"]),[idx("Sessions")]:new Set(["d","delete","return"]),[idx("Profiles & Automation")]:new Set(["return","space","d","delete","k"]),[idx("Config")]:new Set(["space","return","h","l","]","[","ctrl+s","d","delete"]),[idx("Eikon")]:new Set(["return","n","d","delete","s","u","ctrl+s","ctrl+u"])};function isDangerous(tab,keyName2,ctrl){let set3=DANGEROUS[tab];if(!set3)return!1;let id=ctrl?`ctrl+${keyName2}`:keyName2;return set3.has(id)}function makeKey(opts){return{name:opts.name,ctrl:opts.ctrl??!1,meta:opts.meta??!1,shift:opts.shift??!1,option:!1,sequence:opts.raw??opts.name,number:!1,raw:opts.raw??opts.name,eventType:"press",source:"raw"}}function injectKey(renderer,key5){let r=renderer;if(!r?.keyInput?.processParsedKey)return!1;return r.keyInput.processParsedKey(key5)}function getNodeChildren(n){if(n.getChildren)return n.getChildren();if(n._childrenInLayoutOrder)return[...n._childrenInLayoutOrder];return[]}function getNodeType(n){return n._type||n.tagName||n.constructor?.name||"unknown"}function buildFocusTree(node,depth=0){if(!node||typeof node!=="object")return null;let n=node,type=getNodeType(n),focused=n.focused??!1,focusable=n.focusable??!1,children2=[];if(depth<20)for(let child of getNodeChildren(n)){let c=buildFocusTree(child,depth+1);if(c)children2.push(c)}if(!(focusable||children2.some((c)=>c.focusable||c.focused||c.children.length>0))&&!focused&&depth>0)return null;let text5=n.value||n.textContent||n.text||void 0;return{type,focused,focusable,children:children2,text:text5}}function findFocused(node){if(!node||typeof node!=="object")return null;let n=node;if(n.focused)return getNodeType(n);for(let child of getNodeChildren(n)){let found2=findFocused(child);if(found2)return found2}return null}function countNodes(node){let result={total:0,focusable:0,focused:0};function walk2(n){if(!n||typeof n!=="object")return;let nd=n;if(result.total++,nd.focusable)result.focusable++;if(nd.focused)result.focused++;for(let child of getNodeChildren(nd))walk2(child)}return walk2(node),result}async function handle(req){let url2=new URL(req.url),path4=url2.pathname;if(!bridge)return json2({error:"bridge not ready"},503);if(path4==="/status"){let m2=process.memoryUsage(),tab=currentTab();return pendingTab=null,json2({tab,tabName:TAB_NAMES[tab]??"unknown",ready:bridge.ready(),streaming:bridge.streaming(),messages:bridge.messages(),session:bridge.session(),input:bridge.input(),focusRegion:bridge.focusRegion(),rss:Math.round(m2.rss/1024/1024),heap:Math.round(m2.heapUsed/1024/1024)})}let tabMatch=path4.match(/^\/tab\/(\d+)$/);if(tabMatch){let n=Number(tabMatch[1]);if(n<0||n>TAB_MAX)return json2({error:`tab 0-${TAB_MAX}`},400);let renderer=bridge.renderer();if(renderer){let cur=bridge.tab(),diff=n-cur,key5=makeKey({name:diff>0?"right":"left",meta:!0});for(let i=Math.abs(diff);i>0;i--)injectKey(renderer,key5)}else bridge.setTab(n);return pendingTab=n,json2({tab:n,tabName:TAB_NAMES[n]})}if(path4==="/send"&&req.method==="POST"){let body2=await req.json();if(!body2.message)return json2({error:"message required"},400);if(!bridge.ready())return json2({error:"not connected"},503);if(bridge.streaming())return json2({error:"already streaming"},409);if(pendingSend)return json2({error:"send already pending"},409);pendingSend=!0;try{await bridge.send(body2.message)}catch(err){return json2({error:err instanceof Error?err.message:String(err)},502)}finally{pendingSend=!1}return json2({sent:!0,message:body2.message})}if(path4==="/key"&&req.method==="POST"){let body2=await req.json();if(!body2.name)return json2({error:"name required"},400);let renderer=bridge.renderer();if(!renderer)return json2({error:"renderer not available"},503);let safe2=body2.safe!==!1,tab=currentTab();if(safe2&&isDangerous(tab,body2.name,!!body2.ctrl))return json2({error:"blocked",reason:`Key "${body2.ctrl?"ctrl+":""}${body2.name}" is dangerous on tab ${TAB_NAMES[tab]} (index ${tab}). Pass safe=false to override.`,tab,tabName:TAB_NAMES[tab]},403);let key5=makeKey({name:body2.name,ctrl:body2.ctrl,shift:body2.shift,meta:body2.meta,raw:body2.raw??(body2.name.length===1?body2.name:"")}),handled=injectKey(renderer,key5);return json2({injected:!0,handled,key:body2.name,tab,tabName:TAB_NAMES[tab]})}if(path4==="/keys"&&req.method==="POST"){let body2=await req.json();if(!body2.keys?.length)return json2({error:"keys array required"},400);let renderer=bridge.renderer();if(!renderer)return json2({error:"renderer not available"},503);let safe2=body2.safe!==!1,tab=currentTab(),delay=body2.delay??0,results=[];for(let k2 of body2.keys){if(safe2&&isDangerous(currentTab(),k2.name,!!k2.ctrl)){results.push({key:k2.name,injected:!1,handled:!1,blocked:!0});continue}let key5=makeKey({name:k2.name,ctrl:k2.ctrl,shift:k2.shift,meta:k2.meta,raw:k2.raw??(k2.name.length===1?k2.name:"")}),handled=injectKey(renderer,key5);if(results.push({key:k2.name,injected:!0,handled}),delay>0)await new Promise((r)=>setTimeout(r,delay))}return json2({results,tab,tabName:TAB_NAMES[tab]})}if(path4==="/type"&&req.method==="POST"){let body2=await req.json();if(!body2.text)return json2({error:"text required"},400);let renderer=bridge.renderer();if(!renderer)return json2({error:"renderer not available"},503);let safe2=body2.safe!==!1,tab=currentTab(),delay=body2.delay??0,count4=0;for(let ch of body2.text){if(safe2&&isDangerous(tab,ch,!1))continue;let key5=makeKey({name:ch,raw:ch});if(injectKey(renderer,key5),count4++,delay>0)await new Promise((r)=>setTimeout(r,delay))}return json2({typed:count4,total:body2.text.length,tab,tabName:TAB_NAMES[tab]})}if(path4==="/input"&&req.method==="POST"){let body2=await req.json();return bridge.setInput(body2.text??""),json2({ok:!0,text:body2.text??""})}if(path4==="/quit")return setTimeout(()=>process.exit(0),10),json2({ok:!0});if(path4==="/focus"){let r=bridge.renderer();if(!r?.root)return json2({error:"no renderer root"},503);let counts=countNodes(r.root),tree3=buildFocusTree(r.root),focused=findFocused(r.root),currentFocus=r.currentFocusedRenderable?getNodeType(r.currentFocusedRenderable):null;return json2({focused,currentFocus,counts,tree:tree3})}if(path4==="/frame"){let r=bridge.renderer();if(!r?.currentRenderBuffer)return json2({error:"no render buffer"},503);let frame2=new TextDecoder().decode(r.currentRenderBuffer.getRealCharBytes(!0)),grep=url2.searchParams.get("grep"),body2=grep?frame2.split(`
4184
+ *[interrupted]*`,usage:p?.usage};return{kind:"message.complete",text:p?.text??void 0,usage:p?.usage}}case"tool.start":return{kind:"tool.start",id:ev.payload.tool_id,name:ev.payload.name??"unknown",preview:ev.payload.context,args:ev.payload.args_text};case"tool.progress":return{kind:"tool.progress",name:ev.payload.name,preview:ev.payload.preview};case"tool.generating":return{kind:"tool.generating",name:ev.payload.name};case"tool.complete":return{kind:"tool.complete",id:ev.payload.tool_id,summary:ev.payload.summary,error:ev.payload.error,inline_diff:ev.payload.inline_diff,duration:typeof ev.payload.duration_s==="number"?ev.payload.duration_s*1000:void 0,result:ev.payload.result_text};case"thinking.delta":return side.onStatus?.(ev.payload?.text??""),null;case"reasoning.delta":case"reasoning.available":{let text5=ev.payload?.text;if(!text5)return null;return{kind:"thinking",text:text5,final:ev.type==="reasoning.available",verbose:ev.payload?.verbose}}case"moa.reference":return{kind:"reference",text:reference(ev.payload?.label??"reference",ev.payload?.text??"",ev.payload?.index,ev.payload?.count)};case"moa.aggregating":{let agg=ev.payload?.aggregator;return side.onStatus?.(agg?`aggregating with ${agg}\u2026`:"aggregating\u2026"),null}case"subagent.start":case"subagent.thinking":case"subagent.tool":case"subagent.progress":case"subagent.complete":{let sub2=ev.type.slice(9);return record(sub2,ev.payload),{kind:"subagent",event:sub2,payload:ev.payload}}case"error":return{kind:"error",text:ev.payload?.message??"Unknown error"};case"clarify.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"clarify",...ev.payload}};case"approval.request":{let req={variant:"approval",...ev.payload},fallback2={kind:"prompt",id:`approval-${pid()}`,req};if(shouldRemember(req))return side.onApprovalRemembered?.(fallback2),null;return fallback2}case"sudo.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"sudo",...ev.payload}};case"secret.request":return{kind:"prompt",id:ev.payload.request_id,req:{variant:"secret",...ev.payload}};case"background.complete":return side.onBackground?.(ev.payload.task_id,ev.payload.text),null;case"review.summary":{let text5=String(ev.payload?.text??"").trim();if(!text5)return null;return{kind:"system",text:text5}}case"btw.complete":return side.onBtw?.(ev.payload.text),null;case"gateway.stderr":{let line4=ev.payload.line;if(/error|fail|traceback|exception|\b[45]\d\d\b|refused|denied|unauthori/i.test(line4))return{kind:"error",text:line4,fatal:!1};return null}case"skin.changed":return side.onSkin?.(ev.payload),null;case"gateway.start_timeout":return{kind:"error",text:`gateway startup timed out (${ev.payload?.python??"python"} @ ${ev.payload?.cwd??"?"})`};case"gateway.protocol_error":return{kind:"system",text:`protocol error: ${ev.payload?.preview??"?"}`};case"browser.progress":{let text5=ev.payload?.message??"";if(!text5)return null;return ev.payload?.level==="error"?{kind:"error",text:text5}:{kind:"system",text:`\xB7 ${text5}`}}case"status.update":{let kind2=ev.payload?.kind,text5=ev.payload?.text??"";if(kind2==="process")return side.onStatus?.(formatProcessNotification(text5)),null;if(side.onStatus?.(text5),!kind2||kind2==="status")return null;return{kind:"system",text:text5}}case"notification.show":if(side.notices)showNotification(side.notices,ev.payload);return null;case"notification.clear":if(side.notices)clearNotification(side.notices,ev.payload);return null;case"voice.status":{let state3=String(ev.payload?.state??"");return side.onVoiceStatus?.(state3),null}case"voice.transcript":{if(ev.payload?.no_speech_limit===!0)return side.onVoiceTranscript?.("",!0),null;let text5=String(ev.payload?.text??"").trim();if(!text5)return null;return side.onVoiceTranscript?.(text5,!1),null}}return null}var STREAM_EVENTS=new Set(["message.start","message.delta","reasoning.delta","reasoning.available","thinking.delta","moa.reference","moa.aggregating","tool.start","tool.progress","tool.generating"]),TITLE_DELAYS=[1200,5000,15000,30000];function useStream(c){let gw=useGateway(),dialog=useDialog(),toast=useToast(),bg2=useBackground(),ctx2=import_react142.useRef(c);ctx2.current=c;let timers=import_react142.useRef([]);import_react142.useEffect(()=>()=>{timers.current.forEach(clearTimeout),timers.current=[]},[]);let interrupted=import_react142.useRef(!1),info3=import_react142.useRef(!1),deltas=import_react142.useRef({text:"",think:"",timer:null}),flush2=import_react142.useCallback(()=>{let d2=deltas.current;if(d2.timer)clearTimeout(d2.timer),d2.timer=null;if(d2.think)ctx2.current.dispatch({kind:"thinking",text:d2.think,final:!1}),d2.think="";if(d2.text)ctx2.current.dispatch({kind:"message.delta",chunk:d2.text}),d2.text=""},[]),sync=import_react142.useCallback((ms2=0)=>{let sid2=ctx2.current.sidRef.current;if(!sid2)return;let run=()=>gw.request("session.title",{session_id:sid2}).then((r)=>{if(ctx2.current.sidRef.current!==sid2)return;if(ctx2.current.setTitle(r.title??""),r.session_key)set("lastSessionId",r.session_key)}).catch(()=>{});if(ms2<=0)return run();let id=setTimeout(()=>{timers.current=timers.current.filter((t2)=>t2!==id),run()},ms2);timers.current.push(id)},[gw]),retitle=import_react142.useCallback((sid2,title)=>{if(!sid2||title===void 0)return;if(sid2===ctx2.current.sidRef.current)ctx2.current.setTitle(title);home3.update("recentSessions",(rows3)=>rows3.map((r)=>r.id===sid2?{...r,title}:r))},[]),handle=import_react142.useCallback((ev)=>{let x2=ctx2.current;if(ev.type==="gateway.ready")info3.current=!1;if(ev.type==="message.start")x2.start();if(ev.type==="background.complete"&&ev.session_id&&x2.sidRef.current&&ev.session_id!==x2.sidRef.current){bg2.unregister(ev.payload.task_id);return}let shared=ev.type==="background.complete"&&!ev.session_id;if(ev.session_id&&x2.sidRef.current&&ev.session_id!==x2.sidRef.current&&!ev.type.startsWith("gateway.")&&!shared)return;if(interrupted.current){if(STREAM_EVENTS.has(ev.type))return;if(ev.type==="status.update"&&ev.payload?.kind==="lifecycle")return}let action=mapEvent(ev,{onReady:()=>{x2.session.boot(x2.launchRef.current).then((r)=>{if(x2.setSid(r.id),r.info)x2.setInfo(r.info),x2.setUsage(r.info.usage);if(x2.sessionStart.current=Date.now(),r.messages.length)x2.dispatch({kind:"load",messages:r.messages});if(r.note)toast.show({variant:"info",message:r.note})}).catch((err)=>{let msg=err instanceof Error?err.message:String(err);x2.setReady(!1),x2.setStarting(!1),x2.setStatus(`session boot failed: ${msg}`),x2.setErrorPulse(!0),x2.dispatch({kind:"system",text:`Failed to start session: ${msg}`})})},onSessionInfo:(si)=>{if(x2.setInfo(si),si.usage)x2.setUsage(si.usage);if(x2.setReady(!0),si.running===!1)x2.start(),x2.setStarting(!1),x2.setStatus("");if(si.session_id)x2.setSid(si.session_id);if(x2.settle(),si.title!==void 0)x2.setTitle(si.title);let bad=(si.mcp_servers??[]).filter((s)=>!s.connected);if(bad.length)x2.dispatch({kind:"system",text:`MCP: ${bad.length} server(s) failed to connect \u2014 ${bad.map((s)=>s.name+(s.error?` (${s.error})`:"")).join(", ")}`});gw.request("config.get",{key:"busy"}).then((r)=>{let m2=r.value;if(m2==="queue"||m2==="steer"||m2==="interrupt")x2.setBusy(m2)}).catch(()=>{})},onUsage:(u3)=>x2.setUsage(u3),onTurnComplete:()=>{x2.setStarting(!1),x2.setStatus(""),flush(gw,x2.sidRef.current),x2.goalHook.check(x2.sidRef.current),TITLE_DELAYS.forEach(sync)},onBackground:(tid,text5)=>{let title=bg2.label(tid);bg2.unregister(tid),x2.dispatch({kind:"background",id:tid,title,text:text5})},onBtw:(text5)=>{let head=text5.split(`
4185
+ `)[0].slice(0,80);x2.dispatch({kind:"system",text:`\u25C8 btw \u2014 ${head}`}),toast.show({variant:"info",title:"btw",message:head,duration:8000,action:{label:"view",run:()=>openAlert(dialog,"btw",text5)}})},onStatus:(text5)=>x2.setStatus(text5),onSessionTitle:retitle,onApprovalRemembered:(fallback2)=>{let sid2=x2.sidRef.current;gw.request("approval.respond",{choice:"always"}).catch((err)=>{if(ctx2.current.sidRef.current!==sid2)return;x2.dispatch(fallback2),toast.show({variant:"error",message:err.message})})},onSkin:(s)=>x2.setSkin(deriveSkin(s)),onVoiceStatus:x2.onVoiceStatus,onVoiceTranscript:x2.onVoiceTranscript,notices:toast});if(!action)return;if(ev.type==="session.info"){if(info3.current)return;info3.current=!0}let d2=deltas.current;if(action.kind==="message.delta"){if(d2.think)flush2();d2.text+=action.chunk,d2.timer??=setTimeout(flush2,16);return}if(action.kind==="thinking"&&!action.final){if(d2.text)flush2();d2.think+=action.text,d2.timer??=setTimeout(flush2,16);return}if(flush2(),action.kind==="message.start")x2.setStarting(!1),x2.setStatus("");if(action.kind==="error")x2.setStarting(!1);if(action.kind==="error")x2.setErrorPulse(!0);x2.dispatch(action)},[gw,dialog,toast,flush2,bg2,retitle]);useGatewayEvent(handle);let doInterrupt=import_react142.useCallback(()=>{interrupted.current=!0;let d2=deltas.current;if(d2.timer)clearTimeout(d2.timer),d2.timer=null;d2.text="",d2.think="",ctx2.current.session.interrupt().catch((err)=>{interrupted.current=!1,toast.show({variant:"error",message:err.message})})},[toast]);return{interrupted,doInterrupt}}var import_react148=__toESM(require_react_production(),1);init_perf();var PORT=Number(process.env.CONTROL_PORT)||7777,BIND=process.env.CONTROL_BIND||"127.0.0.1",enabled2=process.env.CONTROL==="1",LOOPBACK=new Set(["127.0.0.1","::1","localhost"]);function isLoopback(host){return LOOPBACK.has(host)}function warningFor(on,bind,port2){if(!on)return null;if(isLoopback(bind))return null;return{host:bind,port:port2,message:`CONTROL server bound to ${bind}:${port2} \u2014 reachable from the network. Set CONTROL_BIND=127.0.0.1 to restrict to loopback.`}}function warning(){return warningFor(enabled2,BIND,PORT)}var TAB_NAMES=TABS.map((t2)=>t2.name),bridge=null,pendingTab=null,pendingSend=!1;function setBridge(b2){bridge=b2}function currentTab(){if(pendingTab!==null)return pendingTab;return bridge?.tab()??0}var json2=(data2,status2=200)=>new Response(JSON.stringify(data2),{status:status2,headers:{"Content-Type":"application/json"}}),idx=(name)=>{let n=TAB_NAMES.indexOf(name);if(n<0)throw Error(`control.ts DANGEROUS: tab '${name}' missing from TAB_NAMES`);return n},DANGEROUS={[idx("Chat")]:new Set(["return"]),[idx("Sessions")]:new Set(["d","delete","return"]),[idx("Profiles & Automation")]:new Set(["return","space","d","delete","k"]),[idx("Config")]:new Set(["space","return","h","l","]","[","ctrl+s","d","delete"]),[idx("Eikon")]:new Set(["return","n","d","delete","s","u","ctrl+s","ctrl+u"])};function isDangerous(tab,keyName2,ctrl){let set3=DANGEROUS[tab];if(!set3)return!1;let id=ctrl?`ctrl+${keyName2}`:keyName2;return set3.has(id)}function makeKey(opts){return{name:opts.name,ctrl:opts.ctrl??!1,meta:opts.meta??!1,shift:opts.shift??!1,option:!1,sequence:opts.raw??opts.name,number:!1,raw:opts.raw??opts.name,eventType:"press",source:"raw"}}function injectKey(renderer,key5){let r=renderer;if(!r?.keyInput?.processParsedKey)return!1;return r.keyInput.processParsedKey(key5)}function getNodeChildren(n){if(n.getChildren)return n.getChildren();if(n._childrenInLayoutOrder)return[...n._childrenInLayoutOrder];return[]}function getNodeType(n){return n._type||n.tagName||n.constructor?.name||"unknown"}function buildFocusTree(node,depth=0){if(!node||typeof node!=="object")return null;let n=node,type=getNodeType(n),focused=n.focused??!1,focusable=n.focusable??!1,children2=[];if(depth<20)for(let child of getNodeChildren(n)){let c=buildFocusTree(child,depth+1);if(c)children2.push(c)}if(!(focusable||children2.some((c)=>c.focusable||c.focused||c.children.length>0))&&!focused&&depth>0)return null;let text5=n.value||n.textContent||n.text||void 0;return{type,focused,focusable,children:children2,text:text5}}function findFocused(node){if(!node||typeof node!=="object")return null;let n=node;if(n.focused)return getNodeType(n);for(let child of getNodeChildren(n)){let found2=findFocused(child);if(found2)return found2}return null}function countNodes(node){let result={total:0,focusable:0,focused:0};function walk2(n){if(!n||typeof n!=="object")return;let nd=n;if(result.total++,nd.focusable)result.focusable++;if(nd.focused)result.focused++;for(let child of getNodeChildren(nd))walk2(child)}return walk2(node),result}async function handle(req){let url2=new URL(req.url),path4=url2.pathname;if(!bridge)return json2({error:"bridge not ready"},503);if(path4==="/status"){let m2=process.memoryUsage(),tab=currentTab();return pendingTab=null,json2({tab,tabName:TAB_NAMES[tab]??"unknown",ready:bridge.ready(),streaming:bridge.streaming(),messages:bridge.messages(),session:bridge.session(),input:bridge.input(),focusRegion:bridge.focusRegion(),rss:Math.round(m2.rss/1024/1024),heap:Math.round(m2.heapUsed/1024/1024)})}let tabMatch=path4.match(/^\/tab\/(\d+)$/);if(tabMatch){let n=Number(tabMatch[1]);if(n<0||n>TAB_MAX)return json2({error:`tab 0-${TAB_MAX}`},400);let renderer=bridge.renderer();if(renderer){let cur=bridge.tab(),diff=n-cur,key5=makeKey({name:diff>0?"right":"left",meta:!0});for(let i=Math.abs(diff);i>0;i--)injectKey(renderer,key5)}else bridge.setTab(n);return pendingTab=n,json2({tab:n,tabName:TAB_NAMES[n]})}if(path4==="/send"&&req.method==="POST"){let body2=await req.json();if(!body2.message)return json2({error:"message required"},400);if(!bridge.ready())return json2({error:"not connected"},503);if(bridge.streaming())return json2({error:"already streaming"},409);if(pendingSend)return json2({error:"send already pending"},409);pendingSend=!0;try{await bridge.send(body2.message)}catch(err){return json2({error:err instanceof Error?err.message:String(err)},502)}finally{pendingSend=!1}return json2({sent:!0,message:body2.message})}if(path4==="/key"&&req.method==="POST"){let body2=await req.json();if(!body2.name)return json2({error:"name required"},400);let renderer=bridge.renderer();if(!renderer)return json2({error:"renderer not available"},503);let safe2=body2.safe!==!1,tab=currentTab();if(safe2&&isDangerous(tab,body2.name,!!body2.ctrl))return json2({error:"blocked",reason:`Key "${body2.ctrl?"ctrl+":""}${body2.name}" is dangerous on tab ${TAB_NAMES[tab]} (index ${tab}). Pass safe=false to override.`,tab,tabName:TAB_NAMES[tab]},403);let key5=makeKey({name:body2.name,ctrl:body2.ctrl,shift:body2.shift,meta:body2.meta,raw:body2.raw??(body2.name.length===1?body2.name:"")}),handled=injectKey(renderer,key5);return json2({injected:!0,handled,key:body2.name,tab,tabName:TAB_NAMES[tab]})}if(path4==="/keys"&&req.method==="POST"){let body2=await req.json();if(!body2.keys?.length)return json2({error:"keys array required"},400);let renderer=bridge.renderer();if(!renderer)return json2({error:"renderer not available"},503);let safe2=body2.safe!==!1,tab=currentTab(),delay=body2.delay??0,results=[];for(let k2 of body2.keys){if(safe2&&isDangerous(currentTab(),k2.name,!!k2.ctrl)){results.push({key:k2.name,injected:!1,handled:!1,blocked:!0});continue}let key5=makeKey({name:k2.name,ctrl:k2.ctrl,shift:k2.shift,meta:k2.meta,raw:k2.raw??(k2.name.length===1?k2.name:"")}),handled=injectKey(renderer,key5);if(results.push({key:k2.name,injected:!0,handled}),delay>0)await new Promise((r)=>setTimeout(r,delay))}return json2({results,tab,tabName:TAB_NAMES[tab]})}if(path4==="/type"&&req.method==="POST"){let body2=await req.json();if(!body2.text)return json2({error:"text required"},400);let renderer=bridge.renderer();if(!renderer)return json2({error:"renderer not available"},503);let safe2=body2.safe!==!1,tab=currentTab(),delay=body2.delay??0,count4=0;for(let ch of body2.text){if(safe2&&isDangerous(tab,ch,!1))continue;let key5=makeKey({name:ch,raw:ch});if(injectKey(renderer,key5),count4++,delay>0)await new Promise((r)=>setTimeout(r,delay))}return json2({typed:count4,total:body2.text.length,tab,tabName:TAB_NAMES[tab]})}if(path4==="/input"&&req.method==="POST"){let body2=await req.json();return bridge.setInput(body2.text??""),json2({ok:!0,text:body2.text??""})}if(path4==="/quit"){let renderer=bridge.renderer();try{renderer?.setTerminalTitle?.("")}catch{}return setTimeout(()=>process.exit(0),10),json2({ok:!0})}if(path4==="/focus"){let r=bridge.renderer();if(!r?.root)return json2({error:"no renderer root"},503);let counts=countNodes(r.root),tree3=buildFocusTree(r.root),focused=findFocused(r.root),currentFocus=r.currentFocusedRenderable?getNodeType(r.currentFocusedRenderable):null;return json2({focused,currentFocus,counts,tree:tree3})}if(path4==="/frame"){let r=bridge.renderer();if(!r?.currentRenderBuffer)return json2({error:"no render buffer"},503);let frame2=new TextDecoder().decode(r.currentRenderBuffer.getRealCharBytes(!0)),grep=url2.searchParams.get("grep"),body2=grep?frame2.split(`
4186
4186
  `).filter((l)=>l.includes(grep)).join(`
4187
4187
  `):frame2;if(url2.searchParams.get("json")==="1")return json2({frame:body2,match:grep?frame2.includes(grep):void 0,lines:frame2.split(`
4188
4188
  `).length});return new Response(body2,{headers:{"Content-Type":"text/plain; charset=utf-8"}})}if(path4==="/logs"){let n=Number(url2.searchParams.get("n"))||200;return new Response(bridge.logs(n),{headers:{"Content-Type":"text/plain; charset=utf-8"}})}let pm=path4.match(/^\/plugin\/([^/]+)$/);if(pm&&req.method==="POST"){let body2=await req.json(),ok=await bridge.plugin(pm[1],body2.on!==!1);return json2({id:pm[1],on:body2.on!==!1,ok})}if(path4==="/push"&&req.method==="POST"){let body2=await req.json();if(!body2.type)return json2({error:"type required"},400);return bridge.push(body2),json2({pushed:body2.type})}if(path4==="/perf"){let d2=data();if(!d2)return json2({error:"PERF not enabled"},400);return json2(d2)}if(path4==="/tabs"){let ms2=Number(url2.searchParams.get("delay")||"500");for(let i=0;i<=TAB_MAX;i++)bridge.setTab(i),await new Promise((r)=>setTimeout(r,ms2));return bridge.setTab(CHAT_TAB),json2({cycled:TAB_MAX+1,delay:ms2})}if(path4==="/mem"){mem("control:snapshot");let m2=process.memoryUsage();return json2({rss:Math.round(m2.rss/1024/1024),heap:Math.round(m2.heapUsed/1024/1024),heapTotal:Math.round(m2.heapTotal/1024/1024),external:Math.round(m2.external/1024/1024)})}return json2({error:"not found",routes:["GET /status","GET /tab/:n","POST /send {message}","POST /key {name, ctrl?, shift?, meta?, raw?, safe?}","POST /keys {keys: [{name, ...}], delay?, safe?}","POST /type {text, delay?, safe?}","POST /input {text}","POST /plugin/:id {on}","POST /push {type, payload?}","GET /quit","GET /frame ?grep=pat&json=1","GET /logs ?n=200","GET /focus","GET /perf","GET /tabs","GET /mem"]},404)}function start(){if(!enabled2)return;Bun.serve({port:PORT,hostname:BIND,fetch:handle});let w2=warning();if(w2){process.stderr.write(`\x1B[33m[control] WARNING: ${w2.message}\x1B[0m
4189
4189
  `);return}process.stderr.write(`\x1B[90m[control] http://${BIND}:${PORT}\x1B[0m
4190
- `)}var import_react146=__toESM(require_react_production(),1);function select(dialog,opts){return new Promise((res)=>{let settled=!1,done2=(v2)=>{if(settled)return;settled=!0,res(v2),dialog.clear()};dialog.replace($jsx(DialogSelect,{title:opts.title,options:opts.options,placeholder:opts.placeholder,onSelect:(o)=>done2(o)}),()=>done2(null))})}function locate3(routes,name){let lower=name.toLowerCase(),hit2=TAB_SLASH[lower];if(hit2)return hit2;let i=[...routes.keys()].findIndex((n)=>n.toLowerCase()===lower);if(i<0)return;return{tab:TABS.length+i,sub:0}}function createApi(input){return{renderer:input.renderer,theme:{get current(){return input.theme.current.theme},get name(){return input.theme.current.name},get mode(){return input.theme.current.mode},set:(name)=>input.theme.current.set(name),setMode:(mode2)=>input.theme.current.setMode(mode2),has:(name)=>input.theme.current.has(name)},get keys(){return input.keys.current},ui:{dialog:input.dialog,toast:(o)=>input.toast.show({variant:o.variant??"info",title:o.title,message:o.message}),confirm:(o)=>openConfirm(input.dialog,o),prompt:(o)=>openTextPrompt(input.dialog,o),alert:(title,body2)=>openAlert(input.dialog,title,body2),select:(o)=>select(input.dialog,o)},kv:{get:(key5,fallback)=>{return get2("plugin")?.[key5]??fallback},set:(key5,value2)=>{let bag=get2("plugin")??{};set("plugin",{...bag,[key5]:value2})}},get client(){return input.gw.current},event:{on:(fn)=>{let c=input.gw.current,h2=(ev)=>fn(ev);return c.on("event",h2),()=>c.off("event",h2)}},route:{register:(defs)=>{for(let d2 of defs)input.routes.set(d2.name,d2);return input.bump(),()=>{for(let d2 of defs)input.routes.delete(d2.name);input.bump()}},navigate:(name,sub2)=>{let at=locate3(input.routes,name);if(!at)return;input.nav.current?.(at.tab,sub2??at.sub)},get current(){return input.cur.current?.()}},command:{register:(cmds)=>input.cmd.register(cmds)},slots:{register(){throw Error("slots.register is only available inside a plugin's tui() factory")}},eikon:{rasterizer:{register:(r)=>register(r)}},lifecycle:{signal:new AbortController().signal,onDispose:()=>()=>{}}}}function createScope(id,fail2){let ctrl=new AbortController,list3=[],done2=!1,onDispose=(fn)=>{if(done2)return()=>{};let key5=Symbol();return list3.push({key:key5,fn}),()=>{list3=list3.filter((x2)=>x2.key!==key5)}},track=(fn)=>{if(!fn)return()=>{};let ran=!1,drop2=()=>{},wrapped=()=>{if(ran)return;return ran=!0,drop2(),fn()};return drop2=onDispose(wrapped),wrapped},race=(fn,left)=>new Promise((res)=>{let t2=setTimeout(()=>res("timeout"),left);Promise.resolve().then(fn).then(()=>{clearTimeout(t2),res("ok")}).catch((e)=>{clearTimeout(t2),res(e instanceof Error?e:Error(String(e)))})}),dispose=async()=>{if(done2)return;done2=!0,ctrl.abort();let queue=[...list3].reverse();list3=[];let until2=Date.now()+5000;for(let item of queue){let left=until2-Date.now();if(left<=0){fail2(`[plugin:${id}] dispose budget exhausted`);return}let out=await race(item.fn,left);if(out==="ok")continue;if(out==="timeout"){fail2(`[plugin:${id}] dispose timed out`);return}fail2(`[plugin:${id}] dispose threw`,out)}};return{lifecycle:{signal:ctrl.signal,onDispose},track,dispose}}var import_react143=__toESM(require_react_production(),1);var fmt4=(d2)=>[d2.getHours(),d2.getMinutes(),d2.getSeconds()].map((n)=>String(n).padStart(2,"0")).join(":");function Clock(props){let[now,set3]=import_react143.useState(()=>new Date);return import_react143.useEffect(()=>{let t2=setInterval(()=>set3(new Date),1000);return()=>clearInterval(t2)},[]),$jsx("text",{fg:props.api.theme.current.textMuted,wrapMode:"none",children:fmt4(now)})}var plugin={id:"demo.clock",enabled:!1,tui(api){api.slots.register({order:100,slots:{app_bottom:()=>$jsx(Clock,{api})}})}},clock_default=plugin;var import_react144=__toESM(require_react_production(),1);import{readdirSync as readdirSync12,statSync as statSync11}from"fs";import{join as join27,basename as basename15}from"path";import{homedir as homedir10}from"os";var PREVIEW_MAX=200000,read4=(dir2)=>{return(dir2==="/"?[]:[{name:"..",dir:!0}]).concat(readdirSync12(dir2,{withFileTypes:!0}).filter((d2)=>!d2.name.startsWith(".")).sort((a,b2)=>a.isDirectory()===b2.isDirectory()?a.name.localeCompare(b2.name):a.isDirectory()?-1:1).map((d2)=>({name:d2.name,dir:d2.isDirectory()})))},isMd=(name)=>/\.(md|markdown|mdx)$/i.test(name);function Files(props){let api=props.api,theme=api.theme.current,[dir2,setDir]=import_react144.useState(()=>homedir10()),[sel,setSel]=import_react144.useState(0),[preview2,setPreview]=import_react144.useState(""),listing=import_react144.useMemo(()=>{try{return{rows:read4(dir2),error:""}}catch(e){return{rows:[],error:e instanceof Error?e.message:String(e)}}},[dir2]),rows3=listing.rows;import_react144.useEffect(()=>{setSel((s)=>Math.min(s,Math.max(0,rows3.length-1)))},[rows3.length]);let active=rows3[sel];import_react144.useEffect(()=>{if(!active||active.dir){setPreview("");return}let path4=join27(dir2,active.name),cancel=!1;return(async()=>{let st=statSync11(path4);if(st.size>PREVIEW_MAX){if(!cancel)setPreview(`(file too large \u2014 ${st.size} bytes)`);return}let text5=await Bun.file(path4).text();if(!cancel)setPreview(text5)})().catch((e)=>{if(!cancel)setPreview(`(read error: ${e})`)}),()=>{cancel=!0}},[dir2,active?.name,active?.dir]);let enter=()=>{if(!active)return;if(active.name===".."){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}if(active.dir)setDir((d2)=>join27(d2,active.name)),setSel(0)};return useKeyboard((key5)=>{if(!props.focused||api.ui.dialog.open())return;if(key5.name==="left"){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}handleListKey(api.keys,key5,{count:rows3.length,setSel,onActivate:enter})}),$jsxs("box",{flexGrow:1,flexDirection:"column",children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:dir2})}),$jsxs("box",{flexGrow:1,flexDirection:"row",children:[$jsxs("box",{width:32,flexShrink:0,flexDirection:"column",border:!0,borderColor:theme.border,children:[rows3.map((e,i)=>$jsx("box",{height:1,paddingX:1,backgroundColor:i===sel?theme.backgroundElement:void 0,children:$jsx("text",{fg:i===sel?theme.selectedListItemText:e.dir?theme.accent:theme.text,wrapMode:"none",children:(e.dir?"\u25B8 ":" ")+e.name})},e.name)),listing.error?$jsx("box",{height:1,paddingX:1,children:$jsx("text",{fg:theme.error,wrapMode:"none",children:listing.error})}):null]}),$jsx("box",{flexGrow:1,flexDirection:"column",border:!0,borderColor:theme.border,children:active&&!active.dir?$jsxs($Fragment,{children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:[basename15(active.name),isMd(active.name)?" \xB7 markdown":""]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:preview2})})]}):$jsx("box",{paddingX:1,children:$jsx("text",{fg:theme.textMuted,children:"Select a file to preview."})})})]})]})}var plugin2={id:"demo.files",enabled:!1,tui(api){api.route.register([{name:"Files",description:"File browser",render:({focused})=>$jsx(Files,{api,focused})}]),api.command.register([{title:"Files: open browser",value:"plugin.files.open",category:"Plugin",onSelect:()=>api.route.navigate("Files")}])}},files_default=plugin2;var INTERNAL=[clock_default,files_default];var KV_ENABLED="enabled",Ctx7=import_react146.createContext(null);function fail2(msg,err){let tail=err instanceof Error?`: ${err.message}`:err!==void 0?`: ${String(err)}`:"";console.error(msg+tail)}var RouteBody=(props)=>props.render(props.ctx);class RouteBoundary extends import_react146.Component{state={};static getDerivedStateFromError(error){return{error}}componentDidCatch(error,_info){fail2(`[plugin:${this.props.id}] render error in route "${this.props.name}"`,error)}render(){if(this.state.error)return $jsx("text",{children:`Plugin ${this.props.id} route ${this.props.name}: ${this.state.error.message}`});return this.props.children}}function enabledMap(){let v2=get2("plugin")?.[KV_ENABLED];return v2&&typeof v2==="object"?v2:{}}function persist2(id,on){let bag=get2("plugin")??{},map={...enabledMap(),[id]:on};set("plugin",{...bag,[KV_ENABLED]:map})}function scoped(base3,reg,id,scope){let n=0;return{...base3,slots:{register(p){let sid2=n++?`${id}:${n}`:id;return scope.track(reg.register({...p,id:sid2}))}},route:{register:(defs)=>scope.track(base3.route.register(defs.map((def2)=>({...def2,render:(ctx2)=>$jsx(RouteBoundary,{id,name:def2.name,children:$jsx(RouteBody,{render:def2.render,ctx:ctx2})})})))),navigate:base3.route.navigate,get current(){return base3.route.current}},event:{on:(fn)=>scope.track(base3.event.on(fn))},command:{register:(cmds)=>scope.track(base3.command.register(cmds))},eikon:{rasterizer:{register:(r)=>scope.track(base3.eikon.rasterizer.register(r))}},kv:{get:(key5,fb)=>base3.kv.get(`${id}.${key5}`,fb),set:(key5,v2)=>base3.kv.set(`${id}.${key5}`,v2)},lifecycle:scope.lifecycle}}var CELLS=new WeakMap;function ctxFor(renderer,themeRef){let hit2=CELLS.get(renderer);if(hit2)return hit2.themeRef=themeRef,hit2.ctx;let cell={themeRef,ctx:{}};return Object.defineProperty(cell.ctx,"theme",{get:()=>cell.themeRef.current.theme,enumerable:!0}),CELLS.set(renderer,cell),cell.ctx}function PluginProvider(props){let list3=props.plugins??INTERNAL,renderer=useRenderer(),themeCtx=useTheme(),keys=useKeys(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),gw=useGateway(),themeRef=import_react146.useRef(themeCtx);themeRef.current=themeCtx;let keysRef=import_react146.useRef(keys);keysRef.current=keys;let gwRef=import_react146.useRef(gw);gwRef.current=gw;let navRef=import_react146.useRef(null),curRef=import_react146.useRef(null),routes=import_react146.useRef(new Map).current,[rev3,bump2]=import_react146.useReducer((x2)=>x2+1,0),reg=import_react146.useMemo(()=>createReactSlotRegistry(renderer,ctxFor(renderer,themeRef),{onPluginError:(e)=>fail2(`[plugin:${e.pluginId}] ${e.phase} error in slot "${e.slot}"`,e.error)}),[renderer]),Slot2=import_react146.useMemo(()=>createSlot(reg),[reg]),api=import_react146.useMemo(()=>createApi({renderer,theme:themeRef,keys:keysRef,dialog,toast,gw:gwRef,cmd,routes,bump:bump2,nav:navRef,cur:curRef}),[renderer,dialog,toast,cmd,routes]),entries2=import_react146.useRef(new Map),[gen,force]=import_react146.useReducer((x2)=>x2+1,0),activate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!0,write)persist2(id,!0);if(e.scope)return!0;let scope=createScope(id,fail2),ok=await Promise.resolve().then(()=>e.plugin.tui(scoped(api,reg,id,scope))).then(()=>!0).catch((err)=>{return fail2(`[plugin:${id}] activation failed`,err),e.error=String(err?.message??err),!1});if(!ok||!e.enabled)return await scope.dispose(),force(),ok&&!0;return e.scope=scope,e.error=void 0,force(),!0},deactivate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!1,write)persist2(id,!1);let scope=e.scope;if(e.scope=void 0,scope)await scope.dispose();return force(),!0},started=import_react146.useRef(!1);import_react146.useEffect(()=>{if(started.current)return;started.current=!0;let on=enabledMap();for(let p of list3)entries2.current.set(p.id,{plugin:p,enabled:on[p.id]??p.enabled??!0});return(async()=>{for(let[id,e]of entries2.current)if(e.enabled)await activate(id,!1)})(),()=>{for(let[,e]of entries2.current)e.scope?.dispose();entries2.current.clear(),routes.clear(),reg.clear()}},[]);let value2=import_react146.useMemo(()=>({Slot:Slot2,routes:[...routes.values()],bind:(nav,current2)=>{navRef.current=nav,curRef.current=current2},status:()=>[...entries2.current.values()].map((e)=>({id:e.plugin.id,enabled:e.enabled,active:!!e.scope,error:e.error})),has:(slot2)=>reg.resolveEntries(slot2).length>0,activate:(id)=>activate(id),deactivate:(id)=>deactivate(id)}),[Slot2,routes,rev3,gen]);return $jsx(Ctx7.Provider,{value:value2,children:props.children})}var usePlugins=makeUse(Ctx7,"usePlugins");function useBridge(o){let gw=useGateway(),renderer=useRenderer(),plugins=usePlugins(),state3=import_react148.useRef(o);state3.current=o,import_react148.useEffect(()=>{if(!enabled2)return;setBridge({tab:()=>state3.current.tab,setTab:o.setTab,send:async(msg)=>{let s=state3.current;if(!s.ready)throw Error("not connected");if(s.streaming)throw Error("already streaming");s.setTab(CHAT_TAB);try{await gw.request("prompt.submit",{text:msg}),s.dispatch({kind:"user",text:msg})}catch(err){let text5=err instanceof Error?err.message:String(err);throw s.dispatch({kind:"system",text:`Failed to send: ${text5}`}),err}},ready:()=>state3.current.ready,streaming:()=>state3.current.streaming,messages:()=>state3.current.messages.length,session:()=>state3.current.sid,input:()=>state3.current.composer.current?.value()??"",setInput:(v2)=>state3.current.composer.current?.set(v2),focusRegion:()=>state3.current.focusRegion,setFocusRegion:o.setFocusRegion,renderer:()=>renderer,logs:(n)=>gw.tail(n),plugin:(id,on)=>on?plugins.activate(id):plugins.deactivate(id),push:(ev)=>gw.emit("event",ev)})},[gw,renderer,plugins])}var import_react156=__toESM(require_react_production(),1);var winDrive=(s,off=0)=>s.length>=off+3&&/[A-Za-z]/.test(s[off])&&s[off+1]===":"&&(s[off+2]==="\\"||s[off+2]==="/");function looksLikePath(s){let t2=s.trim();if(!t2||t2.includes(`
4190
+ `)}var import_react146=__toESM(require_react_production(),1);function select(dialog,opts){return new Promise((res)=>{let settled=!1,done2=(v2)=>{if(settled)return;settled=!0,res(v2),dialog.clear()};dialog.replace($jsx(DialogSelect,{title:opts.title,options:opts.options,placeholder:opts.placeholder,onSelect:(o)=>done2(o)}),()=>done2(null))})}function locate3(routes,name){let lower=name.toLowerCase(),hit2=TAB_SLASH[lower];if(hit2)return hit2;let i=[...routes.keys()].findIndex((n)=>n.toLowerCase()===lower);if(i<0)return;return{tab:TABS.length+i,sub:0}}function createApi(input){return{renderer:input.renderer,theme:{get current(){return input.theme.current.theme},get name(){return input.theme.current.name},get mode(){return input.theme.current.mode},set:(name)=>input.theme.current.set(name),setMode:(mode2)=>input.theme.current.setMode(mode2),has:(name)=>input.theme.current.has(name)},get keys(){return input.keys.current},ui:{dialog:input.dialog,toast:(o)=>input.toast.show({variant:o.variant??"info",title:o.title,message:o.message}),confirm:(o)=>openConfirm(input.dialog,o),prompt:(o)=>openTextPrompt(input.dialog,o),alert:(title,body2)=>openAlert(input.dialog,title,body2),select:(o)=>select(input.dialog,o)},kv:{get:(key5,fallback2)=>{return get2("plugin")?.[key5]??fallback2},set:(key5,value2)=>{let bag=get2("plugin")??{};set("plugin",{...bag,[key5]:value2})}},get client(){return input.gw.current},event:{on:(fn)=>{let c=input.gw.current,h2=(ev)=>fn(ev);return c.on("event",h2),()=>c.off("event",h2)}},route:{register:(defs)=>{for(let d2 of defs)input.routes.set(d2.name,d2);return input.bump(),()=>{for(let d2 of defs)input.routes.delete(d2.name);input.bump()}},navigate:(name,sub2)=>{let at=locate3(input.routes,name);if(!at)return;input.nav.current?.(at.tab,sub2??at.sub)},get current(){return input.cur.current?.()}},command:{register:(cmds)=>input.cmd.register(cmds)},slots:{register(){throw Error("slots.register is only available inside a plugin's tui() factory")}},eikon:{rasterizer:{register:(r)=>register(r)}},lifecycle:{signal:new AbortController().signal,onDispose:()=>()=>{}}}}function createScope(id,fail2){let ctrl=new AbortController,list3=[],done2=!1,onDispose=(fn)=>{if(done2)return()=>{};let key5=Symbol();return list3.push({key:key5,fn}),()=>{list3=list3.filter((x2)=>x2.key!==key5)}},track=(fn)=>{if(!fn)return()=>{};let ran=!1,drop2=()=>{},wrapped=()=>{if(ran)return;return ran=!0,drop2(),fn()};return drop2=onDispose(wrapped),wrapped},race=(fn,left)=>new Promise((res)=>{let t2=setTimeout(()=>res("timeout"),left);Promise.resolve().then(fn).then(()=>{clearTimeout(t2),res("ok")}).catch((e)=>{clearTimeout(t2),res(e instanceof Error?e:Error(String(e)))})}),dispose=async()=>{if(done2)return;done2=!0,ctrl.abort();let queue=[...list3].reverse();list3=[];let until2=Date.now()+5000;for(let item of queue){let left=until2-Date.now();if(left<=0){fail2(`[plugin:${id}] dispose budget exhausted`);return}let out=await race(item.fn,left);if(out==="ok")continue;if(out==="timeout"){fail2(`[plugin:${id}] dispose timed out`);return}fail2(`[plugin:${id}] dispose threw`,out)}};return{lifecycle:{signal:ctrl.signal,onDispose},track,dispose}}var import_react143=__toESM(require_react_production(),1);var fmt4=(d2)=>[d2.getHours(),d2.getMinutes(),d2.getSeconds()].map((n)=>String(n).padStart(2,"0")).join(":");function Clock(props){let[now,set3]=import_react143.useState(()=>new Date);return import_react143.useEffect(()=>{let t2=setInterval(()=>set3(new Date),1000);return()=>clearInterval(t2)},[]),$jsx("text",{fg:props.api.theme.current.textMuted,wrapMode:"none",children:fmt4(now)})}var plugin={id:"demo.clock",enabled:!1,tui(api){api.slots.register({order:100,slots:{app_bottom:()=>$jsx(Clock,{api})}})}},clock_default=plugin;var import_react144=__toESM(require_react_production(),1);import{readdirSync as readdirSync12,statSync as statSync11}from"fs";import{join as join27,basename as basename15}from"path";import{homedir as homedir10}from"os";var PREVIEW_MAX=200000,read4=(dir2)=>{return(dir2==="/"?[]:[{name:"..",dir:!0}]).concat(readdirSync12(dir2,{withFileTypes:!0}).filter((d2)=>!d2.name.startsWith(".")).sort((a,b2)=>a.isDirectory()===b2.isDirectory()?a.name.localeCompare(b2.name):a.isDirectory()?-1:1).map((d2)=>({name:d2.name,dir:d2.isDirectory()})))},isMd=(name)=>/\.(md|markdown|mdx)$/i.test(name);function Files(props){let api=props.api,theme=api.theme.current,[dir2,setDir]=import_react144.useState(()=>homedir10()),[sel,setSel]=import_react144.useState(0),[preview2,setPreview]=import_react144.useState(""),listing=import_react144.useMemo(()=>{try{return{rows:read4(dir2),error:""}}catch(e){return{rows:[],error:e instanceof Error?e.message:String(e)}}},[dir2]),rows3=listing.rows;import_react144.useEffect(()=>{setSel((s)=>Math.min(s,Math.max(0,rows3.length-1)))},[rows3.length]);let active=rows3[sel];import_react144.useEffect(()=>{if(!active||active.dir){setPreview("");return}let path4=join27(dir2,active.name),cancel=!1;return(async()=>{let st=statSync11(path4);if(st.size>PREVIEW_MAX){if(!cancel)setPreview(`(file too large \u2014 ${st.size} bytes)`);return}let text5=await Bun.file(path4).text();if(!cancel)setPreview(text5)})().catch((e)=>{if(!cancel)setPreview(`(read error: ${e})`)}),()=>{cancel=!0}},[dir2,active?.name,active?.dir]);let enter=()=>{if(!active)return;if(active.name===".."){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}if(active.dir)setDir((d2)=>join27(d2,active.name)),setSel(0)};return useKeyboard((key5)=>{if(!props.focused||api.ui.dialog.open())return;if(key5.name==="left"){setDir((d2)=>d2==="/"?"/":join27(d2,"..")),setSel(0);return}handleListKey(api.keys,key5,{count:rows3.length,setSel,onActivate:enter})}),$jsxs("box",{flexGrow:1,flexDirection:"column",children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:dir2})}),$jsxs("box",{flexGrow:1,flexDirection:"row",children:[$jsxs("box",{width:32,flexShrink:0,flexDirection:"column",border:!0,borderColor:theme.border,children:[rows3.map((e,i)=>$jsx("box",{height:1,paddingX:1,backgroundColor:i===sel?theme.backgroundElement:void 0,children:$jsx("text",{fg:i===sel?theme.selectedListItemText:e.dir?theme.accent:theme.text,wrapMode:"none",children:(e.dir?"\u25B8 ":" ")+e.name})},e.name)),listing.error?$jsx("box",{height:1,paddingX:1,children:$jsx("text",{fg:theme.error,wrapMode:"none",children:listing.error})}):null]}),$jsx("box",{flexGrow:1,flexDirection:"column",border:!0,borderColor:theme.border,children:active&&!active.dir?$jsxs($Fragment,{children:[$jsx("box",{height:1,flexShrink:0,paddingX:1,children:$jsxs("text",{fg:theme.textMuted,wrapMode:"none",children:[basename15(active.name),isMd(active.name)?" \xB7 markdown":""]})}),$jsx("scrollbox",{scrollY:!0,flexGrow:1,children:$jsx("text",{fg:theme.text,wrapMode:"word",children:preview2})})]}):$jsx("box",{paddingX:1,children:$jsx("text",{fg:theme.textMuted,children:"Select a file to preview."})})})]})]})}var plugin2={id:"demo.files",enabled:!1,tui(api){api.route.register([{name:"Files",description:"File browser",render:({focused})=>$jsx(Files,{api,focused})}]),api.command.register([{title:"Files: open browser",value:"plugin.files.open",category:"Plugin",onSelect:()=>api.route.navigate("Files")}])}},files_default=plugin2;var INTERNAL=[clock_default,files_default];var KV_ENABLED="enabled",Ctx7=import_react146.createContext(null);function fail2(msg,err){let tail=err instanceof Error?`: ${err.message}`:err!==void 0?`: ${String(err)}`:"";console.error(msg+tail)}var RouteBody=(props)=>props.render(props.ctx);class RouteBoundary extends import_react146.Component{state={};static getDerivedStateFromError(error){return{error}}componentDidCatch(error,_info){fail2(`[plugin:${this.props.id}] render error in route "${this.props.name}"`,error)}render(){if(this.state.error)return $jsx("text",{children:`Plugin ${this.props.id} route ${this.props.name}: ${this.state.error.message}`});return this.props.children}}function enabledMap(){let v2=get2("plugin")?.[KV_ENABLED];return v2&&typeof v2==="object"?v2:{}}function persist2(id,on){let bag=get2("plugin")??{},map={...enabledMap(),[id]:on};set("plugin",{...bag,[KV_ENABLED]:map})}function scoped(base3,reg,id,scope){let n=0;return{...base3,slots:{register(p){let sid2=n++?`${id}:${n}`:id;return scope.track(reg.register({...p,id:sid2}))}},route:{register:(defs)=>scope.track(base3.route.register(defs.map((def2)=>({...def2,render:(ctx2)=>$jsx(RouteBoundary,{id,name:def2.name,children:$jsx(RouteBody,{render:def2.render,ctx:ctx2})})})))),navigate:base3.route.navigate,get current(){return base3.route.current}},event:{on:(fn)=>scope.track(base3.event.on(fn))},command:{register:(cmds)=>scope.track(base3.command.register(cmds))},eikon:{rasterizer:{register:(r)=>scope.track(base3.eikon.rasterizer.register(r))}},kv:{get:(key5,fb)=>base3.kv.get(`${id}.${key5}`,fb),set:(key5,v2)=>base3.kv.set(`${id}.${key5}`,v2)},lifecycle:scope.lifecycle}}var CELLS=new WeakMap;function ctxFor(renderer,themeRef){let hit2=CELLS.get(renderer);if(hit2)return hit2.themeRef=themeRef,hit2.ctx;let cell={themeRef,ctx:{}};return Object.defineProperty(cell.ctx,"theme",{get:()=>cell.themeRef.current.theme,enumerable:!0}),CELLS.set(renderer,cell),cell.ctx}function PluginProvider(props){let list3=props.plugins??INTERNAL,renderer=useRenderer(),themeCtx=useTheme(),keys=useKeys(),dialog=useDialog(),toast=useToast(),cmd=useCommand(),gw=useGateway(),themeRef=import_react146.useRef(themeCtx);themeRef.current=themeCtx;let keysRef=import_react146.useRef(keys);keysRef.current=keys;let gwRef=import_react146.useRef(gw);gwRef.current=gw;let navRef=import_react146.useRef(null),curRef=import_react146.useRef(null),routes=import_react146.useRef(new Map).current,[rev3,bump2]=import_react146.useReducer((x2)=>x2+1,0),reg=import_react146.useMemo(()=>createReactSlotRegistry(renderer,ctxFor(renderer,themeRef),{onPluginError:(e)=>fail2(`[plugin:${e.pluginId}] ${e.phase} error in slot "${e.slot}"`,e.error)}),[renderer]),Slot2=import_react146.useMemo(()=>createSlot(reg),[reg]),api=import_react146.useMemo(()=>createApi({renderer,theme:themeRef,keys:keysRef,dialog,toast,gw:gwRef,cmd,routes,bump:bump2,nav:navRef,cur:curRef}),[renderer,dialog,toast,cmd,routes]),entries2=import_react146.useRef(new Map),[gen,force]=import_react146.useReducer((x2)=>x2+1,0),activate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!0,write)persist2(id,!0);if(e.scope)return!0;let scope=createScope(id,fail2),ok=await Promise.resolve().then(()=>e.plugin.tui(scoped(api,reg,id,scope))).then(()=>!0).catch((err)=>{return fail2(`[plugin:${id}] activation failed`,err),e.error=String(err?.message??err),!1});if(!ok||!e.enabled)return await scope.dispose(),force(),ok&&!0;return e.scope=scope,e.error=void 0,force(),!0},deactivate=async(id,write=!0)=>{let e=entries2.current.get(id);if(!e)return!1;if(e.enabled=!1,write)persist2(id,!1);let scope=e.scope;if(e.scope=void 0,scope)await scope.dispose();return force(),!0},started=import_react146.useRef(!1);import_react146.useEffect(()=>{if(started.current)return;started.current=!0;let on=enabledMap();for(let p of list3)entries2.current.set(p.id,{plugin:p,enabled:on[p.id]??p.enabled??!0});return(async()=>{for(let[id,e]of entries2.current)if(e.enabled)await activate(id,!1)})(),()=>{for(let[,e]of entries2.current)e.scope?.dispose();entries2.current.clear(),routes.clear(),reg.clear()}},[]);let value2=import_react146.useMemo(()=>({Slot:Slot2,routes:[...routes.values()],bind:(nav,current2)=>{navRef.current=nav,curRef.current=current2},status:()=>[...entries2.current.values()].map((e)=>({id:e.plugin.id,enabled:e.enabled,active:!!e.scope,error:e.error})),has:(slot2)=>reg.resolveEntries(slot2).length>0,activate:(id)=>activate(id),deactivate:(id)=>deactivate(id)}),[Slot2,routes,rev3,gen]);return $jsx(Ctx7.Provider,{value:value2,children:props.children})}var usePlugins=makeUse(Ctx7,"usePlugins");function useBridge(o){let gw=useGateway(),renderer=useRenderer(),plugins=usePlugins(),state3=import_react148.useRef(o);state3.current=o,import_react148.useEffect(()=>{if(!enabled2)return;setBridge({tab:()=>state3.current.tab,setTab:o.setTab,send:async(msg)=>{let s=state3.current;if(!s.ready)throw Error("not connected");if(s.streaming)throw Error("already streaming");s.setTab(CHAT_TAB);try{await gw.request("prompt.submit",{text:msg}),s.dispatch({kind:"user",text:msg})}catch(err){let text5=err instanceof Error?err.message:String(err);throw s.dispatch({kind:"system",text:`Failed to send: ${text5}`}),err}},ready:()=>state3.current.ready,streaming:()=>state3.current.streaming,messages:()=>state3.current.messages.length,session:()=>state3.current.sid,input:()=>state3.current.composer.current?.value()??"",setInput:(v2)=>state3.current.composer.current?.set(v2),focusRegion:()=>state3.current.focusRegion,setFocusRegion:o.setFocusRegion,renderer:()=>renderer,logs:(n)=>gw.tail(n),plugin:(id,on)=>on?plugins.activate(id):plugins.deactivate(id),push:(ev)=>gw.emit("event",ev)})},[gw,renderer,plugins])}var import_react156=__toESM(require_react_production(),1);var winDrive=(s,off=0)=>s.length>=off+3&&/[A-Za-z]/.test(s[off])&&s[off+1]===":"&&(s[off+2]==="\\"||s[off+2]==="/");function looksLikePath(s){let t2=s.trim();if(!t2||t2.includes(`
4191
4191
  `))return!1;if(t2.startsWith("file://"))return!0;if(t2.startsWith("/")||t2.startsWith("~")||t2.startsWith("./")||t2.startsWith("../"))return!0;if(winDrive(t2))return!0;let q5=t2[0];if(q5==='"'||q5==="'"){let inner=t2[1];if(inner==="/"||inner==="~")return!0;if(winDrive(t2,1))return!0}return!1}var import_react150=__toESM(require_react_production(),1);var SEP=new Set(["-","_","/"," ","."]);function boundary2(hay,i){if(i===0)return!0;let prev=hay[i-1];if(SEP.has(prev))return!0;if(prev===prev.toLowerCase()&&hay[i]!==hay[i].toLowerCase())return!0;return!1}function score(needle,hay){if(!needle)return 0;let n=needle.toLowerCase(),h2=hay.toLowerCase(),pts=0,from2=0,prev=-2;for(let i=0;i<n.length;i++){let at=h2.indexOf(n[i],from2);if(at<0)return 0;if(pts+=1,at===0)pts+=8;if(at===prev+1)pts+=5;if(at!==prev+1&&boundary2(hay,at))pts+=4;pts-=(at-(prev<0?0:prev+1))*0.1,prev=at,from2=at+1}if(h2.startsWith(n))pts+=100;return pts-hay.length*0.01}function best(q5,cmd){return cmd.aliases.reduce((m2,a)=>Math.max(m2,score(q5,a)),score(q5,cmd.name))}function rank(list3,q5){if(!q5)return[...list3];return list3.map((cmd)=>({cmd,s:best(q5,cmd)})).filter((r)=>r.s>0).sort((a,b2)=>b2.s-a.s).map((r)=>r.cmd)}function boundary3(ch){return ch===void 0||/\s/.test(ch)||"({\"'`".includes(ch)}function tag2(s){return s?`${s.start}:${s.end}:${s.text}`:""}function exact(spot,cmds){let m2=spot.query.match(/^(\S+)(?:\s+(\S.*))?$/);if(!m2)return!1;return cmds.some((c)=>c.name===m2[1]||c.aliases.includes(m2[1]))&&(m2[2]!==void 0||spot.query===m2[1])}function slashTokenAt(input,caret=input.length){let off=Math.max(0,Math.min(caret,input.length));if(/^\/[A-Za-z0-9_-]*$/.test(input))return{text:input,query:input.slice(1),start:0,end:input.length,whole:!0};let line4=input.lastIndexOf(`
4192
4192
  `,Math.max(0,off-1))+1,slash3=input.lastIndexOf("/",off);if(slash3<line4)return null;if(!boundary3(input[slash3-1]))return null;if(input[slash3-1]==="("&&input[slash3-2]==="]")return null;if(input[slash3-1]==="[")return null;let query2=input.slice(slash3+1).match(/^[A-Za-z0-9_-]*/)?.[0]??"",end=slash3+1+query2.length;if(input[end]==="/")return null;if(slash3===line4&&off>end&&/^\s+[^\n]*$/.test(input.slice(end,off)))return{text:input.slice(slash3,off),query:input.slice(slash3+1,off),start:slash3,end:off,whole:!0};if(off>end||off<slash3)return null;if(!query2&&input[slash3+1]==="/")return null;return{text:input.slice(slash3,end),query:query2,start:slash3,end,whole:!1}}function replaceSlashToken(input,spot,cmd){let text5=`/${cmd.name}${cmd.name.includes(" ")?" ":""}`;return input.slice(0,spot.start)+text5+input.slice(spot.end)}function useSlashPopover(input,cmds,caret=input.length){let[cursor,setCursor]=import_react150.useState(0),[dismissed,setDismissed]=import_react150.useState(null),spot=import_react150.useMemo(()=>slashTokenAt(input,caret),[input,caret]),key5=tag2(spot),popover=import_react150.useMemo(()=>{if(!spot||dismissed===key5)return null;if(spot.whole&&exact(spot,cmds))return null;let subs3=matchSub(cmds,spot.text);if(subs3)return subs3;return rank(cmds,spot.query)},[spot,cmds,dismissed,key5]),active=popover?Math.max(0,Math.min(cursor,popover.length-1)):0;import_react150.useEffect(()=>{setCursor((c)=>c===0?c:0),setDismissed((d2)=>d2&&d2!==key5?null:d2)},[key5]);let ghost=import_react150.useMemo(()=>{if(!popover||popover.length===0)return"";let hit2=popover[active];if(!hit2||hit2.name.includes(" "))return"";if(!spot||!/^\/\S*$/.test(spot.text))return"";let typed=spot.query;if(typed.length<2)return"";if(!hit2.name.toLowerCase().startsWith(typed.toLowerCase()))return"";return hit2.name.slice(typed.length)},[spot,popover,active]),open3=popover!==null&&popover.length>0;return{popover,cursor:active,setCursor,ghost,open:open3,spot,dismiss:(next2,off=next2?.length??caret)=>setDismissed(tag2(next2===void 0?spot:slashTokenAt(next2,off)))}}var import_react151=__toESM(require_react_production(),1);var exports_frecency={};__export(exports_frecency,{score:()=>score2,frecency:()=>exports_frecency,bump:()=>bump2,_reset:()=>_reset});import{join as join28}from"path";import{existsSync as existsSync32,readFileSync as readFileSync23,writeFileSync as writeFileSync10,appendFileSync,mkdirSync as mkdirSync8}from"fs";var MAX2=1000,file3=()=>join28(configDir(),"frecency.jsonl"),data2=null;function load6(){if(!existsSync32(file3()))return{};let rows3=readFileSync23(file3(),"utf-8").split(`
4193
4193
  `).filter(Boolean).map((l)=>{try{return JSON.parse(l)}catch{return null}}).filter((e)=>e!==null),latest3={};for(let e of rows3)latest3[e.path]=e;let kept=Object.values(latest3).sort((a,b2)=>b2.at-a.at).slice(0,MAX2);if(kept.length<rows3.length)mkdirSync8(configDir(),{recursive:!0}),writeFileSync10(file3(),kept.map((e)=>JSON.stringify(e)).join(`
@@ -4207,10 +4207,10 @@ ${body2}`:head}function formatProcessNotification(text5){let body2=text5.replace
4207
4207
  `)&&t2.cursorOffset!==0)return t2.cursorOffset=0,!0;return hist.up(),!0},historyDown:()=>{let t2=ta.current;if(!t2||modeRef.current==="shell")return!1;let buf2=live.current.input;if(buf2.indexOf(`
4208
4208
  `,t2.cursorOffset)>=0)return!1;if(buf2.includes(`
4209
4209
  `)&&t2.cursorOffset!==buf2.length)return t2.cursorOffset=buf2.length,!0;return hist.down(),!0}}),[hist.up,hist.down,pop3.setCursor,write]);let sidsRef=import_react156.useRef(sids);sidsRef.current=sids;let taRef=import_react156.useCallback((r)=>{if(ta.current=r,r&&!buf.current)buf.current=new PartsBuffer(r,sidsRef.current);if(!r)buf.current=null},[]),label3=!props.ready?"Connecting...":props.starting?props.status||"Starting agent...":props.streaming?props.status||"Generating...":"Ready",dot=props.ready?props.streaming?theme.warning:theme.success:theme.error,resume=resumeHint(props.subagents,props.streaming),rows3=Math.min(MAX_ROWS,Math.max(1,input.split(`
4210
- `).length)),all2=props.attachments??[],previews=all2.filter((a)=>a.path&&classify(a.path)==="img").slice(0,MAX_PREVIEWS),chips=all2.filter((a)=>!previews.includes(a)).slice(0,MAX_PREVIEWS),shown=new Set([...previews,...chips]),attRows=all2.length>0?previews.length>0?2:1:0,lift=rows3+attRows+3,more=all2.filter((a)=>!shown.has(a)).length,bits=[props.hidden?.profile,props.hidden?.title,props.hidden?.place,props.hidden?.context].filter(Boolean);return $jsxs("box",{flexDirection:"column",position:"relative",children:[props.focused&&pop3.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(SlashPopover,{commands:pop3.popover,cursor:pop3.cursor,onCursor:pop3.setCursor,onSelect:select2})}):props.focused&&at.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(AtRefPopover,{items:at.items,cursor:at.cursor,onCursor:at.setCursor,onSelect:atAccept})}):props.focused&&comp.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(AtRefPopover,{items:comp.items,cursor:comp.cursor,onCursor:comp.setCursor,onSelect:(idx2)=>{let it=comp.items[idx2];if(it?.text)write(acceptCompletion(input,it,comp.replaceFrom,comp.replaceTo))}})}):null,(props.queue?.length??0)>0?$jsx("box",{flexDirection:"column",paddingX:1,paddingBottom:1,children:props.queue.map((q5,i)=>$jsx("box",{height:1,onMouseDown:()=>props.onDequeue?.(i),children:$jsxs("text",{children:[$jsxs("span",{fg:theme.borderSubtle,children:[i===0?"\u256D":"\u2502"," "]}),$jsxs("span",{fg:theme.textMuted,children:["\u23F8 ",i+1,". ",trunc5(q5,60)]})]})},i))}):null,$jsxs("box",{border:!0,borderStyle:"single",borderColor:mode2==="shell"?theme.primary:props.focused?theme.borderActive:theme.border,flexDirection:"column",position:"relative",children:[previews.length>0?$jsx("box",{flexDirection:"column",paddingX:1,maxHeight:MAX_PREVIEWS,overflow:"hidden",children:previews.map((a)=>$jsx(ChafaImage,{path:a.path,width:60,bare:!0},`p-${a.path}`))}):null,chips.length>0?$jsxs("box",{flexDirection:"row",flexWrap:"wrap",gap:1,paddingX:1,paddingTop:previews.length>0?0:1,paddingBottom:1,children:[chips.map((a,i)=>{if(a.path){let kind2=classify(a.path);return $jsxs("box",{flexDirection:"row",height:1,children:[$jsx(MediaChip,{path:a.path,bare:kind2==="img"}),kind2!=="img"&&a.token_estimate?$jsxs("text",{fg:theme.textMuted,children:[" ~",fmt5(a.token_estimate),"t"]}):null]},a.path)}return $jsxs("text",{children:[$jsx("span",{bg:theme.secondary,fg:theme.background,children:" file "}),$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[" ",a.name??`file ${i+1}`," "]})]},a.name??i)}),more>0?$jsxs("text",{fg:theme.textMuted,children:["+",more]}):null]}):null,$jsxs("box",{flexDirection:"row",children:[$jsx("box",{width:1,children:$jsx("text",{fg:theme.primary,children:mode2==="shell"?"$":">"})}),$jsx("box",{width:1}),$jsx("textarea",{ref:taRef,syntaxStyle,onContentChange:()=>{let t2=ta.current;setInput(t2?.plainText??""),setCaret(t2?.cursorOffset??0)},onCursorChange:()=>{if(!live.current.input.includes("@")&&!live.current.input.includes("/"))return;let off=ta.current?.cursorOffset??0;setCaret((c)=>c===off?c:off)},onSubmit:submit4,onPaste:paste,keyBindings:bindings,wrapMode:"word",minHeight:1,maxHeight:MAX_ROWS,placeholder:mode2==="shell"?"Run a shell command (30s cap, cwd) \u2014 esc or \u232B to exit":props.streaming?"Type to queue... (Enter queues, click chip to edit)":"Message Hermes... (/ for commands, Shift+Enter for newline)",focused:props.focused,textColor:theme.text,focusedTextColor:theme.text,placeholderColor:theme.textMuted,cursorColor:theme.text,backgroundColor:"transparent",focusedBackgroundColor:"transparent",flexGrow:1})]}),pop3.ghost&&props.focused&&rows3===1&&pop3.spot?.whole?$jsx("box",{position:"absolute",top:attRows,left:2+input.length,height:1,children:$jsx("text",{fg:theme.textMuted,children:pop3.ghost})}):null]}),$jsxs("box",{height:1,flexDirection:"row",paddingX:1,children:[$jsxs("text",{children:[props.streaming?$jsx(SpinGlyph,{fg:dot}):$jsx("span",{fg:dot,children:"\u25CF"}),$jsxs("span",{fg:theme.textMuted,children:[" ",mode2==="shell"?"Shell":label3]}),mode2==="shell"?$jsx("span",{fg:theme.textMuted,children:" esc exit shell mode"}):props.starting&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to cancel"}):props.starting?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 cancel"}):props.streaming&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to interrupt"}):props.streaming?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 interrupt"}):null]}),$jsx("box",{flexGrow:1}),props.streaming&&(props.queue?.length??0)>0?$jsxs("text",{fg:theme.textMuted,children:[keys.print("queue.flush")," to send queued now "]}):null,bg2.count>0?$jsxs("text",{fg:theme.text,children:["\u25B6 ",bg2.count," "]}):null,resume?$jsxs("text",{fg:theme.textMuted,children:[resume," "]}):null,bits.length>0?$jsxs("text",{fg:theme.textMuted,children:[trunc5(bits.join(" \xB7 "),56)," "]}):null,props.model?$jsx("text",{fg:theme.textMuted,children:props.model}):null]})]})}));var import_react157=__toESM(require_react_production(),1);init_sessions_db();var normalize3=(sid2)=>sid2.trim().replace(/\.json$/i,"").replace(/^session_(?=\d{8}_)/,"");function useSession(){let gw=useGateway(),inflightMessages=(inflight)=>{let user2=String(inflight?.user??"").trim(),assistant2=String(inflight?.assistant??""),messages=[];if(user2)messages.push(...transcriptToMessages([{role:"user",text:user2}]));if(assistant2||inflight?.streaming)messages.push(...transcriptToMessages([{role:"assistant",text:assistant2}]));return messages},resume=import_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.resume",{session_id:target2}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.resumed??target2);let messages=res.messages?.length?transcriptToMessages(res.messages):[];return{id,messages,info:res.info}},[gw]),create=import_react157.useCallback(async()=>{let res=await gw.request("session.create",{});return gw.setSession(res.session_id),{id:res.session_id,info:res.info}},[gw]),activate=import_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.activate",{session_id:target2}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.session_key??id);let history=res.messages?.length?transcriptToMessages(res.messages):[],running2=Boolean(res.running||res.status==="working"||res.status==="waiting");return{id,info:res.info,messages:[...history,...inflightMessages(res.inflight)],running:running2,startedAt:res.started_at?res.started_at*1000:void 0,status:res.status}},[gw]),busy2=import_react157.useCallback(async()=>{try{return(await gw.request("agents.list")).processes?.some((p)=>p.status==="running")??!1}catch{return!0}},[gw]),close2=import_react157.useCallback(async(sid2,opts)=>{if(!sid2)return!1;if(opts?.preserveBackground&&await busy2())return!1;try{return await gw.request("session.close",{session_id:sid2}),!0}catch{return!1}},[gw,busy2]),boot2=import_react157.useCallback(async(launch)=>{let fresh2=async(note)=>({...await create(),messages:[],note});if(launch.mode==="resume"){let target2=launch.sid??exports_sessions_db.lastReal()?.id;if(!target2)return fresh2("no prior session to resume \u2014 starting fresh");try{return await resume(target2)}catch(e){let msg=e instanceof Error?e.message:String(e);return fresh2(`resume ${target2} failed: ${msg} \u2014 starting fresh`)}}let last4=get2("lastSessionId"),row4=last4?exports_sessions_db.byId(last4):null;if(row4?.message_count===0&&row4.parent_session_id==null)try{return await resume(row4.id)}catch{}return fresh2()},[create,resume]),interrupt=import_react157.useCallback(async()=>{await gw.request("session.interrupt")},[gw]),branch2=import_react157.useCallback(async(name)=>{return(await gw.request("session.branch",name?{name}:{})).session_id??null},[gw]),compress=import_react157.useCallback(async(arg="")=>{let raw2=arg.trim(),params=raw2?{raw_args:raw2,focus_topic:raw2}:{};return gw.request("session.compress",params)},[gw]),undo=import_react157.useCallback(async()=>{await gw.request("session.undo")},[gw]);return import_react157.useMemo(()=>({boot:boot2,create,resume,activate,close:close2,interrupt,branch:branch2,compress,undo}),[boot2,create,resume,activate,close2,interrupt,branch2,compress,undo])}init_sessions_db();init_hermes_analytics();function rehome(newHome){process.env.HERMES_HOME=newHome,setHome2(newHome),setHome(newHome),cache3.clear(),resetKanban(),close(),exports_preferences.reload(),home3.reset()}var import_react158=__toESM(require_react_production(),1);var Countdown=(p)=>{let theme=useTheme().theme,[n,setN]=import_react158.useState(p.seconds);import_react158.useEffect(()=>{if(n<=0){p.onFire();return}let t2=setTimeout(()=>setN((v2)=>v2-1),1000);return()=>clearTimeout(t2)},[n,p.onFire]),useKeyboard(()=>p.onCancel());let bar3="\u2588".repeat(n)+"\u2591".repeat(Math.max(0,p.seconds-n));return $jsxs("box",{flexDirection:"column",width:58,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.warning,children:[bar3," ",n,"s"]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.action})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"press any key to cancel"})})]})};function openCountdown(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Countdown,{...opts,onFire:()=>{dialog.clear(),resolve4(!0)},onCancel:()=>{dialog.clear(),resolve4(!1)}}),()=>resolve4(!1))})}var SECONDS=10,SUSPEND=process.platform==="darwin"?"pmset sleepnow":"systemctl suspend",run=(cmd)=>Bun.spawn(["sh","-c",cmd],{stdout:"ignore",stderr:"ignore"}),fired=new Map;function makeGoalHook(dialog,toast){let act=(goal,done2,total)=>{let pref=(exports_preferences.get("onGoalDone")??"toast").trim(),head=goal.length>60?goal.slice(0,57)+"\u2026":goal,n=total&&total>0?` ${done2}/${total} items`:"";if(toast.show({variant:"success",title:"Goal complete",message:head+n,duration:8000}),pref==="toast")return;let cmd=pref==="suspend"?SUSPEND:pref;openCountdown(dialog,{title:"Goal complete \u2014 "+(pref==="suspend"?"suspending":"running hook"),body:head,action:`\u2192 ${cmd}`,seconds:SECONDS}).then((ok)=>{if(ok)run(cmd)})};return{check:(sid2)=>{if(!sid2)return;io.goalState(sid2).then((s)=>{if(!s||s.status!=="done")return;if(fired.get(sid2)===s.goal)return;fired.set(sid2,s.goal);let list3=s.checklist??[],done2=list3.filter((i)=>i.status==="completed"||i.status==="impossible").length;act(s.goal,done2,list3.length)}).catch(()=>{})}}}var import_react160=__toESM(require_react_production(),1);function useVoice(gw,sys){let[enabled3,setEnabled]=import_react160.useState(!1),[recording,setRecording]=import_react160.useState(!1),[processing,setProcessing]=import_react160.useState(!1),[recordKeyRaw,setRecordKeyRaw]=import_react160.useState(),[tts,setTts]=import_react160.useState(!1),[onTranscript,setTranscript]=import_react160.useState(null),pending3=import_react160.useRef(0),recordGen=import_react160.useRef(0),toggleGen=import_react160.useRef(0),setOnTranscript=import_react160.useCallback((fn)=>setTranscript(fn?()=>fn:null),[]),reset4=import_react160.useCallback(()=>{toggleGen.current++,recordGen.current++,pending3.current=0,setEnabled(!1),setRecording(!1),setProcessing(!1),setTts(!1)},[]),recordKey=import_react160.useMemo(()=>parseVoiceRecordKey(recordKeyRaw),[recordKeyRaw]),keyLabel=import_react160.useMemo(()=>formatVoiceRecordKey(recordKey),[recordKey]),state3=import_react160.useMemo(()=>({enabled:enabled3,recording,processing,recordKey,tts}),[enabled3,recording,processing,recordKey,tts]),toggle=import_react160.useCallback(async(action,sid2)=>{let current2=++toggleGen.current;try{let r=await gw("voice.toggle",{action,session_id:sid2});if(toggleGen.current!==current2)return;if(r.enabled!==void 0){if(setEnabled(r.enabled),!r.enabled)recordGen.current++,setRecording(!1),setProcessing(!1)}if(r.tts!==void 0)setTts(r.tts);if(r.record_key)setRecordKeyRaw(r.record_key);let label3=formatVoiceRecordKey(parseVoiceRecordKey(r.record_key)),ttsMsg=r.tts?" \xB7 tts on":"",details2=action==="status"&&r.details?.trim()?` \xB7 ${r.details.trim()}`:"";sys(`voice ${r.enabled?"on":"off"}${ttsMsg} [${label3}]${details2}`)}catch(e){if(toggleGen.current!==current2)return;sys(`voice: ${e instanceof Error?e.message:"gateway error"}`)}},[gw,sys]),record2=import_react160.useCallback(async(sid2)=>{if(!enabled3){sys("voice: mode is off \u2014 enable with /voice on");return}if(pending3.current)return;let current2=++recordGen.current;pending3.current=current2;let starting=!recording,action=starting?"start":"stop";if(starting)setRecording(!0);else setRecording(!1),setProcessing(!1);try{let r=await gw("voice.record",{action,session_id:sid2});if(recordGen.current!==current2)return;if(starting&&r.status!=="recording"){if(setRecording(!1),r.status==="busy")setProcessing(!0),sys("voice: still transcribing; try again shortly")}}catch(e){if(recordGen.current!==current2)return;setRecording(!starting),sys(`voice error: ${e instanceof Error?e.message:"gateway error"}`)}finally{if(pending3.current===current2)pending3.current=0}},[enabled3,recording,gw,sys]);return{state:state3,toggle,record:record2,setEnabled,setRecording,setProcessing,setRecordKey:setRecordKeyRaw,reset:reset4,keyLabel,onTranscript,setOnTranscript}}function VoiceIndicator({voice,keyLabel}){let theme=useTheme().theme;if(!voice.enabled&&!voice.recording&&!voice.processing)return null;let text5,fg2=theme.text;if(voice.recording)text5="\u25CF recording",fg2=theme.error;else if(voice.processing)text5="\u25CC transcribing",fg2=theme.warning;else text5=`voice ready [${keyLabel}]`,fg2=theme.textMuted;return $jsx("text",{children:$jsxs("span",{fg:fg2,children:[text5," "]})})}function sessionCapabilities(input){let sessionConnected=Boolean(input.sid),metadataHydrated=input.ready;return{sessionConnected,metadataHydrated,canSubmitPrompt:sessionConnected,canDispatchGatewayCommand:sessionConnected,canDrainQueue:sessionConnected&&!input.streaming}}var import_react161=__toESM(require_react_production(),1);function openMessage(dialog,m2,ops){let text5=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join("");dialog.replace($jsx(DialogSelect,{title:"Message Actions",options:[{title:"Copy",value:"copy",description:"message text to clipboard"},{title:"Rewind here",value:"rewind",description:"undo back to this turn (destructive)"},{title:"Fork here",value:"fork",description:"branch a new session at this point"}],onSelect:(o)=>{if(dialog.clear(),o.value==="copy")return void copyText(text5,ops.toast);if(o.value==="rewind")return ops.rewind(m2);if(o.value==="fork")return ops.fork(m2)}}))}async function undo(gw,count4,sid2){for(let i=0;i<count4;i++)await gw.request("session.undo",sid2?{session_id:sid2}:{})}var textOf=(message2)=>message2.parts.filter((part)=>part.type==="text").map((part)=>part.content).join("");function useMessageActions(args){let turns=import_react161.useCallback((message2)=>{let messages=args.turn.current.messages,at=messages.findIndex((item)=>item.id===message2.id);return at<0?0:messages.slice(at).filter((item)=>item.role==="user").length},[args.turn]),rewind=import_react161.useCallback(async(message2)=>{if(args.turn.current.streaming)return!1;let count4=turns(message2);if(!count4)return!1;try{await undo(args.gw,count4);let result=await args.gw.request("session.history");return args.dispatch({kind:"load",messages:transcriptToMessages(result.messages??[])}),args.composer.current?.set(textOf(message2)),args.focus("input"),!0}catch(err){return args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)}),!1}},[args.gw,args.toast,args.turn,args.dispatch,args.composer,args.focus,turns]),fork2=import_react161.useCallback(async(message2)=>{if(args.turn.current.streaming)return;let result=await args.gw.request("session.branch",{}).catch((err)=>{return args.toast.show({variant:"error",message:`branch failed: ${err.message}`}),null});if(!result?.session_id)return;try{if(await undo(args.gw,turns(message2),result.session_id),!await args.activate(result.session_id)){await args.session.close(result.session_id);return}args.composer.current?.set(textOf(message2)),args.focus("input"),args.toast.show({variant:"success",message:`forked \u2192 ${result.title??result.session_id}`})}catch(err){await args.session.close(result.session_id),args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)})}},[args.gw,args.toast,args.turn,args.activate,args.session,args.composer,args.focus,turns]),menu=import_react161.useCallback((message2)=>{if(args.turn.current.streaming)return;openMessage(args.dialog,message2,{rewind,fork:fork2,toast:args.toast})},[args.dialog,args.toast,args.turn,rewind,fork2]);return{rewind,fork:fork2,menu}}var BUSY_RE=/session busy|waiting for model response/i,App=(props)=>$jsx(ThemeProvider,{initial:props.initialTheme,children:$jsx(GatewayProvider,{client:props.gateway,children:$jsx(ToastProvider,{children:$jsx(KeysProvider,{overrides:props.keyOverrides,children:$jsx(DialogProvider,{children:$jsx(CommandProvider,{children:$jsx(PluginProvider,{plugins:props.plugins,children:$jsx(BackgroundProvider,{children:$jsx(AppInner,{launch:props.launch??{mode:"new"}})})})})})})})})}),AppInner=({launch:launch0})=>{let gw=useGateway(),gwRestart=useGatewayRestart(),dialog=useDialog(),dialogOpen=useDialogOpen(),themeCtx=useTheme(),toast=useToast(),renderer=useRenderer(),plugins=usePlugins(),session=useSession(),dims=useTerminalDimensions(),goalHook=import_react163.useMemo(()=>makeGoalHook(dialog,toast),[dialog,toast]),[turn,dispatch]=import_react163.useReducer(turnReducer,initialTurn),[ready,setReady]=import_react163.useState(!1),[sid2,setSid]=import_react163.useState(""),sidRef=import_react163.useRef(sid2);sidRef.current=sid2;let[starting,setStarting]=import_react163.useState(!1),startRef=import_react163.useRef(starting);startRef.current=starting;let active=turn.streaming||starting,capabilities=sessionCapabilities({sid:sid2,ready,streaming:active}),[tab,setTab]=import_react163.useState(CHAT_TAB),[subTabs,setSubTabs]=import_react163.useState(()=>({[SESSIONS_TAB]:0,[AUTOMATION_TAB]:0,[CONFIG_TAB]:0,[EIKON_TAB]:0})),setSub=import_react163.useCallback((tabIdx,sub2)=>setSubTabs((prev)=>prev[tabIdx]===sub2?prev:{...prev,[tabIdx]:sub2}),[]),sessSub=import_react163.useCallback((i)=>setSub(SESSIONS_TAB,i),[setSub]),autoSub=import_react163.useCallback((i)=>setSub(AUTOMATION_TAB,i),[setSub]),cfgSub=import_react163.useCallback((i)=>setSub(CONFIG_TAB,i),[setSub]),eikSub=import_react163.useCallback((i)=>setSub(EIKON_TAB,i),[setSub]),[hideSidebar,setHideSidebar]=import_react163.useState(!1),[usage,setUsage]=import_react163.useState(void 0),[info3,setInfo]=import_react163.useState(null),[title,setTitle]=import_react163.useState(""),caption=title.trim(),titleRef=import_react163.useRef(caption);titleRef.current=caption,import_react163.useEffect(()=>{process.removeAllListeners("SIGINT"),process.on("SIGINT",()=>quit(renderer,sidRef.current,titleRef.current,gw))},[renderer,gw]),import_react163.useEffect(()=>{let w2=warning();if(!w2)return;toast.show({variant:"warning",title:"control server exposed",message:w2.message,duration:15000})},[toast]);let[focusRegion,setFocusRegion]=import_react163.useState("input"),goToTab=import_react163.useCallback((t2)=>{setTab(t2),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),goTo=import_react163.useCallback((t2,sub2)=>{setTab(t2),setSubTabs((prev)=>prev[t2]===sub2?prev:{...prev,[t2]:sub2}),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),[status2,setStatus]=import_react163.useState(""),[escHint,setEscHint]=import_react163.useState(!1),[eikon,setEikon]=import_react163.useState(void 0),[queue,setQueue]=import_react163.useState([]),[busy2,setBusy]=import_react163.useState("queue"),turnRef=import_react163.useRef(turn);turnRef.current=turn;let queueRef=import_react163.useRef(queue);queueRef.current=queue;let launchRef=import_react163.useRef(launch0),launch=launchRef.current,[splash,setSplash]=import_react163.useState(launch.splash!==!1),[switching,setSwitching]=import_react163.useState(!1),summoned=import_react163.useRef(!1),creating=import_react163.useRef(!1),[composing,setComposing]=import_react163.useState(!1),splashLast=import_react163.useMemo(()=>launch.mode==="new"?lastReal():void 0,[launch.mode]),splashInfo=import_react163.useMemo(()=>info3?{agentVersion:info3.version,behind:info3.update_behind,model:info3.model}:void 0,[info3?.version,info3?.update_behind,info3?.model]),splashLastProp=import_react163.useMemo(()=>splashLast?{id:splashLast.id,title:splashLast.title}:void 0,[splashLast]),news=import_react163.useMemo(()=>readChangelog()?.headline,[]),[attachments,setAttachments]=import_react163.useState([]),attachmentsRef=import_react163.useRef(attachments);attachmentsRef.current=attachments;let[cloudH,setCloudH]=import_react163.useState(CLOUD_MIN),[pick2,setPick]=import_react163.useState(void 0),[skin2,setSkin]=import_react163.useState(()=>deriveSkin(void 0)),inflight=import_react163.useRef(!1),hold=import_react163.useRef(!1),pending3=import_react163.useRef(!1),detaching=import_react163.useRef(0),[pulse,setPulse]=import_react163.useState(0),start2=import_react163.useCallback(()=>{inflight.current=!1,pending3.current=!1,setPulse((n)=>n+1)},[]),settle=import_react163.useCallback(()=>{if(!hold.current)return;hold.current=!1,setPulse((n)=>n+1)},[]),undone=import_react163.useRef([]),sessionStart=import_react163.useRef(Date.now()),composer2=import_react163.useRef(null),promptRef=import_react163.useRef(null),{cmds}=useSlashCommands(),cmdsRef=import_react163.useRef(cmds);cmdsRef.current=cmds;let sys=import_react163.useCallback((text5)=>dispatch({kind:"system",text:text5}),[]),voice=useVoice(gw.request.bind(gw),sys);import_react163.useEffect(()=>{voice.setOnTranscript((text5)=>{let c=composer2.current;if(!c)return;c.set(""),setTimeout(()=>sendRef.current(text5),0)})},[]);let[errorPulse,setErrorPulse]=import_react163.useState(!1);import_react163.useEffect(()=>{let restart=(mode2="resume")=>{let sid3=sidRef.current;if(mode2==="resume"&&sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus("gateway restarting"),voice.reset()},exit=(code2)=>{let text5=`gateway exited${code2===null?"":` (${code2})`}`,sid3=sidRef.current;if(sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus(text5),setErrorPulse(!0),voice.reset(),dispatch({kind:"system",text:text5})};return gw.on("restart",restart),gw.on("exit",exit),()=>{gw.off("restart",restart),gw.off("exit",exit)}},[gw]);let agentState=errorPulse?"error":turn.toolActive?"working":turn.streaming&&turn.hasContent?"speaking":active?"thinking":composing?"listening":"idle",onAvatarHold=import_react163.useCallback((s)=>{if(s==="error")setErrorPulse(!1)},[]),prompt=import_react163.useMemo(()=>pending2(turn.messages),[turn.messages]),cloudAuto=turn.streaming&&!turn.hasContent&&!prompt,[force,setForce]=import_react163.useState(void 0),cloud=!prompt&&(force??cloudAuto),prevStream=import_react163.useRef(turn.streaming);import_react163.useEffect(()=>{if(!prevStream.current&&turn.streaming)setForce(void 0),setPick(void 0);prevStream.current=turn.streaming},[turn.streaming]);let onPick=import_react163.useCallback((m2)=>{setPick((p)=>{if(m2&&p&&m2.id===p.id){setForce(!1);return}return setForce(!!m2),m2})},[]),onAvatar=import_react163.useCallback(()=>{let next2=!cloud;if(!next2)setPick(void 0);setForce(next2)},[cloud]),closeCloud=import_react163.useCallback(()=>{setForce(!1),setPick(void 0)},[]),intr=import_react163.useRef(()=>{}),steer=import_react163.useCallback((text5)=>{let v2=text5.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),openSteer=import_react163.useCallback(()=>{openTextPrompt(dialog,{title:"Steer active turn",label:"Soft nudge for the running session"}).then((v2)=>{if(v2)steer(v2)})},[dialog,steer]),onEnqueue=import_react163.useCallback((t2)=>{if(busy2==="steer"){let v2=t2.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>{if(r.status==="queued")return toast.show({variant:"success",message:"Queued \u2014 lands on next tool result"});setQueue((q5)=>[...q5,t2]),toast.show({variant:"info",message:"steer rejected \u2014 queued for next turn"})}).catch(()=>setQueue((q5)=>[...q5,t2]));return}if(busy2==="interrupt"){hold.current=!0,setQueue((q5)=>[t2,...q5]),intr.current();return}setQueue((q5)=>[...q5,t2])},[busy2,gw,toast]),updateAttachments=import_react163.useCallback((next2)=>{let value2=typeof next2==="function"?next2(attachmentsRef.current):next2;attachmentsRef.current=value2,setAttachments(value2)},[]),onAttach=import_react163.useCallback((r)=>updateAttachments((a)=>[...a,r]),[updateAttachments]),stream=useStream({dispatch,session,launchRef,sidRef,sessionStart,goalHook,setSid,setInfo,setReady,setTitle,setBusy,setStarting,setUsage,setStatus,setSkin,setErrorPulse,settle,onVoiceStatus:(state3)=>{voice.setRecording(state3==="listening"||state3==="recording"),voice.setProcessing(state3==="transcribing"||state3==="processing")},onVoiceTranscript:(text5,noSpeechLimit)=>{if(voice.setRecording(!1),voice.setProcessing(!1),noSpeechLimit){voice.setEnabled(!1),sys("voice: disabled after repeated silence");return}voice.onTranscript?.(text5)},start:start2}),interrupt=import_react163.useCallback(()=>{if(startRef.current&&!turnRef.current.streaming)hold.current=!0;stream.doInterrupt()},[stream.doInterrupt]);intr.current=interrupt;let reset4=import_react163.useCallback(()=>{stream.interrupted.current=!1,hold.current=!1,pending3.current=!1,toast.clear("credits.depleted"),undone.current=[],dispatch({kind:"reset"}),setUsage(void 0),setReady(!1),setStarting(!1),setStatus(""),setTitle(""),updateAttachments([])},[toast,updateAttachments]),newSession=import_react163.useCallback(async()=>{if(creating.current)return;creating.current=!0,setSwitching(!0);let prev=sidRef.current;summoned.current=!0,setSplash(!0),setReady(!1),gw.setSession("");try{let r=await session.create();if(reset4(),setSid(r.id),r.info)setInfo(r.info),setUsage(r.info.usage);if(setReady(!0),setStarting(!1),setStatus(""),sessionStart.current=Date.now(),prev)session.close(prev,{preserveBackground:!0})}catch(err){if(prev)gw.setSession(prev),setReady(!0);setSplash(!1),summoned.current=!1,dispatch({kind:"system",text:`Failed to create session: ${err instanceof Error?err.message:String(err)}`})}finally{creating.current=!1,setSwitching(!1)}},[reset4,session,gw]),switchSession=import_react163.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.resume(target2);if(reset4(),setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(setReady(!0),sessionStart.current=Date.now(),res.messages.length)dispatch({kind:"load",messages:res.messages});if(prev&&prev!==res.id)session.close(prev,{preserveBackground:!0});setSplash(!1),summoned.current=!1}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);dispatch({kind:"system",text:`Failed to resume: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset4,session,goToTab,gw]),liveStatus=(state3,running2=!1)=>{if(state3==="waiting")return"waiting for input\u2026";if(state3==="starting")return"starting agent\u2026";return running2||state3==="working"?"running\u2026":"ready"},activateSession=import_react163.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.activate(target2);if(reset4(),setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(sessionStart.current=res.startedAt??Date.now(),dispatch({kind:"load.live",messages:res.messages,streaming:res.running}),setStatus(liveStatus(res.status,res.running)),setReady(!0),setSplash(!1),summoned.current=!1,prev&&prev!==res.id)toast.show({variant:"info",message:"switched live session"});return!0}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);return dispatch({kind:"system",text:`Failed to activate: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1,!1}finally{setSwitching(!1)}},[reset4,session,goToTab,toast,gw]),switchProfile=import_react163.useCallback((newHome,name)=>{voice.reset(),rehome(newHome),reset4(),gw.setSession(""),setSid(""),setInfo(null),setSkin(deriveSkin(void 0)),summoned.current=!0,setSplash(!0),launchRef.current={mode:"new",splash:!0},toast.show({variant:"info",message:`Switching to '${name}'\u2026`}),goToTab(CHAT_TAB),gwRestart("new")},[reset4,goToTab,gwRestart,toast,gw]),loadEikon=import_react163.useCallback((path4)=>{try{setEikon(parseEikonFile(path4))}catch{setEikon(void 0)}},[]),eikonName=usePref("eikon"),eikonRev=import_react163.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision);import_react163.useEffect(()=>{let p=eikonName&&exports_eikon.baked(eikonName)||bundledEikonPath(skin2.skin?.name);if(p)loadEikon(p);else setEikon(void 0)},[eikonName,eikonRev,skin2.skin?.name,loadEikon]);let messageActions=useMessageActions({gw,dialog,toast,session,activate:activateSession,composer:composer2,turn:turnRef,dispatch,focus:setFocusRegion}),rewind=messageActions.rewind,msgMenu=messageActions.menu,attachClipboard=import_react163.useCallback(()=>{gw.request("clipboard.paste").then((r)=>r.attached?updateAttachments((a)=>[...a,r]):toast.show({variant:"info",message:r.message??"No image in clipboard"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,updateAttachments]),sendRef=import_react163.useRef(()=>{}),slash3=useSlash({dispatch,session,turnRef,queueRef,sendRef,composer:composer2,summoned,undone,capabilities,info:info3,sid:sid2,title:caption,skin:skin2,setQueue,setFocusRegion,setSplash,setAttachments:updateAttachments,setInfo,setUsage,setTitle,newSession,switchSession,activateSession,rewind,goTo,attachClipboard,voiceToggle:voice.toggle}),send=import_react163.useCallback(async(raw2)=>{if(creating.current)return;if(["exit","quit",":q",":q!",":wq"].includes(raw2.trim()))return quit(renderer,sidRef.current,titleRef.current,gw);if(detaching.current>0){if(raw2.trim())composer2.current?.set(raw2);setStatus("detaching image\u2026");return}let m2=raw2.match(/^\/(\S+)(?:\s+([\s\S]*))?$/);if(m2){let[,name,arg=""]=m2,r=resolve9(cmdsRef.current,name);if("hit"in r)return slash3(r.hit,arg.trim());if("ambiguous"in r){let head=r.ambiguous.slice(0,6).join(", ");return dispatch({kind:"system",text:`ambiguous: /${name} \u2192 ${head}${r.ambiguous.length>6?", \u2026":""}`})}}let text5=raw2;if(hasInterp(raw2))setStatus("interpolating\u2026"),text5=await interpolate(gw,raw2),setStatus("");stream.interrupted.current=!1;let att=attachmentsRef.current,withMedia=att.length?[...att.flatMap((a)=>a.path?[`MEDIA:${a.path}`]:[]),text5].filter(Boolean).join(`
4211
- `):text5;if(pending3.current){setQueue((q5)=>[...q5,raw2]),setStatus("queued for next turn");return}pending3.current=!0,setPulse((n)=>n+1),gw.request("prompt.submit",{text:text5}).then((r)=>{if(dispatch({kind:"user",text:withMedia}),r.status==="streaming"&&!turnRef.current.streaming)setStarting(!0),setStatus("starting agent\u2026");updateAttachments([]),undone.current=[],setTab(CHAT_TAB)}).catch((e)=>{let msg=e instanceof Error?e.message:String(e);if(BUSY_RE.test(msg)){pending3.current=!1,setPulse((n)=>n+1),inflight.current=!0,setQueue((q5)=>[text5,...q5]),setStatus("queued for next turn"),toast.show({variant:"info",message:"queued for next turn"}),setTimeout(()=>{inflight.current=!1,setPulse((n)=>n+1)},400);return}pending3.current=!1,setPulse((n)=>n+1),inflight.current=!1,setStarting(!1),dispatch({kind:"system",text:`submit failed: ${msg}`}),toast.show({variant:"error",message:msg})})},[gw,slash3,toast,updateAttachments]);sendRef.current=send;let onShell=import_react163.useCallback((command)=>{setSplash(!1),dispatch({kind:"system",text:`$ ${command}`}),setStatus("running\u2026"),gw.request("shell.exec",{command}).then((r)=>{let out=(r.stdout??"").trimEnd(),err=(r.stderr??"").trimEnd(),body2=[out,err&&`stderr:
4210
+ `).length)),all2=props.attachments??[],previews=all2.filter((a)=>a.path&&classify(a.path)==="img").slice(0,MAX_PREVIEWS),chips=all2.filter((a)=>!previews.includes(a)).slice(0,MAX_PREVIEWS),shown=new Set([...previews,...chips]),attRows=all2.length>0?previews.length>0?2:1:0,lift=rows3+attRows+3,more=all2.filter((a)=>!shown.has(a)).length,bits=[props.hidden?.profile,props.hidden?.title,props.hidden?.place,props.hidden?.context].filter(Boolean);return $jsxs("box",{flexDirection:"column",position:"relative",children:[props.focused&&pop3.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(SlashPopover,{commands:pop3.popover,cursor:pop3.cursor,onCursor:pop3.setCursor,onSelect:select2})}):props.focused&&at.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(AtRefPopover,{items:at.items,cursor:at.cursor,onCursor:at.setCursor,onSelect:atAccept})}):props.focused&&comp.open?$jsx("box",{position:"absolute",bottom:lift,left:0,right:0,zIndex:2,children:$jsx(AtRefPopover,{items:comp.items,cursor:comp.cursor,onCursor:comp.setCursor,onSelect:(idx2)=>{let it=comp.items[idx2];if(it?.text)write(acceptCompletion(input,it,comp.replaceFrom,comp.replaceTo))}})}):null,(props.queue?.length??0)>0?$jsx("box",{flexDirection:"column",paddingX:1,paddingBottom:1,children:props.queue.map((q5,i)=>$jsx("box",{height:1,onMouseDown:()=>props.onDequeue?.(i),children:$jsxs("text",{children:[$jsxs("span",{fg:theme.borderSubtle,children:[i===0?"\u256D":"\u2502"," "]}),$jsxs("span",{fg:theme.textMuted,children:["\u23F8 ",i+1,". ",trunc5(q5,60)]})]})},i))}):null,$jsxs("box",{border:!0,borderStyle:"single",borderColor:mode2==="shell"?theme.primary:props.focused?theme.borderActive:theme.border,flexDirection:"column",position:"relative",children:[previews.length>0?$jsx("box",{flexDirection:"column",paddingX:1,maxHeight:MAX_PREVIEWS,overflow:"hidden",children:previews.map((a)=>$jsx(ChafaImage,{path:a.path,width:60,bare:!0},`p-${a.path}`))}):null,chips.length>0?$jsxs("box",{flexDirection:"row",flexWrap:"wrap",gap:1,paddingX:1,paddingTop:previews.length>0?0:1,paddingBottom:1,children:[chips.map((a,i)=>{if(a.path){let kind2=classify(a.path);return $jsxs("box",{flexDirection:"row",height:1,children:[$jsx(MediaChip,{path:a.path,bare:kind2==="img"}),kind2!=="img"&&a.token_estimate?$jsxs("text",{fg:theme.textMuted,children:[" ~",fmt5(a.token_estimate),"t"]}):null]},a.path)}return $jsxs("text",{children:[$jsx("span",{bg:theme.secondary,fg:theme.background,children:" file "}),$jsxs("span",{bg:theme.backgroundElement,fg:theme.textMuted,children:[" ",a.name??`file ${i+1}`," "]})]},a.name??i)}),more>0?$jsxs("text",{fg:theme.textMuted,children:["+",more]}):null]}):null,$jsxs("box",{flexDirection:"row",children:[$jsx("box",{width:1,children:$jsx("text",{fg:theme.primary,children:mode2==="shell"?"$":">"})}),$jsx("box",{width:1}),$jsx("textarea",{ref:taRef,syntaxStyle,onContentChange:()=>{let t2=ta.current;setInput(t2?.plainText??""),setCaret(t2?.cursorOffset??0)},onCursorChange:()=>{if(!live.current.input.includes("@")&&!live.current.input.includes("/"))return;let off=ta.current?.cursorOffset??0;setCaret((c)=>c===off?c:off)},onSubmit:submit4,onPaste:paste,keyBindings:bindings,wrapMode:"word",minHeight:1,maxHeight:MAX_ROWS,placeholder:mode2==="shell"?"Run a shell command (30s cap, cwd) \u2014 esc or \u232B to exit":props.streaming?"Type to queue... (Enter queues, click chip to edit)":"Message Hermes... (/ for commands, Shift+Enter for newline)",focused:props.focused,textColor:theme.text,focusedTextColor:theme.text,placeholderColor:theme.textMuted,cursorColor:theme.text,backgroundColor:"transparent",focusedBackgroundColor:"transparent",flexGrow:1})]}),pop3.ghost&&props.focused&&rows3===1&&pop3.spot?.whole?$jsx("box",{position:"absolute",top:attRows,left:2+input.length,height:1,children:$jsx("text",{fg:theme.textMuted,children:pop3.ghost})}):null]}),$jsxs("box",{height:1,flexDirection:"row",paddingX:1,children:[$jsxs("text",{children:[props.streaming?$jsx(SpinGlyph,{fg:dot}):$jsx("span",{fg:dot,children:"\u25CF"}),$jsxs("span",{fg:theme.textMuted,children:[" ",mode2==="shell"?"Shell":label3]}),mode2==="shell"?$jsx("span",{fg:theme.textMuted,children:" esc exit shell mode"}):props.starting&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to cancel"}):props.starting?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 cancel"}):props.streaming&&props.escHint?$jsx("span",{fg:theme.warning,children:" esc again to interrupt"}):props.streaming?$jsx("span",{fg:theme.textMuted,children:" esc\xD72 interrupt"}):null]}),$jsx("box",{flexGrow:1}),props.streaming&&(props.queue?.length??0)>0?$jsxs("text",{fg:theme.textMuted,children:[keys.print("queue.flush")," to send queued now "]}):null,bg2.count>0?$jsxs("text",{fg:theme.text,children:["\u25B6 ",bg2.count," "]}):null,resume?$jsxs("text",{fg:theme.textMuted,children:[resume," "]}):null,bits.length>0?$jsxs("text",{fg:theme.textMuted,children:[trunc5(bits.join(" \xB7 "),56)," "]}):null,props.model?$jsx("text",{fg:theme.textMuted,children:props.model}):null]})]})}));var import_react157=__toESM(require_react_production(),1);init_sessions_db();var normalize3=(sid2)=>sid2.trim().replace(/\.json$/i,"").replace(/^session_(?=\d{8}_)/,"");function useSession(){let gw=useGateway(),inflightMessages=(inflight)=>{let user2=String(inflight?.user??"").trim(),assistant2=String(inflight?.assistant??""),messages=[];if(user2)messages.push(...transcriptToMessages([{role:"user",text:user2}]));if(assistant2||inflight?.streaming)messages.push(...transcriptToMessages([{role:"assistant",text:assistant2}]));return messages},resume=import_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.resume",{session_id:target2}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.resumed??target2);let messages=res.messages?.length?transcriptToMessages(res.messages):[];return{id,messages,info:res.info}},[gw]),create=import_react157.useCallback(async()=>{let res=await gw.request("session.create",{});return gw.setSession(res.session_id),{id:res.session_id,info:res.info}},[gw]),activate=import_react157.useCallback(async(sid2)=>{let target2=normalize3(sid2),res=await gw.request("session.activate",{session_id:target2}),id=res.session_id;gw.setSession(id),set("lastSessionId",res.session_key??id);let history=res.messages?.length?transcriptToMessages(res.messages):[],running2=Boolean(res.running||res.status==="working"||res.status==="waiting");return{id,info:res.info,messages:[...history,...inflightMessages(res.inflight)],running:running2,startedAt:res.started_at?res.started_at*1000:void 0,status:res.status}},[gw]),busy2=import_react157.useCallback(async()=>{try{return(await gw.request("agents.list")).processes?.some((p)=>p.status==="running")??!1}catch{return!0}},[gw]),close2=import_react157.useCallback(async(sid2,opts)=>{if(!sid2)return!1;if(opts?.preserveBackground&&await busy2())return!1;try{return await gw.request("session.close",{session_id:sid2}),!0}catch{return!1}},[gw,busy2]),boot2=import_react157.useCallback(async(launch)=>{let fresh2=async(note)=>({...await create(),messages:[],note});if(launch.mode==="resume"){let target2=launch.sid??exports_sessions_db.lastReal()?.id;if(!target2)return fresh2("no prior session to resume \u2014 starting fresh");try{return await resume(target2)}catch(e){let msg=e instanceof Error?e.message:String(e);return fresh2(`resume ${target2} failed: ${msg} \u2014 starting fresh`)}}let last4=get2("lastSessionId"),row4=last4?exports_sessions_db.byId(last4):null;if(row4?.message_count===0&&row4.parent_session_id==null)try{return await resume(row4.id)}catch{}return fresh2()},[create,resume]),interrupt=import_react157.useCallback(async()=>{await gw.request("session.interrupt")},[gw]),branch2=import_react157.useCallback(async(name)=>{return(await gw.request("session.branch",name?{name}:{})).session_id??null},[gw]),compress=import_react157.useCallback(async(arg="")=>{let raw2=arg.trim(),params=raw2?{raw_args:raw2,focus_topic:raw2}:{};return gw.request("session.compress",params)},[gw]),undo=import_react157.useCallback(async()=>{await gw.request("session.undo")},[gw]);return import_react157.useMemo(()=>({boot:boot2,create,resume,activate,close:close2,interrupt,branch:branch2,compress,undo}),[boot2,create,resume,activate,close2,interrupt,branch2,compress,undo])}var import_react158=__toESM(require_react_production(),1);function useTerminalTitle(active,cwd){let renderer=useRenderer();import_react158.useEffect(()=>{let title=active?"\u25CF Herm":"Herm",name=cwd?.split(/[\\/]/).filter(Boolean).at(-1);renderer.setTerminalTitle(name?`${title} \xB7 ${name}`:title)},[renderer,active,cwd])}init_sessions_db();init_hermes_analytics();function rehome(newHome){process.env.HERMES_HOME=newHome,setHome2(newHome),setHome(newHome),cache3.clear(),resetKanban(),close(),exports_preferences.reload(),home3.reset()}var import_react160=__toESM(require_react_production(),1);var Countdown=(p)=>{let theme=useTheme().theme,[n,setN]=import_react160.useState(p.seconds);import_react160.useEffect(()=>{if(n<=0){p.onFire();return}let t2=setTimeout(()=>setN((v2)=>v2-1),1000);return()=>clearTimeout(t2)},[n,p.onFire]),useKeyboard(()=>p.onCancel());let bar3="\u2588".repeat(n)+"\u2591".repeat(Math.max(0,p.seconds-n));return $jsxs("box",{flexDirection:"column",width:58,children:[$jsx("box",{height:1,children:$jsx("text",{fg:theme.warning,children:$jsx("strong",{children:p.title})})}),$jsx("box",{height:1}),$jsx("box",{minHeight:1,children:$jsx("text",{wrapMode:"word",children:p.body})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsxs("text",{fg:theme.warning,children:[bar3," ",n,"s"]})}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:p.action})}),$jsx("box",{height:1}),$jsx("box",{height:1,children:$jsx("text",{fg:theme.textMuted,children:"press any key to cancel"})})]})};function openCountdown(dialog,opts){return new Promise((resolve4)=>{dialog.replace($jsx(Countdown,{...opts,onFire:()=>{dialog.clear(),resolve4(!0)},onCancel:()=>{dialog.clear(),resolve4(!1)}}),()=>resolve4(!1))})}var SECONDS=10,SUSPEND=process.platform==="darwin"?"pmset sleepnow":"systemctl suspend",run=(cmd)=>Bun.spawn(["sh","-c",cmd],{stdout:"ignore",stderr:"ignore"}),fired=new Map;function makeGoalHook(dialog,toast){let act=(goal,done2,total)=>{let pref=(exports_preferences.get("onGoalDone")??"toast").trim(),head=goal.length>60?goal.slice(0,57)+"\u2026":goal,n=total&&total>0?` ${done2}/${total} items`:"";if(toast.show({variant:"success",title:"Goal complete",message:head+n,duration:8000}),pref==="toast")return;let cmd=pref==="suspend"?SUSPEND:pref;openCountdown(dialog,{title:"Goal complete \u2014 "+(pref==="suspend"?"suspending":"running hook"),body:head,action:`\u2192 ${cmd}`,seconds:SECONDS}).then((ok)=>{if(ok)run(cmd)})};return{check:(sid2)=>{if(!sid2)return;io.goalState(sid2).then((s)=>{if(!s||s.status!=="done")return;if(fired.get(sid2)===s.goal)return;fired.set(sid2,s.goal);let list3=s.checklist??[],done2=list3.filter((i)=>i.status==="completed"||i.status==="impossible").length;act(s.goal,done2,list3.length)}).catch(()=>{})}}}var import_react162=__toESM(require_react_production(),1);function useVoice(gw,sys){let[enabled3,setEnabled]=import_react162.useState(!1),[recording,setRecording]=import_react162.useState(!1),[processing,setProcessing]=import_react162.useState(!1),[recordKeyRaw,setRecordKeyRaw]=import_react162.useState(),[tts,setTts]=import_react162.useState(!1),[onTranscript,setTranscript]=import_react162.useState(null),pending3=import_react162.useRef(0),recordGen=import_react162.useRef(0),toggleGen=import_react162.useRef(0),setOnTranscript=import_react162.useCallback((fn)=>setTranscript(fn?()=>fn:null),[]),reset4=import_react162.useCallback(()=>{toggleGen.current++,recordGen.current++,pending3.current=0,setEnabled(!1),setRecording(!1),setProcessing(!1),setTts(!1)},[]),recordKey=import_react162.useMemo(()=>parseVoiceRecordKey(recordKeyRaw),[recordKeyRaw]),keyLabel=import_react162.useMemo(()=>formatVoiceRecordKey(recordKey),[recordKey]),state3=import_react162.useMemo(()=>({enabled:enabled3,recording,processing,recordKey,tts}),[enabled3,recording,processing,recordKey,tts]),toggle=import_react162.useCallback(async(action,sid2)=>{let current2=++toggleGen.current;try{let r=await gw("voice.toggle",{action,session_id:sid2});if(toggleGen.current!==current2)return;if(r.enabled!==void 0){if(setEnabled(r.enabled),!r.enabled)recordGen.current++,setRecording(!1),setProcessing(!1)}if(r.tts!==void 0)setTts(r.tts);if(r.record_key)setRecordKeyRaw(r.record_key);let label3=formatVoiceRecordKey(parseVoiceRecordKey(r.record_key)),ttsMsg=r.tts?" \xB7 tts on":"",details2=action==="status"&&r.details?.trim()?` \xB7 ${r.details.trim()}`:"";sys(`voice ${r.enabled?"on":"off"}${ttsMsg} [${label3}]${details2}`)}catch(e){if(toggleGen.current!==current2)return;sys(`voice: ${e instanceof Error?e.message:"gateway error"}`)}},[gw,sys]),record2=import_react162.useCallback(async(sid2)=>{if(!enabled3){sys("voice: mode is off \u2014 enable with /voice on");return}if(pending3.current)return;let current2=++recordGen.current;pending3.current=current2;let starting=!recording,action=starting?"start":"stop";if(starting)setRecording(!0);else setRecording(!1),setProcessing(!1);try{let r=await gw("voice.record",{action,session_id:sid2});if(recordGen.current!==current2)return;if(starting&&r.status!=="recording"){if(setRecording(!1),r.status==="busy")setProcessing(!0),sys("voice: still transcribing; try again shortly")}}catch(e){if(recordGen.current!==current2)return;setRecording(!starting),sys(`voice error: ${e instanceof Error?e.message:"gateway error"}`)}finally{if(pending3.current===current2)pending3.current=0}},[enabled3,recording,gw,sys]);return{state:state3,toggle,record:record2,setEnabled,setRecording,setProcessing,setRecordKey:setRecordKeyRaw,reset:reset4,keyLabel,onTranscript,setOnTranscript}}function VoiceIndicator({voice,keyLabel}){let theme=useTheme().theme;if(!voice.enabled&&!voice.recording&&!voice.processing)return null;let text5,fg2=theme.text;if(voice.recording)text5="\u25CF recording",fg2=theme.error;else if(voice.processing)text5="\u25CC transcribing",fg2=theme.warning;else text5=`voice ready [${keyLabel}]`,fg2=theme.textMuted;return $jsx("text",{children:$jsxs("span",{fg:fg2,children:[text5," "]})})}function sessionCapabilities(input){let sessionConnected=Boolean(input.sid),metadataHydrated=input.ready;return{sessionConnected,metadataHydrated,canSubmitPrompt:sessionConnected,canDispatchGatewayCommand:sessionConnected,canDrainQueue:sessionConnected&&!input.streaming}}var import_react163=__toESM(require_react_production(),1);function openMessage(dialog,m2,ops){let text5=m2.parts.filter((p)=>p.type==="text").map((p)=>p.content).join("");dialog.replace($jsx(DialogSelect,{title:"Message Actions",options:[{title:"Copy",value:"copy",description:"message text to clipboard"},{title:"Rewind here",value:"rewind",description:"undo back to this turn (destructive)"},{title:"Fork here",value:"fork",description:"branch a new session at this point"}],onSelect:(o)=>{if(dialog.clear(),o.value==="copy")return void copyText(text5,ops.toast);if(o.value==="rewind")return ops.rewind(m2);if(o.value==="fork")return ops.fork(m2)}}))}async function undo(gw,count4,sid2){for(let i=0;i<count4;i++)await gw.request("session.undo",sid2?{session_id:sid2}:{})}var textOf=(message2)=>message2.parts.filter((part)=>part.type==="text").map((part)=>part.content).join("");function useMessageActions(args){let turns=import_react163.useCallback((message2)=>{let messages=args.turn.current.messages,at=messages.findIndex((item)=>item.id===message2.id);return at<0?0:messages.slice(at).filter((item)=>item.role==="user").length},[args.turn]),rewind=import_react163.useCallback(async(message2)=>{if(args.turn.current.streaming)return!1;let count4=turns(message2);if(!count4)return!1;try{await undo(args.gw,count4);let result=await args.gw.request("session.history");return args.dispatch({kind:"load",messages:transcriptToMessages(result.messages??[])}),args.composer.current?.set(textOf(message2)),args.focus("input"),!0}catch(err){return args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)}),!1}},[args.gw,args.toast,args.turn,args.dispatch,args.composer,args.focus,turns]),fork2=import_react163.useCallback(async(message2)=>{if(args.turn.current.streaming)return;let result=await args.gw.request("session.branch",{}).catch((err)=>{return args.toast.show({variant:"error",message:`branch failed: ${err.message}`}),null});if(!result?.session_id)return;try{if(await undo(args.gw,turns(message2),result.session_id),!await args.activate(result.session_id)){await args.session.close(result.session_id);return}args.composer.current?.set(textOf(message2)),args.focus("input"),args.toast.show({variant:"success",message:`forked \u2192 ${result.title??result.session_id}`})}catch(err){await args.session.close(result.session_id),args.toast.show({variant:"error",message:err instanceof Error?err.message:String(err)})}},[args.gw,args.toast,args.turn,args.activate,args.session,args.composer,args.focus,turns]),menu=import_react163.useCallback((message2)=>{if(args.turn.current.streaming)return;openMessage(args.dialog,message2,{rewind,fork:fork2,toast:args.toast})},[args.dialog,args.toast,args.turn,rewind,fork2]);return{rewind,fork:fork2,menu}}var BUSY_RE=/session busy|waiting for model response/i,App=(props)=>$jsx(ThemeProvider,{initial:props.initialTheme,children:$jsx(GatewayProvider,{client:props.gateway,children:$jsx(ToastProvider,{children:$jsx(KeysProvider,{overrides:props.keyOverrides,children:$jsx(DialogProvider,{children:$jsx(CommandProvider,{children:$jsx(PluginProvider,{plugins:props.plugins,children:$jsx(BackgroundProvider,{children:$jsx(AppInner,{launch:props.launch??{mode:"new"}})})})})})})})})}),AppInner=({launch:launch0})=>{let gw=useGateway(),gwRestart=useGatewayRestart(),dialog=useDialog(),dialogOpen=useDialogOpen(),themeCtx=useTheme(),toast=useToast(),renderer=useRenderer(),plugins=usePlugins(),session=useSession(),dims=useTerminalDimensions(),goalHook=import_react165.useMemo(()=>makeGoalHook(dialog,toast),[dialog,toast]),[turn,dispatch]=import_react165.useReducer(turnReducer,initialTurn),[ready,setReady]=import_react165.useState(!1),[sid2,setSid]=import_react165.useState(""),sidRef=import_react165.useRef(sid2);sidRef.current=sid2;let[starting,setStarting]=import_react165.useState(!1),startRef=import_react165.useRef(starting);startRef.current=starting;let active=turn.streaming||starting,capabilities=sessionCapabilities({sid:sid2,ready,streaming:active}),[tab,setTab]=import_react165.useState(CHAT_TAB),[subTabs,setSubTabs]=import_react165.useState(()=>({[SESSIONS_TAB]:0,[AUTOMATION_TAB]:0,[CONFIG_TAB]:0,[EIKON_TAB]:0})),setSub=import_react165.useCallback((tabIdx,sub2)=>setSubTabs((prev)=>prev[tabIdx]===sub2?prev:{...prev,[tabIdx]:sub2}),[]),sessSub=import_react165.useCallback((i)=>setSub(SESSIONS_TAB,i),[setSub]),autoSub=import_react165.useCallback((i)=>setSub(AUTOMATION_TAB,i),[setSub]),cfgSub=import_react165.useCallback((i)=>setSub(CONFIG_TAB,i),[setSub]),eikSub=import_react165.useCallback((i)=>setSub(EIKON_TAB,i),[setSub]),[hideSidebar,setHideSidebar]=import_react165.useState(!1),[usage,setUsage]=import_react165.useState(void 0),[info3,setInfo]=import_react165.useState(null),[title,setTitle]=import_react165.useState(""),caption=title.trim(),titleRef=import_react165.useRef(caption);titleRef.current=caption,import_react165.useEffect(()=>{process.removeAllListeners("SIGINT"),process.on("SIGINT",()=>quit(renderer,sidRef.current,titleRef.current,gw))},[renderer,gw]),import_react165.useEffect(()=>{let w2=warning();if(!w2)return;toast.show({variant:"warning",title:"control server exposed",message:w2.message,duration:15000})},[toast]);let[focusRegion,setFocusRegion]=import_react165.useState("input"),goToTab=import_react165.useCallback((t2)=>{setTab(t2),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),goTo=import_react165.useCallback((t2,sub2)=>{setTab(t2),setSubTabs((prev)=>prev[t2]===sub2?prev:{...prev,[t2]:sub2}),setFocusRegion(t2===CHAT_TAB?"input":"content")},[]),[status2,setStatus]=import_react165.useState(""),[escHint,setEscHint]=import_react165.useState(!1),[eikon,setEikon]=import_react165.useState(void 0),[queue,setQueue]=import_react165.useState([]),[busy2,setBusy]=import_react165.useState("queue"),turnRef=import_react165.useRef(turn);turnRef.current=turn;let queueRef=import_react165.useRef(queue);queueRef.current=queue;let launchRef=import_react165.useRef(launch0),launch=launchRef.current,[splash,setSplash]=import_react165.useState(launch.splash!==!1),[switching,setSwitching]=import_react165.useState(!1),summoned=import_react165.useRef(!1),creating=import_react165.useRef(!1),[composing,setComposing]=import_react165.useState(!1),splashLast=import_react165.useMemo(()=>launch.mode==="new"?lastReal():void 0,[launch.mode]),splashInfo=import_react165.useMemo(()=>info3?{agentVersion:info3.version,behind:info3.update_behind,model:info3.model}:void 0,[info3?.version,info3?.update_behind,info3?.model]),splashLastProp=import_react165.useMemo(()=>splashLast?{id:splashLast.id,title:splashLast.title}:void 0,[splashLast]),news=import_react165.useMemo(()=>readChangelog()?.headline,[]),[attachments,setAttachments]=import_react165.useState([]),attachmentsRef=import_react165.useRef(attachments);attachmentsRef.current=attachments;let[cloudH,setCloudH]=import_react165.useState(CLOUD_MIN),[pick2,setPick]=import_react165.useState(void 0),[skin2,setSkin]=import_react165.useState(()=>deriveSkin(void 0)),inflight=import_react165.useRef(!1),hold=import_react165.useRef(!1),pending3=import_react165.useRef(!1),detaching=import_react165.useRef(0),[pulse,setPulse]=import_react165.useState(0),start2=import_react165.useCallback(()=>{inflight.current=!1,pending3.current=!1,setPulse((n)=>n+1)},[]),settle=import_react165.useCallback(()=>{if(!hold.current)return;hold.current=!1,setPulse((n)=>n+1)},[]),undone=import_react165.useRef([]),sessionStart=import_react165.useRef(Date.now()),composer2=import_react165.useRef(null),promptRef=import_react165.useRef(null),{cmds}=useSlashCommands(),cmdsRef=import_react165.useRef(cmds);cmdsRef.current=cmds;let sys=import_react165.useCallback((text5)=>dispatch({kind:"system",text:text5}),[]),voice=useVoice(gw.request.bind(gw),sys);import_react165.useEffect(()=>{voice.setOnTranscript((text5)=>{let c=composer2.current;if(!c)return;c.set(""),setTimeout(()=>sendRef.current(text5),0)})},[]),useTerminalTitle(active,info3?.cwd);let[errorPulse,setErrorPulse]=import_react165.useState(!1);import_react165.useEffect(()=>{let restart=(mode2="resume")=>{let sid3=sidRef.current;if(mode2==="resume"&&sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus("gateway restarting"),voice.reset()},exit=(code2)=>{let text5=`gateway exited${code2===null?"":` (${code2})`}`,sid3=sidRef.current;if(sid3)launchRef.current={mode:"resume",sid:sid3,splash:!1};gw.setSession(""),setReady(!1),setStarting(!1),setStatus(text5),setErrorPulse(!0),voice.reset(),dispatch({kind:"system",text:text5})};return gw.on("restart",restart),gw.on("exit",exit),()=>{gw.off("restart",restart),gw.off("exit",exit)}},[gw]);let agentState=errorPulse?"error":turn.toolActive?"working":turn.streaming&&turn.hasContent?"speaking":active?"thinking":composing?"listening":"idle",onAvatarHold=import_react165.useCallback((s)=>{if(s==="error")setErrorPulse(!1)},[]),prompt=import_react165.useMemo(()=>pending2(turn.messages),[turn.messages]),cloudAuto=turn.streaming&&!turn.hasContent&&!prompt,[force,setForce]=import_react165.useState(void 0),cloud=!prompt&&(force??cloudAuto),prevStream=import_react165.useRef(turn.streaming);import_react165.useEffect(()=>{if(!prevStream.current&&turn.streaming)setForce(void 0),setPick(void 0);prevStream.current=turn.streaming},[turn.streaming]);let onPick=import_react165.useCallback((m2)=>{setPick((p)=>{if(m2&&p&&m2.id===p.id){setForce(!1);return}return setForce(!!m2),m2})},[]),onAvatar=import_react165.useCallback(()=>{let next2=!cloud;if(!next2)setPick(void 0);setForce(next2)},[cloud]),closeCloud=import_react165.useCallback(()=>{setForce(!1),setPick(void 0)},[]),intr=import_react165.useRef(()=>{}),steer=import_react165.useCallback((text5)=>{let v2=text5.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>toast.show(r.status==="queued"?{variant:"success",message:"Queued \u2014 lands on next tool result"}:{variant:"info",message:"No turn running; send as a normal message"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast]),openSteer=import_react165.useCallback(()=>{openTextPrompt(dialog,{title:"Steer active turn",label:"Soft nudge for the running session"}).then((v2)=>{if(v2)steer(v2)})},[dialog,steer]),onEnqueue=import_react165.useCallback((t2)=>{if(busy2==="steer"){let v2=t2.trim();if(!v2)return;gw.request("session.steer",{text:v2}).then((r)=>{if(r.status==="queued")return toast.show({variant:"success",message:"Queued \u2014 lands on next tool result"});setQueue((q5)=>[...q5,t2]),toast.show({variant:"info",message:"steer rejected \u2014 queued for next turn"})}).catch(()=>setQueue((q5)=>[...q5,t2]));return}if(busy2==="interrupt"){hold.current=!0,setQueue((q5)=>[t2,...q5]),intr.current();return}setQueue((q5)=>[...q5,t2])},[busy2,gw,toast]),updateAttachments=import_react165.useCallback((next2)=>{let value2=typeof next2==="function"?next2(attachmentsRef.current):next2;attachmentsRef.current=value2,setAttachments(value2)},[]),onAttach=import_react165.useCallback((r)=>updateAttachments((a)=>[...a,r]),[updateAttachments]),stream=useStream({dispatch,session,launchRef,sidRef,sessionStart,goalHook,setSid,setInfo,setReady,setTitle,setBusy,setStarting,setUsage,setStatus,setSkin,setErrorPulse,settle,onVoiceStatus:(state3)=>{voice.setRecording(state3==="listening"||state3==="recording"),voice.setProcessing(state3==="transcribing"||state3==="processing")},onVoiceTranscript:(text5,noSpeechLimit)=>{if(voice.setRecording(!1),voice.setProcessing(!1),noSpeechLimit){voice.setEnabled(!1),sys("voice: disabled after repeated silence");return}voice.onTranscript?.(text5)},start:start2}),interrupt=import_react165.useCallback(()=>{if(startRef.current&&!turnRef.current.streaming)hold.current=!0;stream.doInterrupt()},[stream.doInterrupt]);intr.current=interrupt;let reset4=import_react165.useCallback(()=>{stream.interrupted.current=!1,hold.current=!1,pending3.current=!1,toast.clear("credits.depleted"),undone.current=[],dispatch({kind:"reset"}),setUsage(void 0),setReady(!1),setStarting(!1),setStatus(""),setTitle(""),updateAttachments([])},[toast,updateAttachments]),newSession=import_react165.useCallback(async()=>{if(creating.current)return;creating.current=!0,setSwitching(!0);let prev=sidRef.current;summoned.current=!0,setSplash(!0),setReady(!1),gw.setSession("");try{let r=await session.create();if(reset4(),setSid(r.id),r.info)setInfo(r.info),setUsage(r.info.usage);if(setReady(!0),setStarting(!1),setStatus(""),sessionStart.current=Date.now(),prev)session.close(prev,{preserveBackground:!0})}catch(err){if(prev)gw.setSession(prev),setReady(!0);setSplash(!1),summoned.current=!1,dispatch({kind:"system",text:`Failed to create session: ${err instanceof Error?err.message:String(err)}`})}finally{creating.current=!1,setSwitching(!1)}},[reset4,session,gw]),switchSession=import_react165.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.resume(target2);if(reset4(),setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(setReady(!0),sessionStart.current=Date.now(),res.messages.length)dispatch({kind:"load",messages:res.messages});if(prev&&prev!==res.id)session.close(prev,{preserveBackground:!0});setSplash(!1),summoned.current=!1}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);dispatch({kind:"system",text:`Failed to resume: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1}finally{setSwitching(!1)}},[reset4,session,goToTab,gw]),liveStatus=(state3,running2=!1)=>{if(state3==="waiting")return"waiting for input\u2026";if(state3==="starting")return"starting agent\u2026";return running2||state3==="working"?"running\u2026":"ready"},activateSession=import_react165.useCallback(async(target2)=>{let prev=sidRef.current;summoned.current=!0,setSplash(!0),setSwitching(!0),gw.setSession(""),setSid(""),goToTab(CHAT_TAB);try{let res=await session.activate(target2);if(reset4(),setSid(res.id),res.info)setInfo(res.info),setUsage(res.info.usage);if(sessionStart.current=res.startedAt??Date.now(),dispatch({kind:"load.live",messages:res.messages,streaming:res.running}),setStatus(liveStatus(res.status,res.running)),setReady(!0),setSplash(!1),summoned.current=!1,prev&&prev!==res.id)toast.show({variant:"info",message:"switched live session"});return!0}catch(err){if(prev)gw.setSession(prev),setSid(prev),setReady(!0);return dispatch({kind:"system",text:`Failed to activate: ${err instanceof Error?err.message:String(err)}`}),setSplash(!1),summoned.current=!1,!1}finally{setSwitching(!1)}},[reset4,session,goToTab,toast,gw]),switchProfile=import_react165.useCallback((newHome,name)=>{voice.reset(),rehome(newHome),reset4(),gw.setSession(""),setSid(""),setInfo(null),setSkin(deriveSkin(void 0)),summoned.current=!0,setSplash(!0),launchRef.current={mode:"new",splash:!0},toast.show({variant:"info",message:`Switching to '${name}'\u2026`}),goToTab(CHAT_TAB),gwRestart("new")},[reset4,goToTab,gwRestart,toast,gw]),loadEikon=import_react165.useCallback((path4)=>{try{setEikon(parseEikonFile(path4))}catch{setEikon(void 0)}},[]),eikonName=usePref("eikon"),eikonRev=import_react165.useSyncExternalStore(exports_eikon.onRevision,exports_eikon.revision);import_react165.useEffect(()=>{let p=eikonName&&exports_eikon.baked(eikonName)||bundledEikonPath(skin2.skin?.name);if(p)loadEikon(p);else setEikon(void 0)},[eikonName,eikonRev,skin2.skin?.name,loadEikon]);let messageActions=useMessageActions({gw,dialog,toast,session,activate:activateSession,composer:composer2,turn:turnRef,dispatch,focus:setFocusRegion}),rewind=messageActions.rewind,msgMenu=messageActions.menu,attachClipboard=import_react165.useCallback(()=>{gw.request("clipboard.paste").then((r)=>r.attached?updateAttachments((a)=>[...a,r]):toast.show({variant:"info",message:r.message??"No image in clipboard"})).catch((e)=>toast.show({variant:"error",message:e.message}))},[gw,toast,updateAttachments]),sendRef=import_react165.useRef(()=>{}),slash3=useSlash({dispatch,session,turnRef,queueRef,sendRef,composer:composer2,summoned,undone,capabilities,info:info3,sid:sid2,title:caption,skin:skin2,setQueue,setFocusRegion,setSplash,setAttachments:updateAttachments,setInfo,setUsage,setTitle,newSession,switchSession,activateSession,rewind,goTo,attachClipboard,voiceToggle:voice.toggle}),send=import_react165.useCallback(async(raw2)=>{if(creating.current)return;if(["exit","quit",":q",":q!",":wq"].includes(raw2.trim()))return quit(renderer,sidRef.current,titleRef.current,gw);if(detaching.current>0){if(raw2.trim())composer2.current?.set(raw2);setStatus("detaching image\u2026");return}let m2=raw2.match(/^\/(\S+)(?:\s+([\s\S]*))?$/);if(m2){let[,name,arg=""]=m2,r=resolve9(cmdsRef.current,name);if("hit"in r)return slash3(r.hit,arg.trim());if("ambiguous"in r){let head=r.ambiguous.slice(0,6).join(", ");return dispatch({kind:"system",text:`ambiguous: /${name} \u2192 ${head}${r.ambiguous.length>6?", \u2026":""}`})}}let text5=raw2;if(hasInterp(raw2))setStatus("interpolating\u2026"),text5=await interpolate(gw,raw2),setStatus("");stream.interrupted.current=!1;let att=attachmentsRef.current,withMedia=att.length?[...att.flatMap((a)=>a.path?[`MEDIA:${a.path}`]:[]),text5].filter(Boolean).join(`
4211
+ `):text5;if(pending3.current){setQueue((q5)=>[...q5,raw2]),setStatus("queued for next turn");return}pending3.current=!0,setPulse((n)=>n+1),gw.request("prompt.submit",{text:text5}).then((r)=>{if(dispatch({kind:"user",text:withMedia}),r.status==="streaming"&&!turnRef.current.streaming)setStarting(!0),setStatus("starting agent\u2026");updateAttachments([]),undone.current=[],setTab(CHAT_TAB)}).catch((e)=>{let msg=e instanceof Error?e.message:String(e);if(BUSY_RE.test(msg)){pending3.current=!1,setPulse((n)=>n+1),inflight.current=!0,setQueue((q5)=>[text5,...q5]),setStatus("queued for next turn"),toast.show({variant:"info",message:"queued for next turn"}),setTimeout(()=>{inflight.current=!1,setPulse((n)=>n+1)},400);return}pending3.current=!1,setPulse((n)=>n+1),inflight.current=!1,setStarting(!1),dispatch({kind:"system",text:`submit failed: ${msg}`}),toast.show({variant:"error",message:msg})})},[gw,slash3,toast,updateAttachments]);sendRef.current=send;let onShell=import_react165.useCallback((command)=>{setSplash(!1),dispatch({kind:"system",text:`$ ${command}`}),setStatus("running\u2026"),gw.request("shell.exec",{command}).then((r)=>{let out=(r.stdout??"").trimEnd(),err=(r.stderr??"").trimEnd(),body2=[out,err&&`stderr:
4212
4212
  ${err}`].filter(Boolean).join(`
4213
- `);if(dispatch({kind:"system",text:body2||`(exit ${r.code??0})`}),(r.code??0)!==0)toast.show({variant:"warning",message:`exit ${r.code}`})}).catch((e)=>dispatch({kind:"system",text:`error: ${e.message}`})).finally(()=>setStatus(""))},[gw,toast]),onSend=import_react163.useCallback((raw2)=>{return setSplash(!1),send(raw2)},[send]),onEmptyEnter=import_react163.useCallback(()=>{if(!splash||summoned.current||!splashLast||composing)return!1;return setSplash(!1),switchSession(splashLast.id),!0},[splash,splashLast,composing,switchSession]);import_react163.useEffect(()=>{if(turn.streaming)start2()},[turn.streaming,start2]),import_react163.useEffect(()=>{if(!capabilities.canDrainQueue||inflight.current||hold.current||pending3.current||queue.length===0)return;let[head,...rest]=queue;inflight.current=!0,setQueue(rest),send(head)},[capabilities.canDrainQueue,queue,send,pulse]);let dequeue=import_react163.useCallback((i)=>{let item=queueRef.current[i];if(item===void 0)return;setQueue((q5)=>q5.filter((_2,j2)=>j2!==i)),composer2.current?.set(item),setFocusRegion("input")},[]),extra=plugins.routes,all2=import_react163.useMemo(()=>[...TABS,...extra.map((r)=>({name:r.name,description:r.description??"Plugin"}))],[extra]),routeName=import_react163.useRef(void 0),routesRef=import_react163.useRef(extra),tabMax=all2.length-1;import_react163.useEffect(()=>{plugins.bind(goTo,()=>all2[tab]?.name)},[plugins,goTo,all2,tab]),import_react163.useEffect(()=>{let changed2=routesRef.current!==extra;if(routesRef.current=extra,changed2&&tab>=TABS.length){let next2=extra.findIndex((route2)=>route2.name===routeName.current);if(next2<0){goToTab(CHAT_TAB);return}let index4=TABS.length+next2;if(index4!==tab){goToTab(index4);return}}routeName.current=all2[tab]?.name},[extra,all2,tab,goToTab]);let subCount=SUB_TABS[tab]?.length??0,cycleSub=import_react163.useCallback((dir2)=>{let labels=SUB_TABS[tab];if(!labels||labels.length===0)return;setSubTabs((prev)=>{let cur=prev[tab]??0,next2=(cur+dir2+labels.length)%labels.length;return next2===cur?prev:{...prev,[tab]:next2}})},[tab]);useAppKeys({tab,tabMax,chatTab:CHAT_TAB,setTab,subCount,cycleSub,focusRegion,setFocusRegion,streaming:turn.streaming,starting,dialogOpen:dialog.open,composer:composer2,onPromptKey:(k2)=>promptRef.current?.feed(k2)??!1,onEscape:()=>{if(!splash||!summoned.current)return!1;return setSplash(!1),summoned.current=!1,!0},onInterrupt:interrupt,queued:queue.length,onFlushQueue:()=>{hold.current=!0,interrupt()},onQuit:()=>quit(renderer,sid2,caption,gw),onQuitArm:(label3)=>toast.show({variant:"info",message:`${label3} again to quit`}),onInterruptNotice:()=>{setEscHint(!0),setTimeout(()=>setEscHint(!1),5000)},onCopyLast:()=>{let m2=[...turnRef.current.messages].reverse().find((x2)=>x2.role==="assistant"&&text2(x2));if(m2)copyText(text2(m2),toast)},onCopyToast:toast.show,onAttachClipboard:attachClipboard,onDetachLast:()=>{if(detaching.current>0)return setStatus("detaching image\u2026"),!0;let target2=attachmentsRef.current.at(-1);if(!target2?.path)return!1;return detaching.current+=1,setStatus("detaching image\u2026"),setPulse((n)=>n+1),gw.request("image.detach",{path:target2.path}).then(()=>updateAttachments((a)=>a.filter((x2)=>x2.path!==target2.path))).catch((e)=>toast.show({variant:"error",message:e.message})).finally(()=>{detaching.current=Math.max(0,detaching.current-1),setStatus(""),setPulse((n)=>n+1)}),!0},onNotice:(text5)=>dispatch({kind:"system",text:text5}),onToggleSidebar:()=>setHideSidebar((v2)=>!v2),onSteer:openSteer,onStash:()=>{let c=composer2.current,v2=c?.value().trim()??"";if(!v2){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});c?.set(e.text);return}let n=exports_stash.push(v2);c?.set(""),toast.show({variant:"info",message:`stashed (${n})`})},voiceRecordKey:voice.state.recordKey,voiceEnabled:voice.state.enabled,onVoiceRecord:()=>voice.record(sidRef.current)}),useBridge({tab,ready,streaming:active,messages:turn.messages,sid:sid2,focusRegion,setTab,setFocusRegion,dispatch,composer:composer2});let contentFocused=focusRegion==="content"&&!active&&!dialogOpen,promptAnswer=import_react163.useCallback((id,label3,ok)=>dispatch({kind:"prompt.answered",id,label:label3,ok}),[]),promptWire=import_react163.useMemo(()=>({ref:promptRef,onAnswer:promptAnswer}),[promptAnswer]);import_react163.useEffect(()=>{if(prompt&&tab!==CHAT_TAB)setTab(CHAT_TAB)},[prompt?.id]);let content=()=>{let inner=(()=>{switch(tab){case CHAT_TAB:return $jsx(Chat,{messages:turn.messages,streaming:turn.streaming,prompt:promptWire,cloud,cloudH,pick:pick2,onResize:setCloudH,onPick,onClose:closeCloud,onRewind:msgMenu});case SESSIONS_TAB:return $jsx(SessionsGroup,{focused:contentFocused,sub:subTabs[SESSIONS_TAB]??0,setSub:sessSub,onSwitch:switchSession,onActivateLive:activateSession,currentId:sid2,messages:turn.messages,sessionStart:sessionStart.current,info:info3??void 0,usage});case AUTOMATION_TAB:return $jsx(Automation,{focused:contentFocused,sub:subTabs[AUTOMATION_TAB]??0,setSub:autoSub,sessionId:sid2,onSwitchProfile:switchProfile});case CONFIG_TAB:return $jsx(ConfigGroup,{focused:contentFocused,sub:subTabs[CONFIG_TAB]??0,setSub:cfgSub});case EIKON_TAB:return $jsx(EikonGroup,{focused:contentFocused,sub:subTabs[EIKON_TAB]??0,setSub:eikSub});default:{let r=extra[tab-TABS.length];return r?r.render({focused:contentFocused}):null}}})(),name=all2[tab]?.name??"unknown";return $jsx(import_react163.Profiler,{id:`tab:${name}`,onRender,children:inner})},theme=themeCtx.theme,onMouseUp=import_react163.useCallback(()=>copySelection(renderer,toast),[renderer,toast]),inputFocused=focusRegion==="input"&&!prompt&&!dialogOpen,sidebarVisible=dims.width>=(tab===CHAT_TAB?120:140)&&!hideSidebar,branch2=useGitBranch(info3?.cwd),hidden3=!sidebarVisible?hidden2({info:info3,usage,profile:activeProfileName(),title:caption,branch:branch2}):void 0;return $jsx(import_react163.Profiler,{id:"shell",onRender,children:$jsx(SkinProvider,{value:skin2,children:$jsxs("box",{width:"100%",height:"100%",flexDirection:"column",backgroundColor:theme.background,onMouseUp,children:[$jsx(TabBar,{tabs:all2,activeTab:tab,onTabChange:goToTab}),$jsxs("box",{flexGrow:1,flexDirection:"row",children:[$jsxs("box",{flexGrow:1,flexDirection:"column",children:[$jsxs("box",{flexGrow:1,position:"relative",children:[content(),splash&&tab===CHAT_TAB?$jsx(Splash,{info:splashInfo,last:summoned.current?void 0:splashLastProp,composing,news,loading:switching||!info3}):null]}),$jsxs("box",{flexShrink:0,zIndex:1,children:[$jsx(VoiceIndicator,{voice:voice.state,keyLabel:voice.keyLabel}),$jsx(Composer,{ref:composer2,focused:inputFocused,canSubmitPrompt:capabilities.canSubmitPrompt&&detaching.current===0,ready,streaming:active||pending3.current,starting,status:status2,model:info3?.model,subagents:usage?.active_subagents??info3?.usage?.active_subagents,hidden:hidden3,escHint,queue,attachments,cmds,onSend,onSlash:slash3,onShell,onAttach,onAttachClipboard:attachClipboard,onEnqueue,onDequeue:dequeue,onDirty:setComposing,onEmptyEnter})]})]}),sidebarVisible?$jsx(import_react163.Profiler,{id:"sidebar",onRender,children:$jsx(Sidebar,{agentState,info:info3,usage,eikon,profile:activeProfileName(),title:caption,cloud:tab===0&&cloud,pulse:active,onAvatar,onAvatarHold})}):null]}),plugins.has("app_bottom")?$jsx("box",{height:1,flexShrink:0,paddingX:1,overflow:"hidden",children:$jsx(plugins.Slot,{name:"app_bottom",mode:"single_winner",sid:sid2,tab,streaming:active})}):null]})})})};var EIKON_CLI_USAGE=`herm eikon \u2014 install and manage Herm avatars
4213
+ `);if(dispatch({kind:"system",text:body2||`(exit ${r.code??0})`}),(r.code??0)!==0)toast.show({variant:"warning",message:`exit ${r.code}`})}).catch((e)=>dispatch({kind:"system",text:`error: ${e.message}`})).finally(()=>setStatus(""))},[gw,toast]),onSend=import_react165.useCallback((raw2)=>{return setSplash(!1),send(raw2)},[send]),onEmptyEnter=import_react165.useCallback(()=>{if(!splash||summoned.current||!splashLast||composing)return!1;return setSplash(!1),switchSession(splashLast.id),!0},[splash,splashLast,composing,switchSession]);import_react165.useEffect(()=>{if(turn.streaming)start2()},[turn.streaming,start2]),import_react165.useEffect(()=>{if(!capabilities.canDrainQueue||inflight.current||hold.current||pending3.current||queue.length===0)return;let[head,...rest]=queue;inflight.current=!0,setQueue(rest),send(head)},[capabilities.canDrainQueue,queue,send,pulse]);let dequeue=import_react165.useCallback((i)=>{let item=queueRef.current[i];if(item===void 0)return;setQueue((q5)=>q5.filter((_2,j2)=>j2!==i)),composer2.current?.set(item),setFocusRegion("input")},[]),extra=plugins.routes,all2=import_react165.useMemo(()=>[...TABS,...extra.map((r)=>({name:r.name,description:r.description??"Plugin"}))],[extra]),routeName=import_react165.useRef(void 0),routesRef=import_react165.useRef(extra),tabMax=all2.length-1;import_react165.useEffect(()=>{plugins.bind(goTo,()=>all2[tab]?.name)},[plugins,goTo,all2,tab]),import_react165.useEffect(()=>{let changed2=routesRef.current!==extra;if(routesRef.current=extra,changed2&&tab>=TABS.length){let next2=extra.findIndex((route2)=>route2.name===routeName.current);if(next2<0){goToTab(CHAT_TAB);return}let index4=TABS.length+next2;if(index4!==tab){goToTab(index4);return}}routeName.current=all2[tab]?.name},[extra,all2,tab,goToTab]);let subCount=SUB_TABS[tab]?.length??0,cycleSub=import_react165.useCallback((dir2)=>{let labels=SUB_TABS[tab];if(!labels||labels.length===0)return;setSubTabs((prev)=>{let cur=prev[tab]??0,next2=(cur+dir2+labels.length)%labels.length;return next2===cur?prev:{...prev,[tab]:next2}})},[tab]);useAppKeys({tab,tabMax,chatTab:CHAT_TAB,setTab,subCount,cycleSub,focusRegion,setFocusRegion,streaming:turn.streaming,starting,dialogOpen:dialog.open,composer:composer2,onPromptKey:(k2)=>promptRef.current?.feed(k2)??!1,onEscape:()=>{if(!splash||!summoned.current)return!1;return setSplash(!1),summoned.current=!1,!0},onInterrupt:interrupt,queued:queue.length,onFlushQueue:()=>{hold.current=!0,interrupt()},onQuit:()=>quit(renderer,sid2,caption,gw),onQuitArm:(label3)=>toast.show({variant:"info",message:`${label3} again to quit`}),onInterruptNotice:()=>{setEscHint(!0),setTimeout(()=>setEscHint(!1),5000)},onCopyLast:()=>{let m2=[...turnRef.current.messages].reverse().find((x2)=>x2.role==="assistant"&&text2(x2));if(m2)copyText(text2(m2),toast)},onCopyToast:toast.show,onAttachClipboard:attachClipboard,onDetachLast:()=>{if(detaching.current>0)return setStatus("detaching image\u2026"),!0;let target2=attachmentsRef.current.at(-1);if(!target2?.path)return!1;return detaching.current+=1,setStatus("detaching image\u2026"),setPulse((n)=>n+1),gw.request("image.detach",{path:target2.path}).then(()=>updateAttachments((a)=>a.filter((x2)=>x2.path!==target2.path))).catch((e)=>toast.show({variant:"error",message:e.message})).finally(()=>{detaching.current=Math.max(0,detaching.current-1),setStatus(""),setPulse((n)=>n+1)}),!0},onNotice:(text5)=>dispatch({kind:"system",text:text5}),onToggleSidebar:()=>setHideSidebar((v2)=>!v2),onSteer:openSteer,onStash:()=>{let c=composer2.current,v2=c?.value().trim()??"";if(!v2){let e=exports_stash.pop();if(!e)return toast.show({variant:"info",message:"stash empty"});c?.set(e.text);return}let n=exports_stash.push(v2);c?.set(""),toast.show({variant:"info",message:`stashed (${n})`})},voiceRecordKey:voice.state.recordKey,voiceEnabled:voice.state.enabled,onVoiceRecord:()=>voice.record(sidRef.current)}),useBridge({tab,ready,streaming:active,messages:turn.messages,sid:sid2,focusRegion,setTab,setFocusRegion,dispatch,composer:composer2});let contentFocused=focusRegion==="content"&&!active&&!dialogOpen,promptAnswer=import_react165.useCallback((id,label3,ok)=>dispatch({kind:"prompt.answered",id,label:label3,ok}),[]),promptWire=import_react165.useMemo(()=>({ref:promptRef,onAnswer:promptAnswer}),[promptAnswer]);import_react165.useEffect(()=>{if(prompt&&tab!==CHAT_TAB)setTab(CHAT_TAB)},[prompt?.id]);let content=()=>{let inner=(()=>{switch(tab){case CHAT_TAB:return $jsx(Chat,{messages:turn.messages,streaming:turn.streaming,prompt:promptWire,cloud,cloudH,pick:pick2,onResize:setCloudH,onPick,onClose:closeCloud,onRewind:msgMenu});case SESSIONS_TAB:return $jsx(SessionsGroup,{focused:contentFocused,sub:subTabs[SESSIONS_TAB]??0,setSub:sessSub,onSwitch:switchSession,onActivateLive:activateSession,currentId:sid2,messages:turn.messages,sessionStart:sessionStart.current,info:info3??void 0,usage});case AUTOMATION_TAB:return $jsx(Automation,{focused:contentFocused,sub:subTabs[AUTOMATION_TAB]??0,setSub:autoSub,sessionId:sid2,onSwitchProfile:switchProfile});case CONFIG_TAB:return $jsx(ConfigGroup,{focused:contentFocused,sub:subTabs[CONFIG_TAB]??0,setSub:cfgSub});case EIKON_TAB:return $jsx(EikonGroup,{focused:contentFocused,sub:subTabs[EIKON_TAB]??0,setSub:eikSub});default:{let r=extra[tab-TABS.length];return r?r.render({focused:contentFocused}):null}}})(),name=all2[tab]?.name??"unknown";return $jsx(import_react165.Profiler,{id:`tab:${name}`,onRender,children:inner})},theme=themeCtx.theme,onMouseUp=import_react165.useCallback(()=>copySelection(renderer,toast),[renderer,toast]),inputFocused=focusRegion==="input"&&!prompt&&!dialogOpen,sidebarVisible=dims.width>=(tab===CHAT_TAB?120:140)&&!hideSidebar,branch2=useGitBranch(info3?.cwd),hidden3=!sidebarVisible?hidden2({info:info3,usage,profile:activeProfileName(),title:caption,branch:branch2}):void 0;return $jsx(import_react165.Profiler,{id:"shell",onRender,children:$jsx(SkinProvider,{value:skin2,children:$jsxs("box",{width:"100%",height:"100%",flexDirection:"column",backgroundColor:theme.background,onMouseUp,children:[$jsx(TabBar,{tabs:all2,activeTab:tab,onTabChange:goToTab}),$jsxs("box",{flexGrow:1,flexDirection:"row",children:[$jsxs("box",{flexGrow:1,flexDirection:"column",children:[$jsxs("box",{flexGrow:1,position:"relative",children:[content(),splash&&tab===CHAT_TAB?$jsx(Splash,{info:splashInfo,last:summoned.current?void 0:splashLastProp,composing,news,loading:switching||!info3}):null]}),$jsxs("box",{flexShrink:0,zIndex:1,children:[$jsx(VoiceIndicator,{voice:voice.state,keyLabel:voice.keyLabel}),$jsx(Composer,{ref:composer2,focused:inputFocused,canSubmitPrompt:capabilities.canSubmitPrompt&&detaching.current===0,ready,streaming:active||pending3.current,starting,status:status2,model:info3?.model,subagents:usage?.active_subagents??info3?.usage?.active_subagents,hidden:hidden3,escHint,queue,attachments,cmds,onSend,onSlash:slash3,onShell,onAttach,onAttachClipboard:attachClipboard,onEnqueue,onDequeue:dequeue,onDirty:setComposing,onEmptyEnter})]})]}),sidebarVisible?$jsx(import_react165.Profiler,{id:"sidebar",onRender,children:$jsx(Sidebar,{agentState,info:info3,usage,eikon,profile:activeProfileName(),title:caption,cloud:tab===0&&cloud,pulse:active,onAvatar,onAvatarHold})}):null]}),plugins.has("app_bottom")?$jsx("box",{height:1,flexShrink:0,paddingX:1,overflow:"hidden",children:$jsx(plugins.Slot,{name:"app_bottom",mode:"single_winner",sid:sid2,tab,streaming:active})}):null]})})})};var EIKON_CLI_USAGE=`herm eikon \u2014 install and manage Herm avatars
4214
4214
 
4215
4215
  Usage:
4216
4216
  herm eikon search [query] [--json]
@@ -4237,5 +4237,5 @@ Run 'herm eikon use ${out.name}' to activate.`)}if(cmd==="search"||cmd==="browse
4237
4237
  source: ${out.source.kind} ${out.source.identity??out.source.origin??"unknown"}
4238
4238
  trust: ${out.trust}`)}if(cmd==="list"){let rows3=deps.list().map((e)=>({name:e.name,file:e.file,hasSource:e.hasSource,sourceUrl:e.sourceUrl,lifecycle:e.lifecycle})),active=deps.getActive()??null;if(p.json)return emit(io2,JSON.stringify({ok:!0,active,eikons:rows3}));return emit(io2,rows3.length?rows3.map((e)=>`${e.name}${e.name===active?" *":""}`).join(`
4239
4239
  `):"No installed eikons")}if(cmd==="use"){let name=p.values[0];if(!name)return emitError(io2,"usage: herm eikon use <name>",p.json);if(!deps.has(name)&&!deps.baked(name))return emitError(io2,`No installed or bundled eikon named '${name}'`,p.json);if(deps.setActive(name),p.json)return emit(io2,JSON.stringify({ok:!0,active:name}));return emit(io2,`Avatar \u2192 ${name}`)}if(cmd==="remove"){let name=p.values[0];if(!name)return emitError(io2,"usage: herm eikon remove <name>",p.json);if(!deps.has(name))return emitError(io2,`No installed eikon named '${name}'`,p.json);let wasActive=deps.getActive()===name,result=deps.remove(name,{confirmActive:p.activeOk});if(result?.type==="active-consequence")return emitError(io2,activeMessage(result),p.json,{consequence:"active",action:result.action,name:result.name});if(p.json)return emit(io2,JSON.stringify({ok:!0,name,removed:!0,activeCleared:wasActive}));return emit(io2,`Removed '${name}'${wasActive?" and cleared active avatar":""}`)}if(cmd==="update"){let name=p.values[0];if(!name)return emitError(io2,"usage: herm eikon update <name>",p.json);let out=await deps.update(name,{confirmActive:p.activeOk});if(isActiveConsequence(out))return emitError(io2,activeMessage(out),p.json,{consequence:"active",action:out.action,name:out.name});let active=deps.getActive()??null;if(p.json)return emit(io2,JSON.stringify({ok:!0,name:out.name,n:out.n,bytes:out.bytes,active}));return emit(io2,`Updated '${out.name}' (${out.n} files)`)}return emitError(io2,`unknown eikon command '${cmd}'`,p.json)}catch(e){return emitError(io2,e instanceof Error?e.message:String(e),p.json)}}init_perf();var exports_bundled_skills={};__export(exports_bundled_skills,{sync:()=>sync,skills:()=>exports_bundled_skills});import{existsSync as existsSync34,mkdirSync as mkdirSync10,readdirSync as readdirSync13,cpSync as cpSync2}from"fs";import{dirname as dirname15,join as join30}from"path";var locate4=()=>{let d2=import.meta.dir;for(let i=0;i<5;i++){let p=join30(d2,"assets/skills");if(existsSync34(p))return p;let up=dirname15(d2);if(up===d2)break;d2=up}return};function has2(root3,n){if(existsSync34(join30(root3,n,"SKILL.md")))return!0;if(!existsSync34(root3))return!1;return readdirSync13(root3,{withFileTypes:!0}).some((e)=>e.isDirectory()&&existsSync34(join30(root3,e.name,n,"SKILL.md")))}function sync(){let src3=locate4();if(!src3)return[];let root3=hermesPath("skills"),dst=join30(root3,"creative"),out=[];for(let e of readdirSync13(src3,{withFileTypes:!0})){if(!e.isDirectory())continue;if(has2(root3,e.name))continue;mkdirSync10(dst,{recursive:!0}),cpSync2(join30(src3,e.name),join30(dst,e.name),{recursive:!0}),out.push(e.name)}return out}var exports_bundled_plugins={};__export(exports_bundled_plugins,{sync:()=>sync2,plugins:()=>exports_bundled_plugins});import{cpSync as cpSync3,existsSync as existsSync35,mkdirSync as mkdirSync11,readFileSync as readFileSync25,readdirSync as readdirSync14,writeFileSync as writeFileSync12}from"fs";import{dirname as dirname16,join as join31}from"path";var locate5=()=>{let dir2=import.meta.dir;for(let i=0;i<5;i++){let path4=join31(dir2,"assets/plugins");if(existsSync35(path4))return path4;let up=dirname16(dir2);if(up===dir2)break;dir2=up}return},obj2=(v2)=>v2&&typeof v2==="object"&&!Array.isArray(v2)?v2:{},arr3=(v2)=>Array.isArray(v2)?v2.map(String):[];function ours(dir2){let path4=join31(dir2,"plugin.yaml");if(!existsSync35(path4))return!1;let raw2=readFileSync25(path4,"utf8");return raw2.includes("name: eikon")&&raw2.includes("eikon_install")}function enable(name){let path4=hermesPath("config.yaml"),raw2=existsSync35(path4)?readFileSync25(path4,"utf8"):"",doc=$parseDocument(raw2||`{}
4240
- `),js=doc.toJS();if(!js||typeof js!=="object"||Array.isArray(js))doc.contents=doc.createNode({});let cfg=obj2(doc.toJS()),plug=obj2(cfg.plugins);if(arr3(plug.disabled).includes(name)||arr3(plug.enabled).includes(name))return!1;return doc.setIn(["plugins","enabled"],[...arr3(plug.enabled),name]),mkdirSync11(dirname16(path4),{recursive:!0}),writeFileSync12(path4,String(doc),"utf8"),!0}function sync2(){let src3=locate5();if(!src3)return[];let root3=hermesPath("plugins"),out=[];for(let e of readdirSync14(src3,{withFileTypes:!0})){if(!e.isDirectory())continue;try{let dst=join31(root3,e.name),fresh2=!existsSync35(dst);if(fresh2)mkdirSync11(root3,{recursive:!0}),cpSync3(join31(src3,e.name),dst,{recursive:!0}),out.push(e.name);if(fresh2||ours(dst))enable(e.name)}catch{}}return out}import{writeSync as writeSync2}from"fs";var TERMINAL_MODE_RESET="\x1B[0'z\x1B[0'{\x1B[?2029l\x1B[?1016l\x1B[?1015l\x1B[?1006l\x1B[?1005l\x1B[?1003l\x1B[?1002l\x1B[?1001l\x1B[?1000l\x1B[?9l\x1B[?1004l\x1B[?2004l\x1B[?1049l\x1B[<u\x1B[>4;0m\x1B[0m\x1B[?25h";function resetTerminalModes(stream=process.stdout){if(!stream.isTTY)return!1;let fd=typeof stream.fd==="number"?stream.fd:stream===process.stdout?1:void 0;if(fd!==void 0)try{return writeSync2(fd,TERMINAL_MODE_RESET),!0}catch{}try{return stream.write(TERMINAL_MODE_RESET),!0}catch{return!1}}var wired=!1;function installExitResetHooks(){if(wired)return;wired=!0,process.on("exit",()=>{resetTerminalModes()});let codes={SIGHUP:129,SIGINT:130,SIGTERM:143};for(let sig of["SIGINT","SIGTERM","SIGHUP"])process.on(sig,()=>{resetTerminalModes(),process.exit(codes[sig])});process.on("uncaughtException",(err)=>{resetTerminalModes(),console.error(err),process.exit(1)}),process.on("unhandledRejection",(reason)=>{resetTerminalModes(),console.error(reason),process.exit(1)})}var cfg={columns:{fallback:80,max:500},rows:{fallback:24,max:200}};function sanitizeTerminalDimension(value2,dim2){if(typeof value2!=="number")return cfg[dim2].fallback;if(!Number.isFinite(value2))return cfg[dim2].fallback;let n=Math.floor(value2);if(n<2)return cfg[dim2].fallback;return Math.min(n,cfg[dim2].max)}function findDescriptor(stream,dim2){let cur=stream;while(cur){let desc=Object.getOwnPropertyDescriptor(cur,dim2);if(desc)return desc;cur=Object.getPrototypeOf(cur)}return}function patchDimension(stream,dim2){let desc=findDescriptor(stream,dim2);if(desc&&desc.configurable===!1)return!1;let raw2=desc&&"value"in desc?desc.value:void 0,read5=desc?.get,write=desc?.set;try{return Object.defineProperty(stream,dim2,{configurable:!0,enumerable:desc?.enumerable??!0,get(){let value2=read5?read5.call(stream):raw2;return sanitizeTerminalDimension(value2,dim2)},set(value2){if(write){write.call(stream,value2);return}raw2=value2}}),!0}catch{return!1}}function clampStdoutDimensions(stream=process.stdout){if(!stream||typeof stream!=="object")return!1;let columns=patchDimension(stream,"columns"),rows3=patchDimension(stream,"rows");return columns||rows3}boot("import-graph",Bun.nanoseconds()/1e6);var argv=Bun.argv.slice(2);if(argv[0]==="eikon"&&argv[1]==="install")exports_bundled_plugins.sync();var eikonCliExit=await handleEikonCli(argv);if(eikonCliExit!==null)process.exit(eikonCliExit);if(argv.includes("--help")||argv.includes("-h"))process.stdout.write(HELP3),process.exit(0);if(argv.includes("--version")||argv.includes("-v"))process.stdout.write(VERSION+`
4241
- `),process.exit(0);var launch=parseLaunch(argv);if(launch.gateway)process.env.HERM_GATEWAY_URL=launch.gateway;if(launch.profile){let home5=resolveProfileHome(launch.profile);if(!home5)throw Error(`profile not found: ${launch.profile}`);rehome(home5)}var main2=async()=>{resetTerminalModes(),installExitResetHooks(),clampStdoutDimensions(),mem("pre-renderer");let prefs=load2(),end=mark("renderer-init"),renderer=await createCliRenderer({exitOnCtrlC:!1,useMouse:prefs.mouse??!0,targetFps:prefs.targetFps??30,gatherStats:!1});renderer.setMaxListeners(64),end();let bump3=()=>renderer.capabilities?.kitty_keyboard||process.stdout.isTTY&&process.stdout.write("\x1B[>4;2m");bump3(),renderer.on("focus",bump3),mem("post-renderer"),await prime(prefs.theme??DEFAULT_THEME);let root3=createRoot(renderer),endRender=mark("first-render");root3.render($jsx(App,{initialTheme:prefs.theme,launch})),endRender(),boot("first-render",Bun.nanoseconds()/1e6),warmup(),warm(),exports_bundled_skills.sync(),exports_bundled_plugins.sync(),mem("post-first-render"),monitor(15000),start()};main2().catch(console.error);
4240
+ `),js=doc.toJS();if(!js||typeof js!=="object"||Array.isArray(js))doc.contents=doc.createNode({});let cfg=obj2(doc.toJS()),plug=obj2(cfg.plugins);if(arr3(plug.disabled).includes(name)||arr3(plug.enabled).includes(name))return!1;return doc.setIn(["plugins","enabled"],[...arr3(plug.enabled),name]),mkdirSync11(dirname16(path4),{recursive:!0}),writeFileSync12(path4,String(doc),"utf8"),!0}function sync2(){let src3=locate5();if(!src3)return[];let root3=hermesPath("plugins"),out=[];for(let e of readdirSync14(src3,{withFileTypes:!0})){if(!e.isDirectory())continue;try{let dst=join31(root3,e.name),fresh2=!existsSync35(dst);if(fresh2)mkdirSync11(root3,{recursive:!0}),cpSync3(join31(src3,e.name),dst,{recursive:!0}),out.push(e.name);if(fresh2||ours(dst))enable(e.name)}catch{}}return out}import{writeSync as writeSync2}from"fs";var TERMINAL_MODE_RESET="\x1B[0'z\x1B[0'{\x1B[?2029l\x1B[?1016l\x1B[?1015l\x1B[?1006l\x1B[?1005l\x1B[?1003l\x1B[?1002l\x1B[?1001l\x1B[?1000l\x1B[?9l\x1B[?1004l\x1B[?2004l\x1B[?1049l\x1B[<u\x1B[>4;0m\x1B[0m\x1B[?25h";function resetTerminalModes(stream=process.stdout){if(!stream.isTTY)return!1;let fd=typeof stream.fd==="number"?stream.fd:stream===process.stdout?1:void 0;if(fd!==void 0)try{return writeSync2(fd,TERMINAL_MODE_RESET),!0}catch{}try{return stream.write(TERMINAL_MODE_RESET),!0}catch{return!1}}var wired=!1;function installExitResetHooks(){if(wired)return;wired=!0,process.on("exit",()=>{resetTerminalModes()});let codes={SIGHUP:129,SIGINT:130,SIGTERM:143};for(let sig of["SIGINT","SIGTERM","SIGHUP"])process.on(sig,()=>{resetTerminalModes(),process.exit(codes[sig])});process.on("uncaughtException",(err)=>{resetTerminalModes(),console.error(err),process.exit(1)}),process.on("unhandledRejection",(reason)=>{resetTerminalModes(),console.error(reason),process.exit(1)})}var cfg={columns:{fallback:80,max:500},rows:{fallback:24,max:200}};function sanitizeTerminalDimension(value2,dim2){if(typeof value2!=="number")return cfg[dim2].fallback;if(!Number.isFinite(value2))return cfg[dim2].fallback;let n=Math.floor(value2);if(n<2)return cfg[dim2].fallback;return Math.min(n,cfg[dim2].max)}function findDescriptor(stream,dim2){let cur=stream;while(cur){let desc=Object.getOwnPropertyDescriptor(cur,dim2);if(desc)return desc;cur=Object.getPrototypeOf(cur)}return}function patchDimension(stream,dim2){let desc=findDescriptor(stream,dim2);if(desc&&desc.configurable===!1)return!1;let raw2=desc&&"value"in desc?desc.value:void 0,read5=desc?.get,write=desc?.set;try{return Object.defineProperty(stream,dim2,{configurable:!0,enumerable:desc?.enumerable??!0,get(){let value2=read5?read5.call(stream):raw2;return sanitizeTerminalDimension(value2,dim2)},set(value2){if(write){write.call(stream,value2);return}raw2=value2}}),!0}catch{return!1}}function clampStdoutDimensions(stream=process.stdout){if(!stream||typeof stream!=="object")return!1;let columns=patchDimension(stream,"columns"),rows3=patchDimension(stream,"rows");return columns||rows3}function fatal(err){resetTerminalModes(),console.error(err),process.exit(1)}boot("import-graph",Bun.nanoseconds()/1e6);var argv=Bun.argv.slice(2);if(argv[0]==="eikon"&&argv[1]==="install")exports_bundled_plugins.sync();var eikonCliExit=await handleEikonCli(argv);if(eikonCliExit!==null)process.exit(eikonCliExit);if(argv.includes("--help")||argv.includes("-h"))process.stdout.write(HELP3),process.exit(0);if(argv.includes("--version")||argv.includes("-v"))process.stdout.write(VERSION+`
4241
+ `),process.exit(0);var launch=parseLaunch(argv);if(launch.gateway)process.env.HERM_GATEWAY_URL=launch.gateway;if(launch.profile){let home5=resolveProfileHome(launch.profile);if(!home5)throw Error(`profile not found: ${launch.profile}`);rehome(home5)}var main2=async()=>{resetTerminalModes(),installExitResetHooks(),clampStdoutDimensions(),mem("pre-renderer");let prefs=load2(),end=mark("renderer-init"),renderer=await createCliRenderer({exitOnCtrlC:!1,useMouse:prefs.mouse??!0,targetFps:prefs.targetFps??30,gatherStats:!1});renderer.setMaxListeners(64),end();let bump3=()=>renderer.capabilities?.kitty_keyboard||process.stdout.isTTY&&process.stdout.write("\x1B[>4;2m");bump3(),renderer.on("focus",bump3),mem("post-renderer"),await prime(prefs.theme??DEFAULT_THEME);let root3=createRoot(renderer),endRender=mark("first-render");root3.render($jsx(App,{initialTheme:prefs.theme,launch})),endRender(),boot("first-render",Bun.nanoseconds()/1e6),warmup(),warm(),exports_bundled_skills.sync(),exports_bundled_plugins.sync(),mem("post-first-render"),monitor(15000),start()};main2().catch(fatal);