From 9ceaa4cd382e8612430f2031df5a5078dd062645 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Thu, 9 May 2024 15:26:58 +0200 Subject: [PATCH] feat: add more interaction Signed-off-by: kjuulh --- crates/hyperlog-tui/src/app.rs | 44 +++-- crates/hyperlog-tui/src/command_parser.rs | 2 + crates/hyperlog-tui/src/components.rs | 91 ++++++++-- crates/hyperlog-tui/src/lib.rs | 1 + crates/hyperlog-tui/src/models.rs | 1 + it-is-nice.cast | 200 ---------------------- 6 files changed, 117 insertions(+), 222 deletions(-) delete mode 100644 it-is-nice.cast diff --git a/crates/hyperlog-tui/src/app.rs b/crates/hyperlog-tui/src/app.rs index 8ea556a..b9bdde0 100644 --- a/crates/hyperlog-tui/src/app.rs +++ b/crates/hyperlog-tui/src/app.rs @@ -4,8 +4,11 @@ use ratatui::{ }; use crate::{ - command_parser::CommandParser, commands::IntoCommand, components::GraphExplorer, - state::SharedState, Msg, + command_parser::{CommandParser, Commands}, + commands::IntoCommand, + components::GraphExplorer, + state::SharedState, + Msg, }; use self::{ @@ -34,6 +37,11 @@ pub enum Mode { Command, } +pub enum AppFocus { + Dialog, + Graph, +} + pub struct App<'a> { root: String, @@ -44,6 +52,8 @@ pub struct App<'a> { command: Option, graph_explorer: GraphExplorer<'a>, + + focus: AppFocus, } impl<'a> App<'a> { @@ -59,6 +69,7 @@ impl<'a> App<'a> { command: None, state, graph_explorer, + focus: AppFocus::Graph, } } @@ -77,22 +88,31 @@ impl<'a> App<'a> { self.command = Some(CommandBarState::default()); self.mode = Mode::Command } + Msg::Interact => match self.focus { + AppFocus::Dialog => {} + AppFocus::Graph => self.graph_explorer.interact()?, + }, Msg::SubmitCommand { command } => { tracing::info!("submitting command"); if let Some(command) = CommandParser::parse(&command) { - if command.is_write() { - if let Some(dialog) = &self.dialog { - if let Some(output) = dialog.get_command() { - self.state.commander.execute(output)?; + match self.focus { + AppFocus::Dialog => { + if command.is_write() { + if let Some(dialog) = &self.dialog { + if let Some(output) = dialog.get_command() { + self.state.commander.execute(output)?; + } + } + + self.graph_explorer.update_graph()?; + } + + if command.is_quit() { + self.dialog = None; } } - } - - self.graph_explorer.update_graph()?; - - if command.is_quit() { - self.dialog = None; + AppFocus::Graph => self.graph_explorer.execute_command(&command)?, } } self.command = None; diff --git a/crates/hyperlog-tui/src/command_parser.rs b/crates/hyperlog-tui/src/command_parser.rs index cd56bf9..8b62bda 100644 --- a/crates/hyperlog-tui/src/command_parser.rs +++ b/crates/hyperlog-tui/src/command_parser.rs @@ -4,6 +4,7 @@ pub enum Commands { Write, Quit, WriteQuit, + Archive, } impl Commands { @@ -29,6 +30,7 @@ impl CommandParser { "w" | "write" => Some(Commands::Write), "q" | "quit" => Some(Commands::Quit), "wq" | "write-quit" => Some(Commands::WriteQuit), + "a" | "archive" => Some(Commands::Archive), _ => None, }, None => None, diff --git a/crates/hyperlog-tui/src/components.rs b/crates/hyperlog-tui/src/components.rs index e6308de..72473e1 100644 --- a/crates/hyperlog-tui/src/components.rs +++ b/crates/hyperlog-tui/src/components.rs @@ -5,7 +5,7 @@ use hyperlog_core::log::GraphItem; use itertools::Itertools; use ratatui::{prelude::*, widgets::*}; -use crate::state::SharedState; +use crate::{command_parser::Commands, state::SharedState}; pub struct GraphExplorer<'a> { state: SharedState, @@ -137,6 +137,24 @@ impl GraphExplorer<'_> { Vec::new() } } + + pub fn execute_command(&self, command: &Commands) -> anyhow::Result<()> { + if let Commands::Archive = command { + if !self.get_current_path().is_empty() { + tracing::debug!("archiving path: {:?}", self.get_current_path()) + } + } + + Ok(()) + } + + pub(crate) fn interact(&mut self) -> anyhow::Result<()> { + if !self.get_current_path().is_empty() { + tracing::info!("toggling state of items"); + } + + Ok(()) + } } trait RenderGraph { @@ -153,6 +171,11 @@ impl RenderGraph for MovementGraph { let mut lines = Vec::new(); for item in &self.items { + let prefix = match item.item_type { + GraphItemType::Section => "- ", + GraphItemType::Item => "- [ ] ", + }; + match items.split_first().map(|(first, rest)| { if item.index == *first { (true, rest) @@ -163,12 +186,12 @@ impl RenderGraph for MovementGraph { Some((true, rest)) => { if rest.is_empty() { lines.push( - Line::raw(format!("- {}", item.name)) + Line::raw(format!("{} {}", prefix, item.name)) .style(Style::new().bold().white()), ); } else { lines.push( - Line::raw(format!("- {}", item.name)) + Line::raw(format!("{} {}", prefix, item.name)) .patch_style(Style::new().dark_gray()), ); } @@ -184,7 +207,8 @@ impl RenderGraph for MovementGraph { } _ => { lines.push( - Line::raw(format!("- {}", item.name)).patch_style(Style::new().dark_gray()), + Line::raw(format!("{} {}", prefix, item.name)) + .patch_style(Style::new().dark_gray()), ); lines.push("".into()); @@ -206,6 +230,10 @@ impl RenderGraph for MovementGraph { let mut lines = Vec::new(); for item in &self.items { + let prefix = match item.item_type { + GraphItemType::Section => "- ", + GraphItemType::Item => "- [ ] ", + }; match items.split_first().map(|(first, rest)| { if item.index == *first { (true, rest) @@ -217,12 +245,12 @@ impl RenderGraph for MovementGraph { let mut line = Vec::new(); if rest.is_empty() { line.push( - Span::raw(format!("- {}", item.name)) + Span::raw(format!("{} {}", prefix, item.name)) .style(Style::new().bold().white()), ); } else { line.push( - Span::raw(format!("- {}", item.name)) + Span::raw(format!("{} {}", prefix, item.name)) .patch_style(Style::new().dark_gray()), ); } @@ -238,9 +266,8 @@ impl RenderGraph for MovementGraph { } } _ => { - lines - .push(vec![Span::raw(format!("- {}", item.name)) - .patch_style(Style::new().dark_gray())]); + lines.push(vec![Span::raw(format!("{prefix} {}", item.name)) + .patch_style(Style::new().dark_gray())]); lines.push(vec!["".into()]); @@ -274,11 +301,19 @@ impl<'a> StatefulWidget for GraphExplorer<'a> { } } +#[derive(PartialEq, Eq, Debug, Clone)] +enum GraphItemType { + Section, + Item, +} + #[derive(PartialEq, Eq, Debug, Clone)] struct MovementGraphItem { index: usize, name: String, values: MovementGraph, + + item_type: GraphItemType, } #[derive(Default, PartialEq, Eq, Debug, Clone)] @@ -381,6 +416,11 @@ impl From for MovementGraph { index: i, name: key.clone(), values: value.clone().into(), + item_type: match value.deref() { + GraphItem::User(_) => GraphItemType::Section, + GraphItem::Section(_) => GraphItemType::Section, + GraphItem::Item { .. } => GraphItemType::Item, + }, }) .collect::>(); @@ -400,7 +440,7 @@ mod test { use hyperlog_core::log::{GraphItem, ItemState}; use similar_asserts::assert_eq; - use crate::components::MovementGraphItem; + use crate::components::{GraphItemType, MovementGraphItem}; use super::MovementGraph; @@ -470,27 +510,32 @@ mod test { items: vec![MovementGraphItem { index: 0, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "00".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, MovementGraphItem { index: 1, name: "01".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "010".into(), values: MovementGraph::default(), + item_type: GraphItemType::Item, }, MovementGraphItem { index: 1, name: "011".into(), values: MovementGraph::default(), + item_type: GraphItemType::Item, }, ] } @@ -510,17 +555,20 @@ mod test { MovementGraphItem { index: 0, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "0".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, MovementGraphItem { index: 1, name: "0".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, ], }, @@ -528,22 +576,26 @@ mod test { MovementGraphItem { index: 1, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "0".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, MovementGraphItem { index: 1, name: "0".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, MovementGraphItem { index: 2, name: "0".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, ], }, @@ -551,17 +603,20 @@ mod test { MovementGraphItem { index: 2, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "0".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, MovementGraphItem { index: 1, name: "0".into(), values: MovementGraph::default(), + item_type: GraphItemType::Section, }, ], }, @@ -618,10 +673,12 @@ mod test { MovementGraphItem { index: 0, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![MovementGraphItem { index: 0, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph::default(), }], }, @@ -629,16 +686,19 @@ mod test { MovementGraphItem { index: 1, name: "1".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph::default(), }, MovementGraphItem { index: 1, name: "1".into(), + item_type: GraphItemType::Section, values: MovementGraph::default(), }, ], @@ -647,21 +707,25 @@ mod test { MovementGraphItem { index: 2, name: "2".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "0".into(), + item_type: GraphItemType::Section, values: MovementGraph::default(), }, MovementGraphItem { index: 1, name: "1".into(), + item_type: GraphItemType::Section, values: MovementGraph::default(), }, MovementGraphItem { index: 2, name: "2".into(), + item_type: GraphItemType::Section, values: MovementGraph::default(), }, ], @@ -687,14 +751,17 @@ mod test { MovementGraphItem { index: 0, name: "other".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![MovementGraphItem { index: 0, name: "other".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![MovementGraphItem { index: 0, name: "other".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![] }, }], }, @@ -704,21 +771,25 @@ mod test { MovementGraphItem { index: 1, name: "some".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![] }, }, MovementGraphItem { index: 2, name: "something".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![ MovementGraphItem { index: 0, name: "else".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![] }, }, MovementGraphItem { index: 1, name: "third".into(), + item_type: GraphItemType::Section, values: MovementGraph { items: vec![] }, }, ], diff --git a/crates/hyperlog-tui/src/lib.rs b/crates/hyperlog-tui/src/lib.rs index 61d4292..a7987b1 100644 --- a/crates/hyperlog-tui/src/lib.rs +++ b/crates/hyperlog-tui/src/lib.rs @@ -74,6 +74,7 @@ fn update( if let Event::Key(key) = event::read().context("event read failed")? { let mut cmd = match &app.mode { app::Mode::View => match key.code { + KeyCode::Enter => app.update(Msg::Interact)?, KeyCode::Char('q') => return Ok(UpdateConclusion::new(true)), KeyCode::Char('l') => app.update(Msg::MoveRight)?, KeyCode::Char('h') => app.update(Msg::MoveLeft)?, diff --git a/crates/hyperlog-tui/src/models.rs b/crates/hyperlog-tui/src/models.rs index f3012c4..095be5c 100644 --- a/crates/hyperlog-tui/src/models.rs +++ b/crates/hyperlog-tui/src/models.rs @@ -7,6 +7,7 @@ pub enum Msg { MoveDown, MoveUp, OpenCreateItemDialog, + Interact, EnterInsertMode, EnterViewMode, diff --git a/it-is-nice.cast b/it-is-nice.cast deleted file mode 100644 index 4a711f5..0000000 --- a/it-is-nice.cast +++ /dev/null @@ -1,200 +0,0 @@ -{"version": 2, "width": 121, "height": 31, "timestamp": 1715205039, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} -[0.340402, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] -[0.415094, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[38;2;255;153;102mhyperlog\u001b[0m \u001b[90mmain\u001b[0m\u001b[38;2;255;153;102m \u001b[0m\u001b[1;31mrs \u001b[0m\r\n\u001b[38;2;255;153;102m❯\u001b[0m \u001b[K"] -[0.416098, "o", "\u001b[6 q"] -[0.417144, "o", "\u001b[6 q"] -[0.417386, "o", "\u001b[?2004h"] -[1.099162, "o", "a"] -[1.137079, "o", "\b\u001b[1m\u001b[31ma\u001b[0m\u001b[39m"] -[1.137376, "o", "\b\u001b[1m\u001b[31ma\u001b[0m\u001b[39m\u001b[90msciinema rec it-is-nice.cast\u001b[39m\u001b[28D"] -[1.895435, "o", "\b\u001b[0m\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[29D"] -[4.16507, "o", "c"] -[4.170318, "o", "\b\u001b[32mc\u001b[39m"] -[4.205236, "o", "\b\u001b[32mc\u001b[39m\u001b[90mlear\u001b[39m\b\b\b\b"] -[4.314062, "o", "\b\u001b[32mc\u001b[32ma\u001b[39m\u001b[39m \u001b[39m \u001b[39m \b\b\b"] -[4.319326, "o", "\b\b\u001b[1m\u001b[31mc\u001b[1m\u001b[31ma\u001b[0m\u001b[39m"] -[4.339872, "o", "\u001b[90mrgo run\u001b[39m\b\b\b\b\b\b\b"] -[4.375674, "o", "\b\b\u001b[1m\u001b[31mc\u001b[1m\u001b[31ma\u001b[1m\u001b[31mr\u001b[0m\u001b[39m"] -[4.553571, "o", "\b\u001b[1m\u001b[31mr\u001b[1m\u001b[31mg\u001b[0m\u001b[39m"] -[4.624486, "o", "\b\u001b[1m\u001b[31mg\u001b[1m\u001b[31mo\u001b[0m\u001b[39m"] -[4.628551, "o", "\b\b\b\b\b\u001b[0m\u001b[32mc\u001b[0m\u001b[32ma\u001b[0m\u001b[32mr\u001b[0m\u001b[32mg\u001b[0m\u001b[32mo\u001b[39m"] -[4.743312, "o", "\b\u001b[32mo\u001b[32m \u001b[39m"] -[4.745288, "o", "\b\b\u001b[32mo\u001b[39m\u001b[39m "] -[4.85978, "o", "\u001b[39mr"] -[4.863278, "o", "\b\u001b[4mr\u001b[24m"] -[4.923563, "o", "\b\u001b[4mr\u001b[39m\u001b[4mu\u001b[24m"] -[4.927058, "o", "\b\b\u001b[24mr\u001b[24mu"] -[5.064694, "o", "\u001b[39mn"] -[5.322632, "o", "\u001b[?1l\u001b>"] -[5.323055, "o", "\u001b[?2004l"] -[5.330122, "o", "\u001b[0 q"] -[5.330526, "o", "\r\r\n"] -[5.677526, "o", "\u001b[1m\u001b[32m Compiling\u001b[0m hyperlog-tui v0.1.0 (/Users/kah/git/git.front.kjuulh.io/kjuulh/hyperlog/crates/hyperlog-tui)\r\n\u001b[1m\u001b[36m Building\u001b[0m [=======================> ] 315/317: hyperlog-tui \r"] -[5.790434, "o", "\u001b[K\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: methods `toggle` and `string` are never used\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0mcrates/hyperlog-tui/src/app/dialog.rs:99:12\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;12m74\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0mimpl InputBuffer {\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m----------------\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12mmethods in this implementation\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;12m...\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;12m99\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m pub fn toggle(&mut self) {\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;12m...\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;12m130\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m pub fn string(&self) -> String {\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(dead_code)]` on by default\u001b[0m\r\n\r\n"] -[5.790526, "o", "\u001b[1m\u001b[36m Building\u001b[0m [=======================> ] 315/317: hyperlog-tui \r"] -[5.964842, "o", "\u001b[K\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m:\u001b[0m `hyperlog-tui` (lib) generated 1 warning\r\n\u001b[1m\u001b[32m Compiling\u001b[0m hyperlog v0.1.0 (/Users/kah/git/git.front.kjuulh.io/kjuulh/hyperlog/crates/hyperlog)\r\n"] -[5.964868, "o", "\u001b[1m\u001b[36m Building\u001b[0m [=======================> ] 316/317: hyperlog(bin) \r"] -[7.029851, "o", "\u001b[K\u001b[1m\u001b[32m Finished\u001b[0m `dev` profile [unoptimized + debuginfo] target(s) in 1.65s\r\n"] -[7.039265, "o", "\u001b[1m\u001b[32m Running\u001b[0m `target/debug/hyperlog`\r\n"] -[7.397795, "o", "\u001b[?1049h"] -[7.400923, "o", "\u001b[1;1H\u001b[38;5;2mhyperlog\u001b[2;1H\u001b[39m─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[3;1H\u001b[38;5;8m- a\u001b[5;3H- b\u001b[7;1H- b\u001b[9;3H- a\u001b[11;3H- b\u001b[13;1H- something\u001b[31;2H\u001b[39m--\u001b[31;5HVIEW\u001b[31;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[7.659643, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[7.920329, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[8.183413, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[8.351457, "o", "\u001b[31;5HEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[8.609528, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[8.868582, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[8.942765, "o", "\u001b[31;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[9.200718, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[9.461421, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[9.512177, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[9.708596, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[9.905173, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[9.945318, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[10.09697, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[10.355132, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[10.39335, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[10.651726, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[10.655332, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[10.843242, "o", "\u001b[7;1H\u001b[38;5;8m- b\u001b[13;1H\u001b[1m\u001b[38;5;15m- something\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[10.998559, "o", "\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[13;1H\u001b[22m\u001b[38;5;8m- something\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.202965, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[7;1H\u001b[22m\u001b[38;5;8m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.246379, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.412109, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[7;1H\u001b[22m\u001b[38;5;8m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.518186, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.657233, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[7;1H\u001b[22m\u001b[38;5;8m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.743079, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.880111, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[7;1H\u001b[22m\u001b[38;5;8m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[11.945269, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[12.205525, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[12.305051, "o", "\u001b[7;1H\u001b[38;5;8m- b\u001b[9;3H\u001b[1m\u001b[38;5;15m- a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[12.563385, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[12.587834, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[12.847447, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[13.056384, "o", "\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[9;3H\u001b[22m\u001b[38;5;8m- a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[13.073621, "o", "\u001b[7;1H\u001b[38;5;8m- b\u001b[13;1H\u001b[1m\u001b[38;5;15m- something\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[13.332382, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[13.590747, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[13.85099, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[13.941815, "o", "\u001b[13;1H\u001b[38;5;8m- something\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[14.200606, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[14.460463, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[14.549192, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[14.809497, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[14.94385, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[15.155403, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[15.413804, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[15.578955, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[7;1H\u001b[22m\u001b[38;5;8m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[15.833893, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[5;3H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[16.097133, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[16.248338, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- a\u001b[5;3H\u001b[22m\u001b[38;5;8m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[16.507132, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[16.572342, "o", "\u001b[3;1H\u001b[38;5;8m- a\u001b[7;1H\u001b[1m\u001b[38;5;15m- b\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[16.830893, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[17.092909, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[17.26512, "o", "\u001b[31;1H: \u001b[31;5H \u001b[31;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[17.524696, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[17.78239, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[17.887591, "o", "\u001b[31;2Ho\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[18.146806, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[18.405362, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[18.431095, "o", "\u001b[31;2H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[18.560467, "o", "\u001b[31;2Hs\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[18.670387, "o", "\u001b[31;3Ho\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[18.834286, "o", "\u001b[31;4Hm\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[18.927281, "o", "\u001b[31;5He\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[19.030836, "o", "\u001b[31;6Ht\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[19.071122, "o", "\u001b[31;7Hh\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[19.211626, "o", "\u001b[31;8Hi\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[19.357607, "o", "\u001b[31;9Hn\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[19.452746, "o", "\u001b[31;10Hg\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[19.646601, "o", "\u001b[31;1H -- VIEW --\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[19.907225, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[20.165462, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[20.423652, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[20.680919, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[20.939263, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[20.996048, "o", "\u001b[1;10H~\u001b[1;12Hcreate\u001b[1;19Hitem\u001b[3;1H┌title──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\u001b[4;1H│\u001b[38;5;0m\u001b[48;5;5m \u001b[4;121H\u001b[39m\u001b[49m│\u001b[5;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[6;1H┌description─────────────────────────────────────────────────────────────────"] -[20.996104, "o", "───────────────────────────────────────────┐\u001b[7;1H│ \u001b[7;121H│\u001b[8;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[9;3H \u001b[11;3H \u001b[13;1H \u001b[31;5HEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[21.010383, "o", "\u001b[4;2Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[21.271922, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[21.529104, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[21.790287, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[21.794558, "o", "\u001b[4;2H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.052204, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.18287, "o", "\u001b[4;2Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.189682, "o", "\u001b[4;3Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.211883, "o", "\u001b[4;4Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.214504, "o", "\u001b[4;5Hk\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.284859, "o", "\u001b[4;6Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.319941, "o", "\u001b[4;7Hj\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.342546, "o", "\u001b[4;8Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.424274, "o", "\u001b[4;9Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.455243, "o", "\u001b[4;10Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.517656, "o", "\u001b[4;11Hk\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.521962, "o", "\u001b[4;12Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.553432, "o", "\u001b[4;13Hj\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.56918, "o", "\u001b[4;14Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.612324, "o", "\u001b[4;15Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.692691, "o", "\u001b[4;16Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.723325, "o", "\u001b[4;17Hk\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.738287, "o", "\u001b[4;18Hj\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.765988, "o", "\u001b[4;19Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.826184, "o", "\u001b[4;20Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.900582, "o", "\u001b[4;21Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[22.953845, "o", "\u001b[4;22Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[23.213295, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[23.420252, "o", "\u001b[4;23H \u001b[31;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[23.683026, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[23.815286, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.074879, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.159029, "o", "\u001b[7;2H\u001b[38;5;0m\u001b[48;5;5m \u001b[31;5H\u001b[39m\u001b[49mEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.301429, "o", "\u001b[7;2Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.345464, "o", "\u001b[7;3Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.348744, "o", "\u001b[7;4Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.427224, "o", "\u001b[7;5Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.474234, "o", "\u001b[7;6Hj\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.554142, "o", "\u001b[7;7Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.603048, "o", "\u001b[7;8Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.632587, "o", "\u001b[7;9Hk\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.636099, "o", "\u001b[7;10Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.671615, "o", "\u001b[7;11Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.727905, "o", "\u001b[7;12Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.823809, "o", "\u001b[7;13Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.839083, "o", "\u001b[7;14Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.887115, "o", "\u001b[7;15Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.94834, "o", "\u001b[7;16Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[24.995917, "o", "\u001b[7;17Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.007211, "o", "\u001b[7;18Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.023711, "o", "\u001b[7;19Hk\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.118431, "o", "\u001b[7;20Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.159273, "o", "\u001b[7;21Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.184474, "o", "\u001b[7;22Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.209847, "o", "\u001b[7;23Hk\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.22384, "o", "\u001b[7;24Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.273719, "o", "\u001b[7;25Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.533912, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[25.792562, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[26.052447, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[26.074376, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[26.337157, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[26.426805, "o", "\u001b[7;26H \u001b[31;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[26.689664, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[26.947668, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[27.000511, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[27.258436, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[27.376346, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[27.636429, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[27.895577, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[28.157791, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[28.417062, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[28.459318, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[28.716785, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[28.974774, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] -[29.024351, "o", "\u001b[?1049l\u001b[?25h"] -[29.026254, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] -[29.086805, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[38;2;255;153;102mhyperlog\u001b[0m \u001b[90mmain\u001b[0m\u001b[38;2;255;153;102m \u001b[0m\u001b[1;31mrs \u001b[0m\u001b[33m23s\u001b[0m \r\n\u001b[38;2;255;153;102m❯\u001b[0m \u001b[K"] -[29.087892, "o", "\u001b[6 q"] -[29.088951, "o", "\u001b[6 q"] -[29.089143, "o", "\u001b[?2004h"] -[30.381431, "o", "\u001b[?2004l\r\r\n"]