@pi-unipi/unipi 3.0.0-alpha.2 → 3.0.0-alpha.21

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 (359) hide show
  1. package/CHANGELOG.md +292 -0
  2. package/README.md +8 -11
  3. package/docs/prefix-cache-architecture.md +14 -0
  4. package/package.json +22 -24
  5. package/packages/ask-user/README.md +55 -107
  6. package/packages/ask-user/ask-ui.ts +306 -732
  7. package/packages/ask-user/clipboard.ts +50 -0
  8. package/packages/ask-user/config.ts +74 -78
  9. package/packages/ask-user/package.json +2 -2
  10. package/packages/ask-user/questions.ts +151 -0
  11. package/packages/ask-user/skills/ask-user/SKILL.md +59 -133
  12. package/packages/ask-user/tools.ts +198 -432
  13. package/packages/autocomplete/package.json +1 -1
  14. package/packages/autocomplete/src/constants.ts +38 -43
  15. package/packages/autocomplete/src/sorting.ts +8 -0
  16. package/packages/background-tasks/package.json +2 -2
  17. package/packages/background-tasks/src/config.ts +0 -73
  18. package/packages/background-tasks/src/index.ts +20 -16
  19. package/packages/background-tasks/src/registry.ts +1 -171
  20. package/packages/background-tasks/src/types.ts +0 -32
  21. package/packages/btw/README.md +13 -56
  22. package/packages/btw/extensions/btw.ts +403 -1796
  23. package/packages/btw/package.json +5 -2
  24. package/packages/btw/skills/btw/SKILL.md +7 -143
  25. package/packages/compactor/README.md +56 -287
  26. package/packages/compactor/package.json +5 -9
  27. package/packages/compactor/skills/compactor/SKILL.md +13 -20
  28. package/packages/compactor/src/card.ts +90 -0
  29. package/packages/compactor/src/commands/index.ts +73 -130
  30. package/packages/compactor/src/compaction/compact-args.ts +5 -3
  31. package/packages/compactor/src/compaction/filter-noise.ts +1 -1
  32. package/packages/compactor/src/compaction/hooks.ts +487 -311
  33. package/packages/compactor/src/compaction/source.ts +178 -0
  34. package/packages/compactor/src/compaction/summarize.ts +586 -52
  35. package/packages/compactor/src/config/manager.ts +130 -127
  36. package/packages/compactor/src/config/schema.ts +32 -48
  37. package/packages/compactor/src/index.ts +40 -431
  38. package/packages/compactor/src/info-screen.ts +44 -190
  39. package/packages/compactor/src/session/recall-blocks.ts +1 -1
  40. package/packages/compactor/src/stats.ts +76 -0
  41. package/packages/compactor/src/tools/context-budget.ts +17 -34
  42. package/packages/compactor/src/tools/ctx-doctor.ts +45 -36
  43. package/packages/compactor/src/tools/register.ts +29 -269
  44. package/packages/compactor/src/types.ts +47 -186
  45. package/packages/core/README.md +25 -0
  46. package/packages/core/child-agent.ts +1 -0
  47. package/packages/core/command-echo.ts +63 -0
  48. package/packages/core/compaction-context.ts +41 -0
  49. package/packages/core/constants.ts +8 -38
  50. package/packages/core/events.ts +0 -53
  51. package/packages/core/fusion-status.ts +4 -0
  52. package/packages/core/global.d.ts +10 -0
  53. package/packages/core/harness-messages.ts +392 -0
  54. package/packages/core/index.ts +14 -0
  55. package/packages/core/kanboard-status.ts +49 -0
  56. package/packages/core/long-horizon-owner-status.ts +46 -0
  57. package/packages/core/model-cache.ts +81 -7
  58. package/packages/core/package.json +6 -3
  59. package/packages/core/src/attach/detect.ts +163 -0
  60. package/packages/core/src/child-agent/child-args.ts +31 -0
  61. package/packages/core/src/child-agent/delivery.ts +41 -0
  62. package/packages/core/src/child-agent/index.ts +5 -0
  63. package/packages/core/src/child-agent/readers.ts +203 -0
  64. package/packages/core/src/child-agent/runtime.ts +584 -0
  65. package/packages/core/src/evidence.ts +78 -0
  66. package/packages/core/src/hints/browser.ts +278 -0
  67. package/packages/core/src/hints/crab-data.ts +19 -0
  68. package/packages/core/src/hints/index.ts +865 -0
  69. package/packages/core/src/hints/lines.ts +607 -0
  70. package/packages/core/src/hints/store.ts +120 -0
  71. package/packages/core/src/jev/chatter.ts +24 -0
  72. package/packages/core/src/jev/settings.ts +177 -14
  73. package/packages/core/src/package-colors.ts +2 -0
  74. package/packages/core/src/settings/catalog.ts +39 -15
  75. package/packages/core/src/settings/engine.ts +48 -2
  76. package/packages/core/src/settings/hub.ts +83 -20
  77. package/packages/core/src/settings/open.ts +49 -0
  78. package/packages/core/src/settings/schema.ts +27 -7
  79. package/packages/core/src/tui/hub-kit.ts +18 -5
  80. package/packages/core/src/tui/kit.ts +198 -0
  81. package/packages/core/src/tui/progress.ts +73 -0
  82. package/packages/core/src/turn/arbiter.ts +290 -0
  83. package/packages/footer/README.md +4 -6
  84. package/packages/footer/package.json +3 -3
  85. package/packages/footer/src/glance-editor.ts +19 -11
  86. package/packages/footer/src/help.ts +1 -1
  87. package/packages/footer/src/index.ts +36 -3
  88. package/packages/footer/src/presets.ts +3 -4
  89. package/packages/footer/src/rendering/icons.ts +0 -20
  90. package/packages/footer/src/segments/compactor.ts +52 -142
  91. package/packages/footer/src/segments/status-ext.ts +0 -1
  92. package/packages/fusion/README.md +14 -4
  93. package/packages/fusion/package.json +4 -3
  94. package/packages/fusion/src/child-args.ts +1 -0
  95. package/packages/fusion/src/index.ts +161 -8
  96. package/packages/fusion/src/pi-settings.ts +57 -0
  97. package/packages/fusion/src/picker.ts +186 -51
  98. package/packages/fusion/src/preset.ts +56 -2
  99. package/packages/fusion/src/prompts.ts +1 -1
  100. package/packages/fusion/src/sidekick-runtime.ts +1 -420
  101. package/packages/fusion/src/tools.ts +107 -128
  102. package/packages/fusion/src/transcript.ts +27 -85
  103. package/packages/info-screen/package.json +2 -2
  104. package/packages/input-shortcuts/README.md +18 -30
  105. package/packages/input-shortcuts/package.json +2 -2
  106. package/packages/input-shortcuts/src/burst.ts +88 -0
  107. package/packages/input-shortcuts/src/chord-overlay.ts +20 -70
  108. package/packages/input-shortcuts/src/cleared-input.ts +97 -0
  109. package/packages/input-shortcuts/src/index.ts +99 -193
  110. package/packages/input-shortcuts/src/last-response.ts +40 -0
  111. package/packages/input-shortcuts/src/registers.ts +8 -23
  112. package/packages/input-shortcuts/src/types.ts +4 -16
  113. package/packages/input-shortcuts/src/undo-redo.ts +59 -47
  114. package/packages/kanboard/README.md +51 -47
  115. package/packages/kanboard/index.ts +293 -55
  116. package/packages/kanboard/package.json +8 -8
  117. package/packages/kanboard/skills/kanboard/SKILL.md +61 -27
  118. package/packages/kanboard/src/badges.ts +93 -0
  119. package/packages/kanboard/src/bin.ts +4 -2
  120. package/packages/kanboard/src/commands.ts +218 -84
  121. package/packages/kanboard/src/debug.ts +20 -0
  122. package/packages/kanboard/src/guard.ts +267 -109
  123. package/packages/kanboard/src/monitor.ts +330 -0
  124. package/packages/kanboard/src/notice-buffer.ts +74 -0
  125. package/packages/kanboard/src/progress.ts +27 -0
  126. package/packages/kanboard/src/reminders.ts +234 -0
  127. package/packages/kanboard/src/settings.ts +69 -15
  128. package/packages/kanboard/src/shapes.ts +5 -0
  129. package/packages/long-horizon/index.ts +190 -13
  130. package/packages/long-horizon/package.json +3 -3
  131. package/packages/long-horizon/src/commands.ts +103 -7
  132. package/packages/long-horizon/src/compaction-brief.ts +35 -0
  133. package/packages/long-horizon/src/engine/continuation.ts +84 -15
  134. package/packages/long-horizon/src/engine/goal-state.ts +64 -13
  135. package/packages/long-horizon/src/engine/nudge-stash.ts +71 -0
  136. package/packages/long-horizon/src/engine/ralph.ts +3 -2
  137. package/packages/long-horizon/src/engine/runaway.ts +68 -11
  138. package/packages/long-horizon/src/engine/verifier.ts +19 -0
  139. package/packages/long-horizon/src/gate.ts +37 -12
  140. package/packages/long-horizon/src/judge/resolve.ts +1 -0
  141. package/packages/long-horizon/src/owner.ts +35 -2
  142. package/packages/long-horizon/src/progress.ts +87 -0
  143. package/packages/long-horizon/src/prompts/goal.ts +1 -1
  144. package/packages/long-horizon/src/runtime.ts +172 -18
  145. package/packages/long-horizon/src/settings.ts +54 -39
  146. package/packages/long-horizon/src/tools/goal.ts +6 -0
  147. package/packages/long-horizon/src/tools/graph.ts +1 -1
  148. package/packages/long-horizon/src/tools/swarm.ts +3 -3
  149. package/packages/mcp/package.json +2 -2
  150. package/packages/memory/commands.ts +7 -2
  151. package/packages/memory/index.ts +210 -32
  152. package/packages/memory/package.json +3 -3
  153. package/packages/memory/save-session.ts +264 -0
  154. package/packages/memory/settings.ts +17 -0
  155. package/packages/memory/tools.ts +253 -203
  156. package/packages/notify/package.json +2 -2
  157. package/packages/skill-registry/README.md +53 -16
  158. package/packages/skill-registry/index.ts +230 -0
  159. package/packages/skill-registry/package.json +19 -8
  160. package/packages/skill-registry/src/editor.ts +206 -0
  161. package/packages/skill-registry/src/judge.ts +289 -0
  162. package/packages/skill-registry/src/registry.ts +87 -0
  163. package/packages/skill-registry/src/settings.ts +259 -0
  164. package/packages/skill-registry/src/vault.ts +80 -0
  165. package/packages/subagents/README.md +39 -119
  166. package/packages/subagents/package.json +6 -13
  167. package/packages/subagents/skills/subagents/SKILL.md +18 -42
  168. package/packages/subagents/src/agents.ts +213 -0
  169. package/packages/subagents/src/cards.ts +182 -0
  170. package/packages/subagents/src/index.ts +609 -1084
  171. package/packages/subagents/src/manager.ts +429 -0
  172. package/packages/subagents/src/profiles.ts +130 -0
  173. package/packages/subagents/src/transcript.ts +154 -0
  174. package/packages/subagents/src/ui.ts +389 -0
  175. package/packages/unipi/bundled.js +39756 -45569
  176. package/packages/unipi/index.ts +55 -10
  177. package/packages/updater/package.json +2 -2
  178. package/packages/utility/README.md +76 -69
  179. package/packages/utility/package.json +2 -2
  180. package/packages/utility/skills/image/SKILL.md +37 -0
  181. package/packages/utility/skills/utility/SKILL.md +17 -60
  182. package/packages/utility/src/answer/extract.ts +128 -0
  183. package/packages/utility/src/answer/index.ts +213 -0
  184. package/packages/utility/src/answer/reply.ts +133 -0
  185. package/packages/utility/src/answer/web.ts +167 -0
  186. package/packages/utility/src/attach/index.ts +205 -0
  187. package/packages/utility/src/commands.ts +38 -142
  188. package/packages/utility/src/diagnostics/engine.ts +50 -5
  189. package/packages/utility/src/image/index.ts +33 -0
  190. package/packages/utility/src/image/models.ts +221 -0
  191. package/packages/{image/src → utility/src/image}/recognize.ts +2 -2
  192. package/packages/utility/src/image/settings.ts +178 -0
  193. package/packages/{image/src/image-source.ts → utility/src/image/source.ts} +1 -1
  194. package/packages/utility/src/image/tools.ts +168 -0
  195. package/packages/utility/src/image/transports.ts +186 -0
  196. package/packages/utility/src/index.ts +68 -389
  197. package/packages/utility/src/lifecycle/cleanup.ts +116 -311
  198. package/packages/utility/src/rename/gate.ts +102 -0
  199. package/packages/utility/src/rename/index.ts +191 -0
  200. package/packages/utility/src/rename/session.ts +170 -0
  201. package/packages/utility/src/render/delegated.ts +285 -0
  202. package/packages/utility/src/render/harness.ts +683 -0
  203. package/packages/utility/src/render/parse.ts +156 -0
  204. package/packages/utility/src/render/pi-settings.ts +38 -0
  205. package/packages/utility/src/render/reply-bg.ts +307 -0
  206. package/packages/utility/src/render/simple.ts +724 -0
  207. package/packages/utility/src/render/spacing.ts +235 -0
  208. package/packages/utility/src/render/styled.ts +251 -0
  209. package/packages/utility/src/render/tools.ts +353 -0
  210. package/packages/utility/src/settings.ts +166 -233
  211. package/packages/utility/src/types.ts +1 -222
  212. package/packages/watchdog/index.ts +17 -6
  213. package/packages/watchdog/package.json +3 -3
  214. package/packages/watchdog/src/config.ts +3 -2
  215. package/packages/web-api/package.json +2 -2
  216. package/packages/workflow/README.md +3 -0
  217. package/packages/workflow/index.ts +0 -2
  218. package/packages/workflow/package.json +2 -2
  219. package/packages/workflow/src/permission/decide.ts +6 -4
  220. package/packages/workflow/src/permission/index.ts +17 -7
  221. package/packages/workflow/src/permission/settings.ts +39 -4
  222. package/packages/workflow/src/plan/index.ts +19 -4
  223. package/packages/background-tasks/extensions/delegate-child.ts +0 -1
  224. package/packages/background-tasks/src/context-parent-snapshot.ts +0 -142
  225. package/packages/background-tasks/src/context-token-budget.ts +0 -903
  226. package/packages/background-tasks/src/context-visible-conversation-v2.ts +0 -551
  227. package/packages/background-tasks/src/delegate/artifacts.ts +0 -487
  228. package/packages/background-tasks/src/delegate/budget.ts +0 -415
  229. package/packages/background-tasks/src/delegate/hook-contract-evidence.json +0 -18
  230. package/packages/background-tasks/src/delegate/hook-contract.ts +0 -154
  231. package/packages/background-tasks/src/delegate/launch.ts +0 -484
  232. package/packages/background-tasks/src/delegate/result-package.ts +0 -459
  233. package/packages/background-tasks/src/delegate/runner.ts +0 -430
  234. package/packages/background-tasks/src/delegate/seed.ts +0 -423
  235. package/packages/background-tasks/src/delegate/types.ts +0 -323
  236. package/packages/background-tasks/src/delegate-child-extension.ts +0 -978
  237. package/packages/background-tasks/src/delegate-extension.ts +0 -654
  238. package/packages/background-tasks/src/fixtures/delegate-context-incident.json +0 -17
  239. package/packages/compactor/skills/compactor-detail/SKILL.md +0 -116
  240. package/packages/compactor/skills/compactor-doctor/SKILL.md +0 -71
  241. package/packages/compactor/skills/compactor-stats/SKILL.md +0 -51
  242. package/packages/compactor/src/compaction/build-sections.ts +0 -76
  243. package/packages/compactor/src/compaction/extract/goals.ts +0 -36
  244. package/packages/compactor/src/compaction/extract/preferences.ts +0 -40
  245. package/packages/compactor/src/compaction/format.ts +0 -53
  246. package/packages/compactor/src/compaction/merge.ts +0 -143
  247. package/packages/compactor/src/config/presets.ts +0 -160
  248. package/packages/compactor/src/executor/executor.ts +0 -233
  249. package/packages/compactor/src/executor/runtime.ts +0 -115
  250. package/packages/compactor/src/security/evaluator.ts +0 -89
  251. package/packages/compactor/src/security/policy.ts +0 -96
  252. package/packages/compactor/src/security/scanner.ts +0 -65
  253. package/packages/compactor/src/session/auto-inject.ts +0 -60
  254. package/packages/compactor/src/session/db.ts +0 -325
  255. package/packages/compactor/src/session/extract.ts +0 -144
  256. package/packages/compactor/src/session/resume-inject.ts +0 -64
  257. package/packages/compactor/src/session/snapshot.ts +0 -327
  258. package/packages/compactor/src/tools/ctx-batch-execute.ts +0 -41
  259. package/packages/compactor/src/tools/ctx-execute-file.ts +0 -23
  260. package/packages/compactor/src/tools/ctx-execute.ts +0 -23
  261. package/packages/compactor/src/tools/ctx-stats.ts +0 -96
  262. package/packages/image/README.md +0 -99
  263. package/packages/image/package.json +0 -61
  264. package/packages/image/skills/image/SKILL.md +0 -76
  265. package/packages/image/src/generate.ts +0 -256
  266. package/packages/image/src/index.ts +0 -135
  267. package/packages/image/src/models.ts +0 -519
  268. package/packages/image/src/openai-images-api.ts +0 -282
  269. package/packages/image/src/register-providers.ts +0 -209
  270. package/packages/image/src/settings.ts +0 -173
  271. package/packages/image/src/tools.ts +0 -326
  272. package/packages/input-shortcuts/src/clipboard.ts +0 -119
  273. package/packages/kanboard/src/runner.ts +0 -817
  274. package/packages/skill-registry/skills/auto/SKILL.md +0 -465
  275. package/packages/skill-registry/skills/brainstorm/SKILL.md +0 -219
  276. package/packages/skill-registry/skills/chore-create/SKILL.md +0 -315
  277. package/packages/skill-registry/skills/chore-execute/SKILL.md +0 -314
  278. package/packages/skill-registry/skills/consolidate/SKILL.md +0 -142
  279. package/packages/skill-registry/skills/consultant/SKILL.md +0 -97
  280. package/packages/skill-registry/skills/debug/SKILL.md +0 -228
  281. package/packages/skill-registry/skills/document/SKILL.md +0 -120
  282. package/packages/skill-registry/skills/fix/SKILL.md +0 -212
  283. package/packages/skill-registry/skills/gather-context/SKILL.md +0 -145
  284. package/packages/skill-registry/skills/plan/SKILL.md +0 -231
  285. package/packages/skill-registry/skills/quick-fix/SKILL.md +0 -135
  286. package/packages/skill-registry/skills/quick-work/SKILL.md +0 -110
  287. package/packages/skill-registry/skills/research/SKILL.md +0 -251
  288. package/packages/skill-registry/skills/review-work/SKILL.md +0 -187
  289. package/packages/skill-registry/skills/scan-issues/SKILL.md +0 -195
  290. package/packages/skill-registry/skills/work/SKILL.md +0 -218
  291. package/packages/skill-registry/skills/worktree-create/SKILL.md +0 -69
  292. package/packages/skill-registry/skills/worktree-list/SKILL.md +0 -78
  293. package/packages/skill-registry/skills/worktree-merge/SKILL.md +0 -89
  294. package/packages/subagents/agents/delegate.md +0 -14
  295. package/packages/subagents/agents/oracle.md +0 -78
  296. package/packages/subagents/agents/researcher.md +0 -52
  297. package/packages/subagents/agents/reviewer.md +0 -80
  298. package/packages/subagents/agents/scout.md +0 -50
  299. package/packages/subagents/agents/worker.md +0 -59
  300. package/packages/subagents/prompts/council.md +0 -48
  301. package/packages/subagents/prompts/gather-context-and-clarify.md +0 -13
  302. package/packages/subagents/prompts/parallel-cleanup.md +0 -59
  303. package/packages/subagents/prompts/parallel-research.md +0 -50
  304. package/packages/subagents/prompts/parallel-review.md +0 -54
  305. package/packages/subagents/prompts/review-loop.md +0 -43
  306. package/packages/subagents/skills/council-mode/SKILL.md +0 -230
  307. package/packages/subagents/skills/subagents/references/constraints-and-recipes.md +0 -259
  308. package/packages/subagents/skills/subagents/references/execution-controls.md +0 -454
  309. package/packages/subagents/skills/subagents/references/management-authoring-rpc.md +0 -161
  310. package/packages/subagents/skills/subagents/references/multi-lane-orchestration.md +0 -39
  311. package/packages/subagents/skills/subagents/references/prompting-and-roles.md +0 -267
  312. package/packages/subagents/src/acceptance.ts +0 -331
  313. package/packages/subagents/src/agent-manager.ts +0 -405
  314. package/packages/subagents/src/agent-memory.ts +0 -300
  315. package/packages/subagents/src/agent-overrides.ts +0 -183
  316. package/packages/subagents/src/agent-runner.ts +0 -271
  317. package/packages/subagents/src/async-runner.ts +0 -422
  318. package/packages/subagents/src/authority-policy.ts +0 -47
  319. package/packages/subagents/src/budgets.ts +0 -285
  320. package/packages/subagents/src/child-safety.ts +0 -140
  321. package/packages/subagents/src/config.ts +0 -249
  322. package/packages/subagents/src/conversation-viewer.ts +0 -281
  323. package/packages/subagents/src/core-compat.ts +0 -94
  324. package/packages/subagents/src/custom-agents.ts +0 -343
  325. package/packages/subagents/src/file-system-retry.ts +0 -50
  326. package/packages/subagents/src/fleet-data.ts +0 -105
  327. package/packages/subagents/src/fleet-view.ts +0 -322
  328. package/packages/subagents/src/foreground-detach.ts +0 -59
  329. package/packages/subagents/src/fork-context.ts +0 -285
  330. package/packages/subagents/src/global.d.ts +0 -7
  331. package/packages/subagents/src/guide.ts +0 -129
  332. package/packages/subagents/src/mission-state.ts +0 -133
  333. package/packages/subagents/src/mission-store.ts +0 -436
  334. package/packages/subagents/src/output-limits.ts +0 -142
  335. package/packages/subagents/src/parity-types.ts +0 -315
  336. package/packages/subagents/src/pi-args.ts +0 -167
  337. package/packages/subagents/src/result-files.ts +0 -232
  338. package/packages/subagents/src/result-watcher.ts +0 -221
  339. package/packages/subagents/src/retained-children.ts +0 -176
  340. package/packages/subagents/src/run-fanout-budget.ts +0 -356
  341. package/packages/subagents/src/scheduled-runs.ts +0 -349
  342. package/packages/subagents/src/schemas.ts +0 -263
  343. package/packages/subagents/src/slash-commands.ts +0 -80
  344. package/packages/subagents/src/supervisor-channel.ts +0 -249
  345. package/packages/subagents/src/tool-handler.ts +0 -1144
  346. package/packages/subagents/src/types.ts +0 -238
  347. package/packages/subagents/src/widget.ts +0 -457
  348. package/packages/subagents/src/workflow-script.ts +0 -737
  349. package/packages/subagents/src/workflow-worker.ts +0 -384
  350. package/packages/subagents/src/worktree.ts +0 -614
  351. package/packages/utility/src/analytics/collector.ts +0 -293
  352. package/packages/utility/src/info-screen.ts +0 -80
  353. package/packages/utility/src/lifecycle/process.ts +0 -162
  354. package/packages/utility/src/prefix-cache.ts +0 -263
  355. package/packages/utility/src/skill-discovery.ts +0 -542
  356. package/packages/utility/src/tools/env.ts +0 -113
  357. package/packages/utility/src/tui/name-badge-state.ts +0 -315
  358. package/packages/utility/src/tui/name-badge.ts +0 -109
  359. /package/packages/{subagents/src → core/src/child-agent}/pi-spawn.ts +0 -0
@@ -0,0 +1,278 @@
1
+ /**
2
+ * /unipi:hint overlay browser built with hub-kit.
3
+ *
4
+ * Displays hints grouped by category with a header per category.
5
+ * Each row shows the hint text and seen/unseen/learned status.
6
+ * Type to filter live. Enter shows the hint above the editor and closes. Esc closes.
7
+ */
8
+
9
+ import type { Theme, KeybindingsManager } from "@earendil-works/pi-coding-agent";
10
+ import {
11
+ Key,
12
+ matchesKey,
13
+ visibleWidth,
14
+ type TUI,
15
+ } from "@earendil-works/pi-tui";
16
+ import { frameOverlay } from "../../tui-overlay.js";
17
+ import {
18
+ hubExactRow,
19
+ hubFrameTitle,
20
+ hubHeaderBand,
21
+ hubHintLine,
22
+ hubKey,
23
+ hubMaxRows,
24
+ hubMoreAbove,
25
+ hubMoreBelow,
26
+ hubRowColumns,
27
+ hubTheme,
28
+ setHubTheme,
29
+ } from "../tui/hub-kit.js";
30
+ import type { Hint, HintCategory } from "./index.js";
31
+ import { loadHintStore } from "./store.js";
32
+
33
+ const CATEGORIES: readonly HintCategory[] = [
34
+ "command",
35
+ "shortcut",
36
+ "setting",
37
+ "capability",
38
+ "explain",
39
+ "trouble",
40
+ "whatsnew",
41
+ "workflow",
42
+ "lore",
43
+ ];
44
+
45
+ interface HintRow {
46
+ readonly kind: "hint";
47
+ readonly hint: Hint;
48
+ readonly status: "learned" | "seen" | "unseen";
49
+ }
50
+
51
+ interface HeaderRow {
52
+ readonly kind: "header";
53
+ readonly category: HintCategory;
54
+ readonly count: number;
55
+ }
56
+
57
+ type BrowserRow = HintRow | HeaderRow;
58
+
59
+ export function renderHintBrowser(
60
+ hints: readonly Hint[],
61
+ onSelect: (hint: Hint) => void,
62
+ terminalRows = 30,
63
+ ) {
64
+ return (
65
+ tui: TUI,
66
+ theme: Theme,
67
+ _kb: KeybindingsManager,
68
+ done: (result: Hint | null) => void,
69
+ ) => {
70
+ setHubTheme(theme);
71
+ const store = loadHintStore();
72
+
73
+ let filter = "";
74
+ let cursor = 0; // index into selectable HintRows
75
+ let scroll = 0;
76
+
77
+ function getSelectableRows(rows: readonly BrowserRow[]): HintRow[] {
78
+ return rows.filter((r): r is HintRow => r.kind === "hint");
79
+ }
80
+
81
+ function buildRows(): BrowserRow[] {
82
+ const q = filter.trim().toLowerCase();
83
+ const rows: BrowserRow[] = [];
84
+
85
+ for (const cat of CATEGORIES) {
86
+ const matching = hints.filter((h) => {
87
+ if (h.category !== cat) return false;
88
+ if (!q) return true;
89
+ return (
90
+ h.text.toLowerCase().includes(q) ||
91
+ h.id.toLowerCase().includes(q) ||
92
+ h.category.toLowerCase().includes(q) ||
93
+ (h.teaches && h.teaches.toLowerCase().includes(q))
94
+ );
95
+ });
96
+
97
+ if (matching.length === 0) continue;
98
+
99
+ rows.push({ kind: "header", category: cat, count: matching.length });
100
+ for (const hint of matching) {
101
+ const isLearned = store.learned.includes(hint.id);
102
+ const count = store.counts[hint.id]?.count ?? 0;
103
+ const status = isLearned ? "learned" : count > 0 ? "seen" : "unseen";
104
+ rows.push({ kind: "hint", hint, status });
105
+ }
106
+ }
107
+ return rows;
108
+ }
109
+
110
+ return {
111
+ render(width: number): string[] {
112
+ const rows = buildRows();
113
+ const selectables = getSelectableRows(rows);
114
+ const inner = Math.max(1, width - 2);
115
+ const maxRows = hubMaxRows(terminalRows, filter ? 3 : 2);
116
+
117
+ // Clamp cursor
118
+ if (selectables.length === 0) {
119
+ cursor = 0;
120
+ } else if (cursor >= selectables.length) {
121
+ cursor = selectables.length - 1;
122
+ } else if (cursor < 0) {
123
+ cursor = 0;
124
+ }
125
+
126
+ // Map selectable cursor to row index in rows
127
+ const selectedHint = selectables[cursor];
128
+ const selectedRowIdx = selectedHint ? rows.indexOf(selectedHint) : 0;
129
+
130
+ // Viewport scrolling
131
+ const kinds = rows.map((r) => r.kind);
132
+ scroll = Math.max(0, Math.min(scroll, Math.max(0, rows.length - maxRows)));
133
+ if (selectedRowIdx < scroll) {
134
+ scroll = selectedRowIdx;
135
+ } else if (selectedRowIdx >= scroll + maxRows) {
136
+ scroll = selectedRowIdx - maxRows + 1;
137
+ }
138
+
139
+ const visibleRows = rows.slice(scroll, scroll + maxRows);
140
+ const body: string[] = [];
141
+
142
+ // Filter line if typing
143
+ if (filter) {
144
+ body.push(hubExactRow(hubTheme.fg("textMuted", " Filter: ") + hubTheme.bold(filter), inner));
145
+ }
146
+
147
+ // Top scroll indicator
148
+ if (scroll > 0) {
149
+ body.push(hubMoreAbove(scroll, inner));
150
+ }
151
+
152
+ for (const row of visibleRows) {
153
+ if (row.kind === "header") {
154
+ body.push(
155
+ hubHeaderBand({
156
+ inner,
157
+ text: `${row.category.toUpperCase()} (${row.count})`,
158
+ namespace: "hints",
159
+ }),
160
+ );
161
+ } else {
162
+ const isSelected = row === selectedHint;
163
+ let statusTag = "unseen";
164
+ if (row.status === "learned") statusTag = "learned";
165
+ else if (row.status === "seen") {
166
+ const c = store.counts[row.hint.id]?.count ?? 1;
167
+ statusTag = c > 1 ? `seen ${c}x` : "seen";
168
+ }
169
+ body.push(
170
+ hubRowColumns({
171
+ inner,
172
+ selected: isSelected,
173
+ label: row.hint.text,
174
+ value: statusTag,
175
+ markNamespace: "hints",
176
+ }),
177
+ );
178
+ }
179
+ }
180
+
181
+ // Bottom scroll indicator
182
+ const hiddenBelow = rows.length - (scroll + visibleRows.length);
183
+ if (hiddenBelow > 0) {
184
+ body.push(hubMoreBelow(hiddenBelow, inner));
185
+ }
186
+
187
+ body.push(
188
+ hubHintLine("Type to filter · ↑↓/jk move · Enter show · Esc close", inner),
189
+ );
190
+
191
+ return frameOverlay(body, width, {
192
+ title: hubFrameTitle("unipi hints", filter ? [filter] : []),
193
+ });
194
+ },
195
+
196
+ handleInput(data: string): void {
197
+ const rows = buildRows();
198
+ const selectables = getSelectableRows(rows);
199
+
200
+ // Escape: clear filter or close
201
+ if (matchesKey(data, Key.escape) || data === "\x1b") {
202
+ if (filter.length > 0) {
203
+ filter = "";
204
+ cursor = 0;
205
+ scroll = 0;
206
+ } else {
207
+ done(null);
208
+ }
209
+ return;
210
+ }
211
+
212
+ // Enter: select hint and close
213
+ if (matchesKey(data, Key.enter) || data === "\r" || data === "\n") {
214
+ const selected = selectables[cursor];
215
+ if (selected) {
216
+ onSelect(selected.hint);
217
+ done(selected.hint);
218
+ } else {
219
+ done(null);
220
+ }
221
+ return;
222
+ }
223
+
224
+ // Navigation
225
+ const key = hubKey(data);
226
+ if (matchesKey(data, Key.up) || (filter === "" && data === "k")) {
227
+ if (cursor > 0) cursor -= 1;
228
+ return;
229
+ }
230
+ if (matchesKey(data, Key.down) || (filter === "" && data === "j")) {
231
+ if (cursor < selectables.length - 1) cursor += 1;
232
+ return;
233
+ }
234
+ if (matchesKey(data, Key.pageUp)) {
235
+ cursor = Math.max(0, cursor - 10);
236
+ return;
237
+ }
238
+ if (matchesKey(data, Key.pageDown)) {
239
+ cursor = Math.min(selectables.length - 1, cursor + 10);
240
+ return;
241
+ }
242
+ if (matchesKey(data, Key.home)) {
243
+ cursor = 0;
244
+ return;
245
+ }
246
+ if (matchesKey(data, Key.end)) {
247
+ cursor = Math.max(0, selectables.length - 1);
248
+ return;
249
+ }
250
+
251
+ // Backspace
252
+ if (matchesKey(data, Key.backspace) || data === "\x7f" || data === "\b") {
253
+ if (filter.length > 0) {
254
+ filter = filter.slice(0, -1);
255
+ cursor = 0;
256
+ scroll = 0;
257
+ }
258
+ return;
259
+ }
260
+
261
+ // Printable text filtering
262
+ if (typeof key === "object" && key.char !== undefined) {
263
+ filter += key.char;
264
+ cursor = 0;
265
+ scroll = 0;
266
+ return;
267
+ }
268
+ if (data.length === 1 && data >= " ") {
269
+ filter += data;
270
+ cursor = 0;
271
+ scroll = 0;
272
+ }
273
+ },
274
+
275
+ invalidate(): void {},
276
+ };
277
+ };
278
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Auto-generated by packages/core/scripts/gen-crab.py — DO NOT EDIT DIRECTLY.
3
+ */
4
+
5
+ export const CRAB_KITTY_PNG_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAFgAAABMCAYAAADp0nC5AAACp0lEQVR4nO2csZHCMBBFxQ0FOKQEhy6BkBIcUgIhJVxICYSUcCElELoEhe7gLr398ngtSx8c/JctGmzpz85nWUvehfr8OuM7wj1zeOv8vmpeTKRIYDISmIwEJiOByUhgMhKYTI2az9SV47Ozo300YRNtXGkOc9j5HQ529GHj5vjC7xfNTxlMRgKTkcBk1vjL1j3X462erAwmI4HJSGAy5R7cgWe9sj3X68+WknX/CusxKIPJSGAyEpjMfsV3rAdFroeOw9l+cPwx4USdXUZ6OfUitowEJiOByazx4FLmexkXMMHeem6A1kHSS7glvQT8jXhrL0QZTEYCk5HAZKo/k/NIPBNxhl2csnhF3aw6eMtIYDISmExxPxhxPfYK8bcN2xUT+s+Qeb+Emw2bXv3gTSOByUhgMkv8xPYOYN9AuOTdsNRjS0k82gM8vMFeiaOhMpiMBCYjgclk94Njb2Mse3EbQYd16N2Gw3AzcdtecqeUd72zDV9QF8O2iBDLpqMMZiOByUhgMlMePNtraKHhOkID9+iMbw1vvrjeCWaf+SmDyUhgMhKYzNT/6PneAzDRL51lvILH3bO+ng1ubWu+M+ebv3558DuRwGQkMJld8DzXe4b1OJmwcUx1cOpi75Geh7ftwatrs9eP/WLwZGUwGQlMRgKT2T/REz3PccBzZonlwXByDg1Cz7MX9AoMyb4NvHx3gg9gfzICeuF8lcFkJDAZCUwmrYMdj5o4u2tYcNZ3ag5M5vfSZc7X+43B/cfKYDISmIwEJrMP4IFNjNaTwYRHPIeW7tVC0GPZ74fw7o/MezSsF/d1eO8kUgaTkcBkJDAZtwYdwsF4FJbJC86dffo9aR5ZZ05wuW2I2h/8SSQwGQlMJvuMRqVrbpmq61UGk5HAZCQwmT9NW6YnYeOECQAAAABJRU5ErkJggg==';
6
+
7
+ export const CRAB_PALETTE: readonly (readonly [number, number, number])[] = [[0, 0, 0], [0, 0, 0], [24, 24, 24], [192, 0, 24], [216, 0, 24], [240, 24, 24], [240, 48, 24], [240, 120, 24], [240, 144, 24], [240, 168, 24], [240, 192, 48], [240, 216, 96], [240, 240, 168]];
8
+
9
+ export const CRAB_22_GRID: readonly (readonly number[])[] = [[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 10, 5, 1, 0, 0, 0, 0, 0, 0, 1, 5, 10, 1, 0, 0, 0, 0], [0, 0, 0, 1, 10, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 10, 1, 0, 0, 0], [0, 0, 0, 1, 6, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 6, 1, 0, 0, 0], [0, 0, 0, 0, 5, 1, 0, 0, 1, 1, 11, 5, 1, 1, 0, 0, 1, 5, 0, 0, 0, 0], [0, 0, 0, 0, 5, 1, 0, 1, 10, 6, 6, 6, 6, 10, 1, 0, 1, 5, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1, 5, 5, 6, 6, 6, 6, 5, 5, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 1, 1, 5, 5, 8, 5, 2, 2, 2, 2, 5, 8, 5, 5, 9, 1, 0, 0, 0], [0, 0, 1, 9, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 8, 1, 0, 0], [0, 0, 1, 4, 5, 3, 7, 2, 12, 2, 2, 2, 2, 12, 2, 7, 3, 5, 4, 1, 0, 0], [0, 1, 1, 1, 5, 1, 7, 2, 12, 2, 2, 2, 2, 12, 2, 7, 1, 5, 1, 1, 1, 0], [0, 1, 9, 9, 1, 1, 1, 7, 2, 2, 2, 2, 2, 2, 7, 1, 1, 1, 9, 9, 1, 0], [1, 9, 6, 6, 11, 1, 1, 4, 4, 5, 5, 5, 5, 4, 4, 1, 1, 9, 6, 6, 9, 1], [3, 6, 6, 6, 11, 6, 5, 6, 1, 1, 4, 4, 1, 1, 1, 5, 6, 11, 6, 6, 6, 4], [1, 5, 6, 1, 1, 6, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 6, 1, 1, 6, 5, 1], [0, 1, 5, 8, 1, 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 8, 6, 1, 0], [0, 0, 4, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 5, 4, 0, 0], [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0]];
10
+
11
+ export const CRAB_14_GRID: readonly (readonly number[])[] = [[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 10, 1, 0, 0, 0, 0, 1, 10, 1, 0, 0], [0, 0, 6, 1, 0, 0, 0, 1, 0, 0, 1, 6, 0, 0], [0, 0, 1, 1, 0, 1, 11, 5, 1, 0, 1, 5, 0, 0], [0, 0, 0, 1, 9, 6, 6, 6, 6, 8, 1, 0, 0, 0], [0, 0, 1, 5, 5, 2, 2, 2, 2, 5, 5, 1, 0, 0], [0, 1, 9, 5, 2, 12, 2, 2, 12, 2, 5, 8, 1, 0], [0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 0], [1, 6, 11, 1, 1, 4, 5, 5, 4, 1, 1, 11, 6, 1], [1, 6, 1, 6, 6, 0, 1, 1, 0, 6, 6, 1, 6, 1], [0, 6, 1, 6, 1, 0, 0, 0, 0, 1, 6, 1, 6, 0], [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]];
12
+
13
+ export const CRAB_22_LINES_TRUECOLOR: readonly string[] = [' \x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m \x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m ', ' \x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;192;48m▀\x1b[39m\x1b[49m\x1b[38;2;240;192;48m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▀\x1b[39m \x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;192;48m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;192;48m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m ', ' \x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;240;48;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m \x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;216;96m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m \x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▀\x1b[39m ', ' \x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;192;48m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;192;48m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m ', ' \x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;168;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;144;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;144;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;168;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;144;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m ', ' \x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;216;0;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;192;0;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;120;24m\x1b[48;2;240;120;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;240;168m\x1b[48;2;240;240;168m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;240;168m\x1b[48;2;240;240;168m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;120;24m\x1b[48;2;240;120;24m▀\x1b[39m\x1b[49m\x1b[38;2;192;0;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;216;0;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m ', '\x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;168;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;168;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;168;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;216;96m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;120;24m\x1b[48;2;216;0;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;216;0;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;216;0;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;120;24m\x1b[48;2;216;0;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;168;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;168;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;168;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;168;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m', '\x1b[38;2;192;0;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;216;96m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;216;0;24m▀\x1b[39m\x1b[38;2;216;0;24m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;216;96m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;216;0;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m', ' \x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;240;24;24m\x1b[48;2;216;0;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;144;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m \x1b[38;2;0;0;0m▀\x1b[39m \x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;144;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;216;0;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▀\x1b[39m ', ' \x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m \x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m '];
14
+
15
+ export const CRAB_22_LINES_256: readonly string[] = [' \x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m \x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m ', ' \x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;215m▀\x1b[39m\x1b[49m\x1b[38;5;215m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m▀\x1b[39m \x1b[38;5;0m▀\x1b[39m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;215m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;215m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m ', ' \x1b[38;5;0m▀\x1b[39m\x1b[38;5;202m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m \x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;221m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m \x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m▀\x1b[39m ', ' \x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;215m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;215m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m ', ' \x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;214m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;214m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;208m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m ', ' \x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;160m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;124m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;208m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;229m\x1b[48;5;229m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;229m\x1b[48;5;229m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;208m▀\x1b[39m\x1b[49m\x1b[38;5;124m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;160m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m ', '\x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;214m▀\x1b[39m\x1b[49m\x1b[38;5;214m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;214m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;221m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;160m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;160m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;160m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;160m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;214m▀\x1b[39m\x1b[49m\x1b[38;5;214m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;214m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;214m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m', '\x1b[38;5;124m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;221m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m\x1b[38;5;160m▀\x1b[39m\x1b[38;5;160m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;221m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;160m\x1b[48;5;0m▀\x1b[39m\x1b[49m', ' \x1b[38;5;0m▀\x1b[39m\x1b[38;5;9m\x1b[48;5;160m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m \x1b[38;5;0m▀\x1b[39m \x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;160m▀\x1b[39m\x1b[49m\x1b[38;5;0m▀\x1b[39m ', ' \x1b[38;5;0m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m \x1b[38;5;0m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m '];
16
+
17
+ export const CRAB_14_LINES_TRUECOLOR: readonly string[] = [' \x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;192;48m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m \x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;192;48m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m ', ' \x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m \x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;240;216;96m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m \x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m ', ' \x1b[38;2;0;0;0m▄\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;168;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;144;24m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m▄\x1b[39m ', ' \x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;168;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;240;168m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;240;168m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;24;24;24m\x1b[48;2;24;24;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;144;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m ', '\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;216;96m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;216;0;24m▀\x1b[39m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;24;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;216;0;24m▀\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;240;216;96m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;240;48;24m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m', ' \x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m▀\x1b[39m\x1b[38;2;0;0;0m▀\x1b[39m \x1b[38;2;0;0;0m▀\x1b[39m\x1b[38;2;240;48;24m▀\x1b[39m\x1b[38;2;0;0;0m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m\x1b[38;2;240;48;24m\x1b[48;2;0;0;0m▀\x1b[39m\x1b[49m '];
18
+
19
+ export const CRAB_14_LINES_256: readonly string[] = [' \x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;215m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m \x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;215m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m ', ' \x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m \x1b[38;5;0m▄\x1b[39m\x1b[38;5;221m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m \x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;9m▀\x1b[39m\x1b[49m ', ' \x1b[38;5;0m▄\x1b[39m\x1b[38;5;0m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;214m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;9m▀\x1b[39m\x1b[49m\x1b[38;5;0m▄\x1b[39m ', ' \x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;214m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;229m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;229m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;234m\x1b[48;5;234m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;208m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m ', '\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;221m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;160m▀\x1b[39m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;9m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;160m▀\x1b[39m\x1b[38;5;0m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;221m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;202m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m', ' \x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m▀\x1b[39m\x1b[38;5;0m▀\x1b[39m \x1b[38;5;0m▀\x1b[39m\x1b[38;5;202m▀\x1b[39m\x1b[38;5;0m\x1b[48;5;0m▀\x1b[39m\x1b[49m\x1b[38;5;202m\x1b[48;5;0m▀\x1b[39m\x1b[49m '];